From 62f02ba4f4b7b561aa15408ebd9951600bdd71aa Mon Sep 17 00:00:00 2001 From: codeworkx Date: Sun, 20 May 2012 12:00:36 +0200 Subject: exynos: reorganized and updated from insignal Changes needed on exynos4210 devices: libcsc -> libseccscapi libswconverter -> remove TARGET_HAL_PATH := hardware/samsung/exynos4/hal TARGET_OMX_PATH := hardware/samsung/exynos/multimedia/openmax $(call inherit-product, hardware/samsung/exynos4210.mk) Change-Id: Ic59ef95b85ef37b3f38fb36cf6a364a5414685ee --- exynos/multimedia/Android.mk | 1 + exynos/multimedia/codecs/Android.mk | 1 + exynos/multimedia/codecs/audio/Android.mk | 11 + exynos/multimedia/codecs/audio/exynos4/Android.mk | 14 + .../codecs/audio/exynos4/srp/alp/Android.mk | 26 + .../codecs/audio/exynos4/srp/alp/include/srp_api.h | 52 + .../audio/exynos4/srp/alp/include/srp_error.h | 22 + .../audio/exynos4/srp/alp/include/srp_ioctl.h | 23 + .../codecs/audio/exynos4/srp/alp/src/srp_api.c | 265 ++ .../codecs/audio/exynos4/srp/libsa_jni/Android.mk | 13 + .../codecs/audio/exynos4/srp/libsa_jni/SACtrl.c | 33 + .../codecs/audio/exynos4/srp/ulp/Android.mk | 23 + .../codecs/audio/exynos4/srp/ulp/include/srp_api.h | 55 + .../audio/exynos4/srp/ulp/include/srp_api_ctrl.h | 25 + .../audio/exynos4/srp/ulp/include/srp_ioctl.h | 66 + .../codecs/audio/exynos4/srp/ulp/src/srp_api.c | 381 ++ .../audio/exynos4/srp/ulp/src/srp_api_ctrl.c | 331 ++ exynos/multimedia/codecs/audio/exynos5/Android.mk | 9 + .../codecs/audio/exynos5/srp/alp/Android.mk | 26 + .../codecs/audio/exynos5/srp/alp/include/srp_api.h | 52 + .../audio/exynos5/srp/alp/include/srp_error.h | 22 + .../audio/exynos5/srp/alp/include/srp_ioctl.h | 23 + .../codecs/audio/exynos5/srp/alp/src/srp_api.c | 265 ++ exynos/multimedia/codecs/video/Android.mk | 11 + exynos/multimedia/codecs/video/exynos4/Android.mk | 11 + .../multimedia/codecs/video/exynos4/mfc/Android.mk | 38 + .../video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c | 1100 +++++ .../video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c | 862 ++++ .../video/exynos4/mfc/include/SsbSipMfcApi.h | 409 ++ .../codecs/video/exynos4/mfc/include/mfc_errno.h | 79 + .../video/exynos4/mfc/include/mfc_interface.h | 524 +++ .../codecs/video/exynos4/mfc_v4l2/Android.mk | 34 + .../exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c | 1352 ++++++ .../exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c | 1206 ++++++ .../video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h | 381 ++ .../video/exynos4/mfc_v4l2/include/mfc_errno.h | 79 + .../video/exynos4/mfc_v4l2/include/mfc_interface.h | 541 +++ exynos/multimedia/codecs/video/exynos5/Android.mk | 7 + .../codecs/video/exynos5/mfc_v4l2/Android.mk | 39 + .../exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c | 1669 ++++++++ .../exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c | 1318 ++++++ .../video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h | 384 ++ .../video/exynos5/mfc_v4l2/include/mfc_errno.h | 79 + .../video/exynos5/mfc_v4l2/include/mfc_interface.h | 555 +++ exynos/multimedia/libstagefrighthw/Android.mk | 23 + .../multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp | 147 + .../multimedia/libstagefrighthw/SEC_OMX_Plugin.h | 76 + exynos/multimedia/openmax/Android.mk | 38 + .../openmax/component/audio/dec/Android.mk | 19 + .../openmax/component/audio/dec/SEC_OMX_Adec.c | 1376 ++++++ .../openmax/component/audio/dec/SEC_OMX_Adec.h | 132 + .../openmax/component/audio/dec/mp3/Android.mk | 31 + .../component/audio/dec/mp3/SEC_OMX_Mp3dec.c | 918 +++++ .../component/audio/dec/mp3/SEC_OMX_Mp3dec.h | 63 + .../component/audio/dec/mp3/library_register.c | 58 + .../component/audio/dec/mp3/library_register.h | 54 + .../multimedia/openmax/component/common/Android.mk | 43 + .../component/common/SEC_OMX_Basecomponent.c | 1535 +++++++ .../component/common/SEC_OMX_Basecomponent.h | 191 + .../openmax/component/common/SEC_OMX_Baseport.c | 1014 +++++ .../openmax/component/common/SEC_OMX_Baseport.h | 95 + .../component/common/SEC_OMX_Resourcemanager.c | 478 +++ .../component/common/SEC_OMX_Resourcemanager.h | 59 + .../openmax/component/video/dec/Android.mk | 23 + .../openmax/component/video/dec/SEC_OMX_Vdec.c | 1505 +++++++ .../openmax/component/video/dec/SEC_OMX_Vdec.h | 153 + .../openmax/component/video/dec/h264/Android.mk | 58 + .../component/video/dec/h264/SEC_OMX_H264dec.c | 2067 ++++++++++ .../component/video/dec/h264/SEC_OMX_H264dec.h | 79 + .../component/video/dec/h264/library_register.c | 60 + .../component/video/dec/h264/library_register.h | 56 + .../openmax/component/video/dec/mpeg4/Android.mk | 52 + .../component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c | 2048 +++++++++ .../component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h | 97 + .../component/video/dec/mpeg4/library_register.c | 63 + .../component/video/dec/mpeg4/library_register.h | 59 + .../openmax/component/video/dec/vc1/Android.mk | 52 + .../component/video/dec/vc1/SEC_OMX_Wmvdec.c | 1960 +++++++++ .../component/video/dec/vc1/SEC_OMX_Wmvdec.h | 99 + .../component/video/dec/vc1/library_register.c | 57 + .../component/video/dec/vc1/library_register.h | 52 + .../openmax/component/video/dec/vp8/Android.mk | 47 + .../component/video/dec/vp8/SEC_OMX_Vp8dec.c | 1547 +++++++ .../component/video/dec/vp8/SEC_OMX_Vp8dec.h | 66 + .../component/video/dec/vp8/library_register.c | 58 + .../component/video/dec/vp8/library_register.h | 54 + .../openmax/component/video/enc/Android.mk | 27 + .../openmax/component/video/enc/SEC_OMX_Venc.c | 1802 ++++++++ .../openmax/component/video/enc/SEC_OMX_Venc.h | 163 + .../openmax/component/video/enc/h264/Android.mk | 39 + .../component/video/enc/h264/SEC_OMX_H264enc.c | 1582 +++++++ .../component/video/enc/h264/SEC_OMX_H264enc.h | 77 + .../component/video/enc/h264/library_register.c | 55 + .../component/video/enc/h264/library_register.h | 55 + .../openmax/component/video/enc/mpeg4/Android.mk | 39 + .../component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c | 1774 ++++++++ .../component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h | 77 + .../component/video/enc/mpeg4/library_register.c | 64 + .../component/video/enc/mpeg4/library_register.h | 59 + exynos/multimedia/openmax/core/Android.mk | 26 + .../openmax/core/SEC_OMX_Component_Register.c | 264 ++ .../openmax/core/SEC_OMX_Component_Register.h | 75 + exynos/multimedia/openmax/core/SEC_OMX_Core.c | 364 ++ exynos/multimedia/openmax/core/SEC_OMX_Core.h | 78 + .../multimedia/openmax/include/khronos/OMX_Audio.h | 1311 ++++++ .../openmax/include/khronos/OMX_Component.h | 579 +++ .../openmax/include/khronos/OMX_ContentPipe.h | 195 + .../multimedia/openmax/include/khronos/OMX_Core.h | 1431 +++++++ .../openmax/include/khronos/OMX_IVCommon.h | 920 +++++ .../multimedia/openmax/include/khronos/OMX_Image.h | 328 ++ .../multimedia/openmax/include/khronos/OMX_Index.h | 258 ++ .../multimedia/openmax/include/khronos/OMX_Other.h | 337 ++ .../multimedia/openmax/include/khronos/OMX_Types.h | 347 ++ .../multimedia/openmax/include/khronos/OMX_Video.h | 1060 +++++ .../multimedia/openmax/include/sec/SEC_OMX_Def.h | 177 + .../openmax/include/sec/SEC_OMX_Macros.h | 66 + exynos/multimedia/openmax/osal/Android.mk | 44 + .../multimedia/openmax/osal/SEC_OSAL_Android.cpp | 579 +++ exynos/multimedia/openmax/osal/SEC_OSAL_Android.h | 81 + exynos/multimedia/openmax/osal/SEC_OSAL_ETC.c | 154 + exynos/multimedia/openmax/osal/SEC_OSAL_ETC.h | 48 + exynos/multimedia/openmax/osal/SEC_OSAL_Event.c | 217 + exynos/multimedia/openmax/osal/SEC_OSAL_Event.h | 61 + exynos/multimedia/openmax/osal/SEC_OSAL_Library.c | 54 + exynos/multimedia/openmax/osal/SEC_OSAL_Library.h | 46 + exynos/multimedia/openmax/osal/SEC_OSAL_Log.c | 53 + exynos/multimedia/openmax/osal/SEC_OSAL_Log.h | 78 + exynos/multimedia/openmax/osal/SEC_OSAL_Memory.c | 71 + exynos/multimedia/openmax/osal/SEC_OSAL_Memory.h | 48 + exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.c | 93 + exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.h | 47 + exynos/multimedia/openmax/osal/SEC_OSAL_Queue.c | 174 + exynos/multimedia/openmax/osal/SEC_OSAL_Queue.h | 66 + .../multimedia/openmax/osal/SEC_OSAL_Semaphore.c | 134 + .../multimedia/openmax/osal/SEC_OSAL_Semaphore.h | 49 + exynos/multimedia/openmax/osal/SEC_OSAL_Thread.c | 158 + exynos/multimedia/openmax/osal/SEC_OSAL_Thread.h | 48 + exynos/multimedia/utils/Android.mk | 1 + exynos/multimedia/utils/csc/Android.mk | 11 + exynos/multimedia/utils/csc/exynos4/Android.mk | 42 + .../utils/csc/exynos4/color_space_convertor.c | 1732 ++++++++ .../utils/csc/exynos4/color_space_convertor.h | 414 ++ exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp | 134 + exynos/multimedia/utils/csc/exynos4/csc_fimc.h | 106 + .../utils/csc/exynos4/csc_interleave_memcpy_neon.s | 120 + .../csc/exynos4/csc_linear_to_tiled_crop_neon.s | 492 +++ .../csc_linear_to_tiled_interleave_crop_neon.s | 563 +++ .../csc/exynos4/csc_tiled_to_linear_crop_neon.s | 701 ++++ .../csc_tiled_to_linear_deinterleave_crop_neon.s | 786 ++++ exynos/multimedia/utils/csc/exynos5/Android.mk | 35 + .../utils/csc/exynos5/color_space_convertor.c | 640 +++ .../utils/csc/exynos5/color_space_convertor.h | 411 ++ exynos/multimedia/utils/csc/exynos5/csc_fimc.cpp | 225 + exynos/multimedia/utils/csc/exynos5/csc_fimc.h | 106 + .../utils/csc/exynos5/csc_interleave_memcpy_neon.s | 120 + .../csc_tiled_to_linear_uv_deinterleave_neon.s | 249 ++ .../csc/exynos5/csc_tiled_to_linear_uv_neon.s | 216 + .../utils/csc/exynos5/csc_tiled_to_linear_y_neon.s | 231 ++ exynos4/Android.mk | 23 - exynos4/exynos4210/Android.mk | 22 + exynos4/exynos4210/liblights/Android.mk | 33 + exynos4/exynos4210/liblights/NOTICE | 190 + exynos4/exynos4210/liblights/lights.c | 253 ++ exynos4/exynos4210/libsensors/AkmSensor.cpp | 331 ++ exynos4/exynos4210/libsensors/AkmSensor.h | 64 + exynos4/exynos4210/libsensors/Android.mk | 45 + exynos4/exynos4210/libsensors/GyroSensor.cpp | 185 + exynos4/exynos4210/libsensors/GyroSensor.h | 55 + exynos4/exynos4210/libsensors/InputEventReader.cpp | 88 + exynos4/exynos4210/libsensors/InputEventReader.h | 47 + exynos4/exynos4210/libsensors/LightSensor.cpp | 160 + exynos4/exynos4210/libsensors/LightSensor.h | 55 + .../exynos4210/libsensors/MODULE_LICENSE_APACHE2 | 0 exynos4/exynos4210/libsensors/ProximitySensor.cpp | 144 + exynos4/exynos4210/libsensors/ProximitySensor.h | 54 + exynos4/exynos4210/libsensors/SensorBase.cpp | 128 + exynos4/exynos4210/libsensors/SensorBase.h | 65 + exynos4/exynos4210/libsensors/ak8973b.h | 51 + exynos4/exynos4210/libsensors/sensors.cpp | 326 ++ exynos4/exynos4210/libsensors/sensors.h | 144 + exynos4/hal/Android.mk | 31 +- exynos4/hal/include/SecHdmi.h | 1 + exynos4/hal/include/gralloc_priv.h | 313 +- exynos4/hal/include/s3c_lcd.h | 1 - exynos4/hal/include/sec_format.h | 2 - exynos4/hal/include/swconverter.h | 462 --- exynos4/hal/include/ump.h | 263 ++ exynos4/hal/include/ump_platform.h | 46 + exynos4/hal/include/ump_ref_drv.h | 59 + exynos4/hal/libcamera/Android.mk | 38 + exynos4/hal/libcamera/NOTICE | 190 + exynos4/hal/libcamera/SecCamera.cpp | 4360 ++++++++++++++++++++ exynos4/hal/libcamera/SecCamera.h | 695 ++++ exynos4/hal/libcamera/SecCameraHWInterface.cpp | 3410 +++++++++++++++ exynos4/hal/libcamera/SecCameraHWInterface.h | 242 ++ exynos4/hal/libfimc/Android.mk | 55 + exynos4/hal/libfimc/SecFimc.cpp | 1701 ++++++++ exynos4/hal/libfimg/Android.mk | 18 - exynos4/hal/libfimg/FimgApi.cpp | 245 -- exynos4/hal/libfimg/FimgApi.h | 186 - exynos4/hal/libfimg/FimgC210.cpp | 478 --- exynos4/hal/libfimg/FimgC210.h | 197 - exynos4/hal/libfimg3x/Android.mk | 22 + exynos4/hal/libfimg3x/FimgApi.cpp | 245 ++ exynos4/hal/libfimg3x/FimgApi.h | 186 + exynos4/hal/libfimg3x/FimgC210.cpp | 478 +++ exynos4/hal/libfimg3x/FimgC210.h | 197 + exynos4/hal/libfimg4x/Android.mk | 22 + exynos4/hal/libfimg4x/FimgApi.cpp | 376 ++ exynos4/hal/libfimg4x/FimgApi.h | 114 + exynos4/hal/libfimg4x/FimgExynos4.cpp | 302 ++ exynos4/hal/libfimg4x/FimgExynos4.h | 169 + exynos4/hal/libfimg4x/sec_g2d_4x.h | 326 ++ exynos4/hal/libgralloc_ump/Android.mk | 56 + exynos4/hal/libgralloc_ump/alloc_device.cpp | 498 +++ exynos4/hal/libgralloc_ump/alloc_device.h | 27 + exynos4/hal/libgralloc_ump/framebuffer_device.cpp | 465 +++ exynos4/hal/libgralloc_ump/framebuffer_device.h | 31 + exynos4/hal/libgralloc_ump/gr.h | 64 + exynos4/hal/libgralloc_ump/gralloc_helper.h | 34 + exynos4/hal/libgralloc_ump/gralloc_module.cpp | 480 +++ exynos4/hal/libhdmi/Android.mk | 17 + exynos4/hal/libhdmi/SecHdmi/Android.mk | 88 + exynos4/hal/libhdmi/SecHdmi/SecHdmi.cpp | 1957 +++++++++ exynos4/hal/libhdmi/SecHdmi/SecHdmiCommon.h | 138 + exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp | 2434 +++++++++++ exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h | 132 + exynos4/hal/libhdmi/SecHdmi/fimd_api.c | 229 + exynos4/hal/libhdmi/SecHdmi/fimd_api.h | 51 + exynos4/hal/libhdmi/libhdmiservice/Android.mk | 126 + exynos4/hal/libhdmi/libhdmiservice/Barrier.h | 55 + exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.cpp | 111 + exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.h | 74 + .../hal/libhdmi/libhdmiservice/MessageQueue.cpp | 197 + exynos4/hal/libhdmi/libhdmiservice/MessageQueue.h | 126 + .../hal/libhdmi/libhdmiservice/SecHdmiClient.cpp | 148 + exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.h | 86 + .../hal/libhdmi/libhdmiservice/SecTVOutService.cpp | 387 ++ .../hal/libhdmi/libhdmiservice/SecTVOutService.h | 174 + exynos4/hal/libhdmi/libsForhdmi/Android.mk | 17 + exynos4/hal/libhdmi/libsForhdmi/libcec/Android.mk | 33 + exynos4/hal/libhdmi/libsForhdmi/libcec/cec.h | 11 + exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.c | 386 ++ exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.h | 209 + exynos4/hal/libhdmi/libsForhdmi/libddc/Android.mk | 45 + exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.c | 285 ++ exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.h | 35 + exynos4/hal/libhdmi/libsForhdmi/libedid/Android.mk | 34 + exynos4/hal/libhdmi/libsForhdmi/libedid/edid.h | 181 + exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.c | 1262 ++++++ exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.h | 42 + exynos4/hal/libhwcomposer/Android.mk | 88 + exynos4/hal/libhwcomposer/SecHWC.cpp | 957 +++++ exynos4/hal/libhwcomposer/SecHWCLog.cpp | 51 + exynos4/hal/libhwcomposer/SecHWCUtils.cpp | 2077 ++++++++++ exynos4/hal/libhwcomposer/SecHWCUtils.h | 331 ++ exynos4/hal/libhwconverter/Android.mk | 11 +- exynos4/hal/libhwconverter/HardwareConverter.cpp | 3 +- exynos4/hal/libhwjpeg/Android.mk | 33 + exynos4/hal/libhwjpeg/jpeg_hal_unit.c | 572 +++ exynos4/hal/liblights/Android.mk | 33 - exynos4/hal/liblights/NOTICE | 190 - exynos4/hal/liblights/lights.c | 253 -- exynos4/hal/libs5pjpeg/Android.mk | 5 +- exynos4/hal/libsensors/AkmSensor.cpp | 331 -- exynos4/hal/libsensors/AkmSensor.h | 64 - exynos4/hal/libsensors/Android.mk | 45 - exynos4/hal/libsensors/GyroSensor.cpp | 185 - exynos4/hal/libsensors/GyroSensor.h | 55 - exynos4/hal/libsensors/InputEventReader.cpp | 88 - exynos4/hal/libsensors/InputEventReader.h | 47 - exynos4/hal/libsensors/LightSensor.cpp | 160 - exynos4/hal/libsensors/LightSensor.h | 55 - exynos4/hal/libsensors/MODULE_LICENSE_APACHE2 | 0 exynos4/hal/libsensors/ProximitySensor.cpp | 144 - exynos4/hal/libsensors/ProximitySensor.h | 54 - exynos4/hal/libsensors/SensorBase.cpp | 128 - exynos4/hal/libsensors/SensorBase.h | 65 - exynos4/hal/libsensors/ak8973b.h | 51 - exynos4/hal/libsensors/sensors.cpp | 326 -- exynos4/hal/libsensors/sensors.h | 144 - exynos4/hal/libswconverter/Android.mk | 30 +- exynos4/hal/libump/Android.mk | 48 - exynos4/hal/libump/Makefile | 38 - exynos4/hal/libump/arch_011_udd/ump_arch.c | 260 -- exynos4/hal/libump/arch_011_udd/ump_arch.h | 65 - exynos4/hal/libump/arch_011_udd/ump_frontend.c | 213 - exynos4/hal/libump/arch_011_udd/ump_internal.h | 62 - exynos4/hal/libump/arch_011_udd/ump_ref_drv.c | 124 - exynos4/hal/libump/include/ump/ump.h | 268 -- exynos4/hal/libump/include/ump/ump_debug.h | 287 -- exynos4/hal/libump/include/ump/ump_osu.h | 430 -- exynos4/hal/libump/include/ump/ump_platform.h | 68 - exynos4/hal/libump/include/ump/ump_ref_drv.h | 66 - exynos4/hal/libump/include/ump/ump_uk_types.h | 147 - exynos4/hal/libump/os/linux/ump_ioctl.h | 55 - exynos4/hal/libump/os/linux/ump_osu_locks.c | 537 --- exynos4/hal/libump/os/linux/ump_osu_memory.c | 60 - exynos4/hal/libump/os/linux/ump_uku.c | 193 - exynos4/hal/libump/os/ump_uku.h | 56 - exynos4/hal/libump/readme.txt | 31 - exynos4/hal/libump/ump.mak | 34 - exynos4/multimedia/Android.mk | 1 - exynos4/multimedia/codecs/Android.mk | 1 - exynos4/multimedia/codecs/sec_codecs/Android.mk | 1 - .../multimedia/codecs/sec_codecs/audio/Android.mk | 11 - .../codecs/sec_codecs/audio/exynos4/Android.mk | 14 - .../sec_codecs/audio/exynos4/srp/alp/Android.mk | 26 - .../audio/exynos4/srp/alp/include/srp_api.h | 52 - .../audio/exynos4/srp/alp/include/srp_error.h | 22 - .../audio/exynos4/srp/alp/include/srp_ioctl.h | 23 - .../sec_codecs/audio/exynos4/srp/alp/src/srp_api.c | 265 -- .../audio/exynos4/srp/libsa_jni/Android.mk | 13 - .../audio/exynos4/srp/libsa_jni/SACtrl.c | 33 - .../sec_codecs/audio/exynos4/srp/ulp/Android.mk | 23 - .../audio/exynos4/srp/ulp/include/srp_api.h | 55 - .../audio/exynos4/srp/ulp/include/srp_api_ctrl.h | 25 - .../audio/exynos4/srp/ulp/include/srp_ioctl.h | 66 - .../sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c | 381 -- .../audio/exynos4/srp/ulp/src/srp_api_ctrl.c | 331 -- .../codecs/sec_codecs/audio/exynos5/Android.mk | 9 - .../sec_codecs/audio/exynos5/srp/alp/Android.mk | 26 - .../audio/exynos5/srp/alp/include/srp_api.h | 52 - .../audio/exynos5/srp/alp/include/srp_error.h | 22 - .../audio/exynos5/srp/alp/include/srp_ioctl.h | 23 - .../sec_codecs/audio/exynos5/srp/alp/src/srp_api.c | 265 -- .../multimedia/codecs/sec_codecs/video/Android.mk | 11 - .../codecs/sec_codecs/video/exynos4/Android.mk | 11 - .../codecs/sec_codecs/video/exynos4/mfc/Android.mk | 38 - .../video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c | 1165 ------ .../video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c | 862 ---- .../video/exynos4/mfc/include/SsbSipMfcApi.h | 420 -- .../video/exynos4/mfc/include/mfc_errno.h | 79 - .../video/exynos4/mfc/include/mfc_interface.h | 525 --- .../sec_codecs/video/exynos4/mfc_v4l2/Android.mk | 34 - .../exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c | 1352 ------ .../exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c | 1206 ------ .../video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h | 382 -- .../video/exynos4/mfc_v4l2/include/mfc_errno.h | 79 - .../video/exynos4/mfc_v4l2/include/mfc_interface.h | 541 --- .../codecs/sec_codecs/video/exynos5/Android.mk | 7 - .../sec_codecs/video/exynos5/mfc_v4l2/Android.mk | 39 - .../exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c | 1740 -------- .../exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c | 1506 ------- .../video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h | 431 -- .../video/exynos5/mfc_v4l2/include/mfc_errno.h | 79 - .../video/exynos5/mfc_v4l2/include/mfc_interface.h | 588 --- exynos4/multimedia/libs/Android.mk | 1 - exynos4/multimedia/libs/libcsc/Android.mk | 64 - exynos4/multimedia/libs/libcsc/csc.c | 740 ---- exynos4/multimedia/libs/libcsc/csc.h | 355 -- .../multimedia/libs/libcsc/hwconverter_wrapper.cpp | 135 - .../multimedia/libs/libcsc/hwconverter_wrapper.h | 107 - exynos4/multimedia/libstagefrighthw/Android.mk | 23 - .../multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp | 147 - .../multimedia/libstagefrighthw/SEC_OMX_Plugin.h | 76 - exynos4/multimedia/openmax/Android.mk | 1 - exynos4/multimedia/openmax/sec_omx/Android.mk | 32 - .../openmax/sec_omx/component/audio/dec/Android.mk | 19 - .../sec_omx/component/audio/dec/SEC_OMX_Adec.c | 1376 ------ .../sec_omx/component/audio/dec/SEC_OMX_Adec.h | 132 - .../sec_omx/component/audio/dec/mp3/Android.mk | 31 - .../component/audio/dec/mp3/SEC_OMX_Mp3dec.c | 918 ----- .../component/audio/dec/mp3/SEC_OMX_Mp3dec.h | 63 - .../component/audio/dec/mp3/library_register.c | 58 - .../component/audio/dec/mp3/library_register.h | 54 - .../openmax/sec_omx/component/common/Android.mk | 43 - .../component/common/SEC_OMX_Basecomponent.c | 1535 ------- .../component/common/SEC_OMX_Basecomponent.h | 196 - .../sec_omx/component/common/SEC_OMX_Baseport.c | 1014 ----- .../sec_omx/component/common/SEC_OMX_Baseport.h | 95 - .../component/common/SEC_OMX_Resourcemanager.c | 478 --- .../component/common/SEC_OMX_Resourcemanager.h | 59 - .../openmax/sec_omx/component/video/dec/Android.mk | 23 - .../sec_omx/component/video/dec/SEC_OMX_Vdec.c | 1544 ------- .../sec_omx/component/video/dec/SEC_OMX_Vdec.h | 160 - .../sec_omx/component/video/dec/h264/Android.mk | 84 - .../component/video/dec/h264/SEC_OMX_H264dec.c | 2611 ------------ .../component/video/dec/h264/SEC_OMX_H264dec.h | 74 - .../component/video/dec/h264/library_register.c | 65 - .../component/video/dec/h264/library_register.h | 57 - .../sec_omx/component/video/dec/mpeg4/Android.mk | 65 - .../component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c | 2103 ---------- .../component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h | 92 - .../component/video/dec/mpeg4/library_register.c | 63 - .../component/video/dec/mpeg4/library_register.h | 59 - .../sec_omx/component/video/dec/vc1/Android.mk | 65 - .../component/video/dec/vc1/SEC_OMX_Wmvdec.c | 2014 --------- .../component/video/dec/vc1/SEC_OMX_Wmvdec.h | 94 - .../component/video/dec/vc1/library_register.c | 57 - .../component/video/dec/vc1/library_register.h | 52 - .../sec_omx/component/video/dec/vp8/Android.mk | 65 - .../component/video/dec/vp8/SEC_OMX_Vp8dec.c | 1665 -------- .../component/video/dec/vp8/SEC_OMX_Vp8dec.h | 66 - .../component/video/dec/vp8/library_register.c | 58 - .../component/video/dec/vp8/library_register.h | 54 - .../openmax/sec_omx/component/video/enc/Android.mk | 37 - .../sec_omx/component/video/enc/SEC_OMX_Venc.c | 1856 --------- .../sec_omx/component/video/enc/SEC_OMX_Venc.h | 166 - .../sec_omx/component/video/enc/h264/Android.mk | 39 - .../component/video/enc/h264/SEC_OMX_H264enc.c | 1605 ------- .../component/video/enc/h264/SEC_OMX_H264enc.h | 77 - .../component/video/enc/h264/library_register.c | 55 - .../component/video/enc/h264/library_register.h | 55 - .../sec_omx/component/video/enc/mpeg4/Android.mk | 39 - .../component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c | 1803 -------- .../component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h | 77 - .../component/video/enc/mpeg4/library_register.c | 64 - .../component/video/enc/mpeg4/library_register.h | 59 - exynos4/multimedia/openmax/sec_omx/core/Android.mk | 26 - .../sec_omx/core/SEC_OMX_Component_Register.c | 264 -- .../sec_omx/core/SEC_OMX_Component_Register.h | 75 - .../multimedia/openmax/sec_omx/core/SEC_OMX_Core.c | 364 -- .../multimedia/openmax/sec_omx/core/SEC_OMX_Core.h | 78 - .../openmax/sec_omx/include/khronos/OMX_Audio.h | 1311 ------ .../sec_omx/include/khronos/OMX_Component.h | 579 --- .../sec_omx/include/khronos/OMX_ContentPipe.h | 195 - .../openmax/sec_omx/include/khronos/OMX_Core.h | 1431 ------- .../openmax/sec_omx/include/khronos/OMX_IVCommon.h | 920 ----- .../openmax/sec_omx/include/khronos/OMX_Image.h | 328 -- .../openmax/sec_omx/include/khronos/OMX_Index.h | 258 -- .../openmax/sec_omx/include/khronos/OMX_Other.h | 337 -- .../openmax/sec_omx/include/khronos/OMX_Types.h | 347 -- .../openmax/sec_omx/include/khronos/OMX_Video.h | 1060 ----- .../openmax/sec_omx/include/sec/SEC_OMX_Def.h | 182 - .../openmax/sec_omx/include/sec/SEC_OMX_Macros.h | 66 - exynos4/multimedia/openmax/sec_omx/osal/Android.mk | 45 - .../openmax/sec_omx/osal/SEC_OSAL_Android.cpp | 581 --- .../openmax/sec_omx/osal/SEC_OSAL_Android.h | 81 - .../multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.c | 237 -- .../multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.h | 66 - .../openmax/sec_omx/osal/SEC_OSAL_Event.c | 217 - .../openmax/sec_omx/osal/SEC_OSAL_Event.h | 61 - .../openmax/sec_omx/osal/SEC_OSAL_Library.c | 54 - .../openmax/sec_omx/osal/SEC_OSAL_Library.h | 46 - .../multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.c | 56 - .../multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.h | 79 - .../openmax/sec_omx/osal/SEC_OSAL_Memory.c | 71 - .../openmax/sec_omx/osal/SEC_OSAL_Memory.h | 48 - .../openmax/sec_omx/osal/SEC_OSAL_Mutex.c | 93 - .../openmax/sec_omx/osal/SEC_OSAL_Mutex.h | 47 - .../openmax/sec_omx/osal/SEC_OSAL_Queue.c | 174 - .../openmax/sec_omx/osal/SEC_OSAL_Queue.h | 66 - .../openmax/sec_omx/osal/SEC_OSAL_Semaphore.c | 134 - .../openmax/sec_omx/osal/SEC_OSAL_Semaphore.h | 49 - .../openmax/sec_omx/osal/SEC_OSAL_Thread.c | 158 - .../openmax/sec_omx/osal/SEC_OSAL_Thread.h | 48 - exynos4210.mk | 23 + exynos4x12.mk | 22 + exynos5/hal/Android.mk | 28 + exynos5/hal/include/Exif.h | 231 ++ exynos5/hal/include/SecBuffer.h | 158 + exynos5/hal/include/SecFimc.h | 186 + exynos5/hal/include/SecHdmi.h | 250 ++ exynos5/hal/include/SecJpegCodecHal.h | 217 + exynos5/hal/include/SecJpegEncoder.h | 157 + exynos5/hal/include/SecRect.h | 172 + exynos5/hal/include/audio.h | 363 ++ exynos5/hal/include/exynos_mem.h | 28 + exynos5/hal/include/gralloc_priv.h | 210 + exynos5/hal/include/i2c-dev.h | 74 + exynos5/hal/include/ion.h | 144 + exynos5/hal/include/jpeg_api.h | 121 + exynos5/hal/include/jpeg_hal.h | 135 + exynos5/hal/include/malisw/arm_cstd/arm_cstd.h | 469 +++ .../include/malisw/arm_cstd/arm_cstd_compilers.h | 565 +++ .../include/malisw/arm_cstd/arm_cstd_pack_pop.h | 22 + .../include/malisw/arm_cstd/arm_cstd_pack_push.h | 22 + .../hal/include/malisw/arm_cstd/arm_cstd_types.h | 28 + .../include/malisw/arm_cstd/arm_cstd_types_gcc.h | 87 + .../include/malisw/arm_cstd/arm_cstd_types_rvct.h | 187 + exynos5/hal/include/malisw/mali_malisw.h | 237 ++ exynos5/hal/include/malisw/mali_stdtypes.h | 210 + exynos5/hal/include/malisw/mali_version_macros.h | 243 ++ exynos5/hal/include/media.h | 132 + exynos5/hal/include/s3c_lcd.h | 83 + exynos5/hal/include/s3c_mem.h | 48 + exynos5/hal/include/s5p_fimc.h | 160 + exynos5/hal/include/s5p_fimc_v4l2.h | 162 + exynos5/hal/include/s5p_tvout.h | 198 + exynos5/hal/include/s5p_tvout_v4l2.h | 207 + exynos5/hal/include/sec_format.h | 48 + exynos5/hal/include/sec_g2d.h | 251 ++ exynos5/hal/include/sec_utils.h | 306 ++ exynos5/hal/include/sec_utils_v4l2.h | 330 ++ exynos5/hal/include/ump.h | 627 +++ exynos5/hal/include/ump_common.h | 232 ++ exynos5/hal/include/ump_platform.h | 57 + exynos5/hal/include/ump_ref_drv.h | 59 + exynos5/hal/include/v4l2-mediabus.h | 116 + exynos5/hal/include/v4l2-subdev.h | 141 + exynos5/hal/include/video.h | 363 ++ exynos5/hal/include/videodev2.h | 2227 ++++++++++ exynos5/hal/include/videodev2_samsung.h | 1060 +++++ exynos5/hal/libcamera/Android.mk | 28 + exynos5/hal/libcamera/NOTICE | 190 + exynos5/hal/libcamera/SecCamera.cpp | 3693 +++++++++++++++++ exynos5/hal/libcamera/SecCamera.h | 698 ++++ exynos5/hal/libcamera/SecCameraHWInterface.cpp | 3043 ++++++++++++++ exynos5/hal/libcamera/SecCameraHWInterface.h | 219 + exynos5/hal/libcamera/mediactl.cpp | 668 +++ exynos5/hal/libcamera/mediactl.h | 270 ++ exynos5/hal/libcamera/v4l2subdev.h | 200 + exynos5/hal/libfimg4x/Android.mk | 22 + exynos5/hal/libfimg4x/FimgApi.cpp | 376 ++ exynos5/hal/libfimg4x/FimgApi.h | 114 + exynos5/hal/libfimg4x/FimgExynos5.cpp | 301 ++ exynos5/hal/libfimg4x/FimgExynos5.h | 169 + exynos5/hal/libfimg4x/sec_g2d_4x.h | 326 ++ exynos5/hal/libgralloc_ump/Android.mk | 59 + exynos5/hal/libgralloc_ump/alloc_device.cpp | 380 ++ exynos5/hal/libgralloc_ump/alloc_device.h | 22 + exynos5/hal/libgralloc_ump/framebuffer_device.cpp | 394 ++ exynos5/hal/libgralloc_ump/framebuffer_device.h | 25 + exynos5/hal/libgralloc_ump/gralloc_helper.h | 29 + exynos5/hal/libgralloc_ump/gralloc_module.cpp | 289 ++ exynos5/hal/libhdmi/Android.mk | 17 + exynos5/hal/libhdmi/SecHdmi/Android.mk | 76 + exynos5/hal/libhdmi/SecHdmi/SecGscaler.cpp | 1524 +++++++ exynos5/hal/libhdmi/SecHdmi/SecGscaler.h | 195 + exynos5/hal/libhdmi/SecHdmi/SecHdmi.cpp | 1985 +++++++++ exynos5/hal/libhdmi/SecHdmi/SecHdmiCommon.h | 118 + exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp | 1350 ++++++ exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h | 86 + exynos5/hal/libhdmi/SecHdmi/fimd_api.c | 229 + exynos5/hal/libhdmi/SecHdmi/fimd_api.h | 51 + exynos5/hal/libhdmi/libhdmiservice/Android.mk | 95 + exynos5/hal/libhdmi/libhdmiservice/Barrier.h | 55 + exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.cpp | 111 + exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.h | 74 + .../hal/libhdmi/libhdmiservice/MessageQueue.cpp | 190 + exynos5/hal/libhdmi/libhdmiservice/MessageQueue.h | 118 + .../hal/libhdmi/libhdmiservice/SecHdmiClient.cpp | 139 + exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.h | 84 + .../hal/libhdmi/libhdmiservice/SecTVOutService.cpp | 377 ++ .../hal/libhdmi/libhdmiservice/SecTVOutService.h | 175 + exynos5/hal/libhdmi/libsForhdmi/Android.mk | 17 + exynos5/hal/libhdmi/libsForhdmi/libcec/Android.mk | 33 + exynos5/hal/libhdmi/libsForhdmi/libcec/cec.h | 11 + exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.c | 386 ++ exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.h | 209 + exynos5/hal/libhdmi/libsForhdmi/libddc/Android.mk | 49 + exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.c | 289 ++ exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.h | 35 + exynos5/hal/libhdmi/libsForhdmi/libedid/Android.mk | 34 + exynos5/hal/libhdmi/libsForhdmi/libedid/edid.h | 181 + exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.c | 1265 ++++++ exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.h | 42 + exynos5/hal/libhwcomposer/Android.mk | 82 + exynos5/hal/libhwcomposer/SecHWC.cpp | 901 ++++ exynos5/hal/libhwcomposer/SecHWCLog.cpp | 51 + exynos5/hal/libhwcomposer/SecHWCUtils.cpp | 1703 ++++++++ exynos5/hal/libhwcomposer/SecHWCUtils.h | 309 ++ exynos5/hal/libhwjpeg/Android.mk | 37 + exynos5/hal/libhwjpeg/SecJpegCodecHal.cpp | 338 ++ exynos5/hal/libhwjpeg/SecJpegDecoderHal.cpp | 498 +++ exynos5/hal/libhwjpeg/SecJpegEncoder.cpp | 952 +++++ exynos5/hal/libhwjpeg/SecJpegEncoderHal.cpp | 497 +++ 558 files changed, 121235 insertions(+), 55167 deletions(-) create mode 100644 exynos/multimedia/Android.mk create mode 100644 exynos/multimedia/codecs/Android.mk create mode 100644 exynos/multimedia/codecs/audio/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos4/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/alp/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_api.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_error.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_ioctl.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/alp/src/srp_api.c create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/SACtrl.c create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api.c create mode 100644 exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c create mode 100644 exynos/multimedia/codecs/audio/exynos5/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos5/srp/alp/Android.mk create mode 100644 exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_api.h create mode 100644 exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_error.h create mode 100644 exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_ioctl.h create mode 100644 exynos/multimedia/codecs/audio/exynos5/srp/alp/src/srp_api.c create mode 100644 exynos/multimedia/codecs/video/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos4/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/include/SsbSipMfcApi.h create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_errno.h create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_interface.h create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h create mode 100644 exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h create mode 100644 exynos/multimedia/codecs/video/exynos5/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/Android.mk create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h create mode 100644 exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h create mode 100644 exynos/multimedia/libstagefrighthw/Android.mk create mode 100644 exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp create mode 100644 exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.h create mode 100644 exynos/multimedia/openmax/Android.mk create mode 100644 exynos/multimedia/openmax/component/audio/dec/Android.mk create mode 100644 exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.c create mode 100644 exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.h create mode 100644 exynos/multimedia/openmax/component/audio/dec/mp3/Android.mk create mode 100644 exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.c create mode 100644 exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.h create mode 100644 exynos/multimedia/openmax/component/audio/dec/mp3/library_register.c create mode 100644 exynos/multimedia/openmax/component/audio/dec/mp3/library_register.h create mode 100644 exynos/multimedia/openmax/component/common/Android.mk create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.c create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.h create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.c create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.h create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c create mode 100644 exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.h create mode 100644 exynos/multimedia/openmax/component/video/dec/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.c create mode 100644 exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.h create mode 100644 exynos/multimedia/openmax/component/video/dec/h264/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.c create mode 100644 exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.h create mode 100644 exynos/multimedia/openmax/component/video/dec/h264/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/dec/h264/library_register.h create mode 100644 exynos/multimedia/openmax/component/video/dec/mpeg4/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c create mode 100644 exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h create mode 100644 exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.h create mode 100644 exynos/multimedia/openmax/component/video/dec/vc1/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.c create mode 100644 exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.h create mode 100644 exynos/multimedia/openmax/component/video/dec/vc1/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/dec/vc1/library_register.h create mode 100644 exynos/multimedia/openmax/component/video/dec/vp8/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.c create mode 100644 exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.h create mode 100644 exynos/multimedia/openmax/component/video/dec/vp8/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/dec/vp8/library_register.h create mode 100644 exynos/multimedia/openmax/component/video/enc/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.c create mode 100644 exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.h create mode 100644 exynos/multimedia/openmax/component/video/enc/h264/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.c create mode 100644 exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.h create mode 100644 exynos/multimedia/openmax/component/video/enc/h264/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/enc/h264/library_register.h create mode 100644 exynos/multimedia/openmax/component/video/enc/mpeg4/Android.mk create mode 100644 exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c create mode 100644 exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h create mode 100644 exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.c create mode 100644 exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.h create mode 100644 exynos/multimedia/openmax/core/Android.mk create mode 100644 exynos/multimedia/openmax/core/SEC_OMX_Component_Register.c create mode 100644 exynos/multimedia/openmax/core/SEC_OMX_Component_Register.h create mode 100644 exynos/multimedia/openmax/core/SEC_OMX_Core.c create mode 100644 exynos/multimedia/openmax/core/SEC_OMX_Core.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Audio.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Component.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_ContentPipe.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Core.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_IVCommon.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Image.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Index.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Other.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Types.h create mode 100644 exynos/multimedia/openmax/include/khronos/OMX_Video.h create mode 100644 exynos/multimedia/openmax/include/sec/SEC_OMX_Def.h create mode 100644 exynos/multimedia/openmax/include/sec/SEC_OMX_Macros.h create mode 100644 exynos/multimedia/openmax/osal/Android.mk create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Android.cpp create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Android.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_ETC.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_ETC.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Event.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Event.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Library.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Library.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Log.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Log.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Memory.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Memory.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Queue.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Queue.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.h create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Thread.c create mode 100644 exynos/multimedia/openmax/osal/SEC_OSAL_Thread.h create mode 100644 exynos/multimedia/utils/Android.mk create mode 100644 exynos/multimedia/utils/csc/Android.mk create mode 100644 exynos/multimedia/utils/csc/exynos4/Android.mk create mode 100644 exynos/multimedia/utils/csc/exynos4/color_space_convertor.c create mode 100644 exynos/multimedia/utils/csc/exynos4/color_space_convertor.h create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_fimc.h create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_deinterleave_crop_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos5/Android.mk create mode 100644 exynos/multimedia/utils/csc/exynos5/color_space_convertor.c create mode 100644 exynos/multimedia/utils/csc/exynos5/color_space_convertor.h create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_fimc.cpp create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_fimc.h create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_interleave_memcpy_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_deinterleave_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_neon.s create mode 100644 exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_y_neon.s delete mode 100644 exynos4/Android.mk create mode 100644 exynos4/exynos4210/Android.mk create mode 100644 exynos4/exynos4210/liblights/Android.mk create mode 100644 exynos4/exynos4210/liblights/NOTICE create mode 100644 exynos4/exynos4210/liblights/lights.c create mode 100644 exynos4/exynos4210/libsensors/AkmSensor.cpp create mode 100644 exynos4/exynos4210/libsensors/AkmSensor.h create mode 100644 exynos4/exynos4210/libsensors/Android.mk create mode 100644 exynos4/exynos4210/libsensors/GyroSensor.cpp create mode 100644 exynos4/exynos4210/libsensors/GyroSensor.h create mode 100644 exynos4/exynos4210/libsensors/InputEventReader.cpp create mode 100644 exynos4/exynos4210/libsensors/InputEventReader.h create mode 100644 exynos4/exynos4210/libsensors/LightSensor.cpp create mode 100644 exynos4/exynos4210/libsensors/LightSensor.h create mode 100644 exynos4/exynos4210/libsensors/MODULE_LICENSE_APACHE2 create mode 100644 exynos4/exynos4210/libsensors/ProximitySensor.cpp create mode 100644 exynos4/exynos4210/libsensors/ProximitySensor.h create mode 100644 exynos4/exynos4210/libsensors/SensorBase.cpp create mode 100644 exynos4/exynos4210/libsensors/SensorBase.h create mode 100644 exynos4/exynos4210/libsensors/ak8973b.h create mode 100644 exynos4/exynos4210/libsensors/sensors.cpp create mode 100644 exynos4/exynos4210/libsensors/sensors.h delete mode 100644 exynos4/hal/include/swconverter.h create mode 100644 exynos4/hal/include/ump.h create mode 100644 exynos4/hal/include/ump_platform.h create mode 100644 exynos4/hal/include/ump_ref_drv.h create mode 100644 exynos4/hal/libcamera/Android.mk create mode 100644 exynos4/hal/libcamera/NOTICE create mode 100644 exynos4/hal/libcamera/SecCamera.cpp create mode 100644 exynos4/hal/libcamera/SecCamera.h create mode 100644 exynos4/hal/libcamera/SecCameraHWInterface.cpp create mode 100644 exynos4/hal/libcamera/SecCameraHWInterface.h create mode 100644 exynos4/hal/libfimc/Android.mk create mode 100644 exynos4/hal/libfimc/SecFimc.cpp delete mode 100644 exynos4/hal/libfimg/Android.mk delete mode 100644 exynos4/hal/libfimg/FimgApi.cpp delete mode 100644 exynos4/hal/libfimg/FimgApi.h delete mode 100644 exynos4/hal/libfimg/FimgC210.cpp delete mode 100644 exynos4/hal/libfimg/FimgC210.h create mode 100644 exynos4/hal/libfimg3x/Android.mk create mode 100644 exynos4/hal/libfimg3x/FimgApi.cpp create mode 100644 exynos4/hal/libfimg3x/FimgApi.h create mode 100644 exynos4/hal/libfimg3x/FimgC210.cpp create mode 100644 exynos4/hal/libfimg3x/FimgC210.h create mode 100644 exynos4/hal/libfimg4x/Android.mk create mode 100644 exynos4/hal/libfimg4x/FimgApi.cpp create mode 100644 exynos4/hal/libfimg4x/FimgApi.h create mode 100644 exynos4/hal/libfimg4x/FimgExynos4.cpp create mode 100644 exynos4/hal/libfimg4x/FimgExynos4.h create mode 100644 exynos4/hal/libfimg4x/sec_g2d_4x.h create mode 100644 exynos4/hal/libgralloc_ump/Android.mk create mode 100644 exynos4/hal/libgralloc_ump/alloc_device.cpp create mode 100644 exynos4/hal/libgralloc_ump/alloc_device.h create mode 100644 exynos4/hal/libgralloc_ump/framebuffer_device.cpp create mode 100644 exynos4/hal/libgralloc_ump/framebuffer_device.h create mode 100644 exynos4/hal/libgralloc_ump/gr.h create mode 100644 exynos4/hal/libgralloc_ump/gralloc_helper.h create mode 100644 exynos4/hal/libgralloc_ump/gralloc_module.cpp create mode 100644 exynos4/hal/libhdmi/Android.mk create mode 100644 exynos4/hal/libhdmi/SecHdmi/Android.mk create mode 100644 exynos4/hal/libhdmi/SecHdmi/SecHdmi.cpp create mode 100644 exynos4/hal/libhdmi/SecHdmi/SecHdmiCommon.h create mode 100644 exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp create mode 100644 exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h create mode 100644 exynos4/hal/libhdmi/SecHdmi/fimd_api.c create mode 100644 exynos4/hal/libhdmi/SecHdmi/fimd_api.h create mode 100644 exynos4/hal/libhdmi/libhdmiservice/Android.mk create mode 100644 exynos4/hal/libhdmi/libhdmiservice/Barrier.h create mode 100644 exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.cpp create mode 100644 exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.h create mode 100644 exynos4/hal/libhdmi/libhdmiservice/MessageQueue.cpp create mode 100644 exynos4/hal/libhdmi/libhdmiservice/MessageQueue.h create mode 100644 exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp create mode 100644 exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.h create mode 100644 exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.cpp create mode 100644 exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.h create mode 100644 exynos4/hal/libhdmi/libsForhdmi/Android.mk create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libcec/Android.mk create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libcec/cec.h create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.c create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.h create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libddc/Android.mk create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.c create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.h create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libedid/Android.mk create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libedid/edid.h create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.c create mode 100644 exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.h create mode 100644 exynos4/hal/libhwcomposer/Android.mk create mode 100644 exynos4/hal/libhwcomposer/SecHWC.cpp create mode 100644 exynos4/hal/libhwcomposer/SecHWCLog.cpp create mode 100644 exynos4/hal/libhwcomposer/SecHWCUtils.cpp create mode 100644 exynos4/hal/libhwcomposer/SecHWCUtils.h create mode 100644 exynos4/hal/libhwjpeg/Android.mk create mode 100644 exynos4/hal/libhwjpeg/jpeg_hal_unit.c delete mode 100644 exynos4/hal/liblights/Android.mk delete mode 100644 exynos4/hal/liblights/NOTICE delete mode 100644 exynos4/hal/liblights/lights.c delete mode 100644 exynos4/hal/libsensors/AkmSensor.cpp delete mode 100644 exynos4/hal/libsensors/AkmSensor.h delete mode 100644 exynos4/hal/libsensors/Android.mk delete mode 100644 exynos4/hal/libsensors/GyroSensor.cpp delete mode 100644 exynos4/hal/libsensors/GyroSensor.h delete mode 100644 exynos4/hal/libsensors/InputEventReader.cpp delete mode 100644 exynos4/hal/libsensors/InputEventReader.h delete mode 100644 exynos4/hal/libsensors/LightSensor.cpp delete mode 100644 exynos4/hal/libsensors/LightSensor.h delete mode 100644 exynos4/hal/libsensors/MODULE_LICENSE_APACHE2 delete mode 100644 exynos4/hal/libsensors/ProximitySensor.cpp delete mode 100644 exynos4/hal/libsensors/ProximitySensor.h delete mode 100644 exynos4/hal/libsensors/SensorBase.cpp delete mode 100644 exynos4/hal/libsensors/SensorBase.h delete mode 100644 exynos4/hal/libsensors/ak8973b.h delete mode 100644 exynos4/hal/libsensors/sensors.cpp delete mode 100644 exynos4/hal/libsensors/sensors.h delete mode 100644 exynos4/hal/libump/Android.mk delete mode 100644 exynos4/hal/libump/Makefile delete mode 100644 exynos4/hal/libump/arch_011_udd/ump_arch.c delete mode 100644 exynos4/hal/libump/arch_011_udd/ump_arch.h delete mode 100644 exynos4/hal/libump/arch_011_udd/ump_frontend.c delete mode 100644 exynos4/hal/libump/arch_011_udd/ump_internal.h delete mode 100644 exynos4/hal/libump/arch_011_udd/ump_ref_drv.c delete mode 100644 exynos4/hal/libump/include/ump/ump.h delete mode 100644 exynos4/hal/libump/include/ump/ump_debug.h delete mode 100644 exynos4/hal/libump/include/ump/ump_osu.h delete mode 100644 exynos4/hal/libump/include/ump/ump_platform.h delete mode 100644 exynos4/hal/libump/include/ump/ump_ref_drv.h delete mode 100644 exynos4/hal/libump/include/ump/ump_uk_types.h delete mode 100644 exynos4/hal/libump/os/linux/ump_ioctl.h delete mode 100644 exynos4/hal/libump/os/linux/ump_osu_locks.c delete mode 100644 exynos4/hal/libump/os/linux/ump_osu_memory.c delete mode 100644 exynos4/hal/libump/os/linux/ump_uku.c delete mode 100644 exynos4/hal/libump/os/ump_uku.h delete mode 100644 exynos4/hal/libump/readme.txt delete mode 100644 exynos4/hal/libump/ump.mak delete mode 100644 exynos4/multimedia/Android.mk delete mode 100644 exynos4/multimedia/codecs/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h delete mode 100644 exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h delete mode 100644 exynos4/multimedia/libs/Android.mk delete mode 100644 exynos4/multimedia/libs/libcsc/Android.mk delete mode 100644 exynos4/multimedia/libs/libcsc/csc.c delete mode 100644 exynos4/multimedia/libs/libcsc/csc.h delete mode 100644 exynos4/multimedia/libs/libcsc/hwconverter_wrapper.cpp delete mode 100644 exynos4/multimedia/libs/libcsc/hwconverter_wrapper.h delete mode 100644 exynos4/multimedia/libstagefrighthw/Android.mk delete mode 100644 exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp delete mode 100644 exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.h delete mode 100644 exynos4/multimedia/openmax/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/core/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Audio.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Component.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_ContentPipe.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Core.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_IVCommon.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Image.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Index.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Other.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Types.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Video.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Def.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Macros.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/Android.mk delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.cpp delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.h delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.c delete mode 100644 exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.h create mode 100644 exynos4210.mk create mode 100644 exynos4x12.mk create mode 100644 exynos5/hal/Android.mk create mode 100644 exynos5/hal/include/Exif.h create mode 100644 exynos5/hal/include/SecBuffer.h create mode 100644 exynos5/hal/include/SecFimc.h create mode 100644 exynos5/hal/include/SecHdmi.h create mode 100644 exynos5/hal/include/SecJpegCodecHal.h create mode 100644 exynos5/hal/include/SecJpegEncoder.h create mode 100644 exynos5/hal/include/SecRect.h create mode 100644 exynos5/hal/include/audio.h create mode 100644 exynos5/hal/include/exynos_mem.h create mode 100644 exynos5/hal/include/gralloc_priv.h create mode 100644 exynos5/hal/include/i2c-dev.h create mode 100644 exynos5/hal/include/ion.h create mode 100644 exynos5/hal/include/jpeg_api.h create mode 100644 exynos5/hal/include/jpeg_hal.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_compilers.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_pop.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_push.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_types.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_gcc.h create mode 100644 exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_rvct.h create mode 100644 exynos5/hal/include/malisw/mali_malisw.h create mode 100644 exynos5/hal/include/malisw/mali_stdtypes.h create mode 100644 exynos5/hal/include/malisw/mali_version_macros.h create mode 100644 exynos5/hal/include/media.h create mode 100644 exynos5/hal/include/s3c_lcd.h create mode 100644 exynos5/hal/include/s3c_mem.h create mode 100644 exynos5/hal/include/s5p_fimc.h create mode 100644 exynos5/hal/include/s5p_fimc_v4l2.h create mode 100644 exynos5/hal/include/s5p_tvout.h create mode 100644 exynos5/hal/include/s5p_tvout_v4l2.h create mode 100644 exynos5/hal/include/sec_format.h create mode 100644 exynos5/hal/include/sec_g2d.h create mode 100644 exynos5/hal/include/sec_utils.h create mode 100644 exynos5/hal/include/sec_utils_v4l2.h create mode 100644 exynos5/hal/include/ump.h create mode 100644 exynos5/hal/include/ump_common.h create mode 100644 exynos5/hal/include/ump_platform.h create mode 100644 exynos5/hal/include/ump_ref_drv.h create mode 100644 exynos5/hal/include/v4l2-mediabus.h create mode 100644 exynos5/hal/include/v4l2-subdev.h create mode 100644 exynos5/hal/include/video.h create mode 100644 exynos5/hal/include/videodev2.h create mode 100644 exynos5/hal/include/videodev2_samsung.h create mode 100644 exynos5/hal/libcamera/Android.mk create mode 100644 exynos5/hal/libcamera/NOTICE create mode 100644 exynos5/hal/libcamera/SecCamera.cpp create mode 100644 exynos5/hal/libcamera/SecCamera.h create mode 100644 exynos5/hal/libcamera/SecCameraHWInterface.cpp create mode 100644 exynos5/hal/libcamera/SecCameraHWInterface.h create mode 100644 exynos5/hal/libcamera/mediactl.cpp create mode 100644 exynos5/hal/libcamera/mediactl.h create mode 100644 exynos5/hal/libcamera/v4l2subdev.h create mode 100644 exynos5/hal/libfimg4x/Android.mk create mode 100644 exynos5/hal/libfimg4x/FimgApi.cpp create mode 100644 exynos5/hal/libfimg4x/FimgApi.h create mode 100644 exynos5/hal/libfimg4x/FimgExynos5.cpp create mode 100644 exynos5/hal/libfimg4x/FimgExynos5.h create mode 100644 exynos5/hal/libfimg4x/sec_g2d_4x.h create mode 100644 exynos5/hal/libgralloc_ump/Android.mk create mode 100644 exynos5/hal/libgralloc_ump/alloc_device.cpp create mode 100644 exynos5/hal/libgralloc_ump/alloc_device.h create mode 100644 exynos5/hal/libgralloc_ump/framebuffer_device.cpp create mode 100644 exynos5/hal/libgralloc_ump/framebuffer_device.h create mode 100644 exynos5/hal/libgralloc_ump/gralloc_helper.h create mode 100644 exynos5/hal/libgralloc_ump/gralloc_module.cpp create mode 100644 exynos5/hal/libhdmi/Android.mk create mode 100644 exynos5/hal/libhdmi/SecHdmi/Android.mk create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecGscaler.cpp create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecGscaler.h create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecHdmi.cpp create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecHdmiCommon.h create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp create mode 100644 exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h create mode 100644 exynos5/hal/libhdmi/SecHdmi/fimd_api.c create mode 100644 exynos5/hal/libhdmi/SecHdmi/fimd_api.h create mode 100644 exynos5/hal/libhdmi/libhdmiservice/Android.mk create mode 100644 exynos5/hal/libhdmi/libhdmiservice/Barrier.h create mode 100644 exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.cpp create mode 100644 exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.h create mode 100644 exynos5/hal/libhdmi/libhdmiservice/MessageQueue.cpp create mode 100644 exynos5/hal/libhdmi/libhdmiservice/MessageQueue.h create mode 100644 exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp create mode 100644 exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.h create mode 100644 exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.cpp create mode 100644 exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.h create mode 100644 exynos5/hal/libhdmi/libsForhdmi/Android.mk create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libcec/Android.mk create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libcec/cec.h create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.c create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.h create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libddc/Android.mk create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.c create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.h create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libedid/Android.mk create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libedid/edid.h create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.c create mode 100644 exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.h create mode 100644 exynos5/hal/libhwcomposer/Android.mk create mode 100644 exynos5/hal/libhwcomposer/SecHWC.cpp create mode 100644 exynos5/hal/libhwcomposer/SecHWCLog.cpp create mode 100644 exynos5/hal/libhwcomposer/SecHWCUtils.cpp create mode 100644 exynos5/hal/libhwcomposer/SecHWCUtils.h create mode 100644 exynos5/hal/libhwjpeg/Android.mk create mode 100644 exynos5/hal/libhwjpeg/SecJpegCodecHal.cpp create mode 100644 exynos5/hal/libhwjpeg/SecJpegDecoderHal.cpp create mode 100644 exynos5/hal/libhwjpeg/SecJpegEncoder.cpp create mode 100644 exynos5/hal/libhwjpeg/SecJpegEncoderHal.cpp diff --git a/exynos/multimedia/Android.mk b/exynos/multimedia/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/exynos/multimedia/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/exynos/multimedia/codecs/Android.mk b/exynos/multimedia/codecs/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/exynos/multimedia/codecs/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/exynos/multimedia/codecs/audio/Android.mk b/exynos/multimedia/codecs/audio/Android.mk new file mode 100644 index 0000000..3bc3577 --- /dev/null +++ b/exynos/multimedia/codecs/audio/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos4/Android.mk +endif + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos5/Android.mk +endif diff --git a/exynos/multimedia/codecs/audio/exynos4/Android.mk b/exynos/multimedia/codecs/audio/exynos4/Android.mk new file mode 100644 index 0000000..df938be --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_AUDIO_PATH :=$(LOCAL_PATH) + +ifeq ($(BOARD_USE_ALP_AUDIO), true) + include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk +else + ifeq ($(USE_ULP_AUDIO), true) + include $(LOCAL_AUDIO_PATH)/srp/ulp/Android.mk + include $(LOCAL_AUDIO_PATH)/srp/libsa_jni/Android.mk + endif +endif diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/alp/Android.mk b/exynos/multimedia/codecs/audio/exynos4/srp/alp/Android.mk new file mode 100644 index 0000000..7393f68 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/alp/Android.mk @@ -0,0 +1,26 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + include/srp_api.h \ + include/srp_ioctl.h \ + include/srp_error.h + +LOCAL_SRC_FILES := \ + src/srp_api.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include + +LOCAL_MODULE := libsrpapi + +LOCAL_MODULE_TAGS := optional + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_api.h b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_api.h new file mode 100644 index 0000000..ad65b90 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_api.h @@ -0,0 +1,52 @@ +#ifndef __SRP_API_H__ +#define __SRP_API_H__ + +#include "srp_ioctl.h" +#include "srp_error.h" + +#define SRP_DEV_NAME "dev/srp" + +#define SRP_INIT_BLOCK_MODE 0 +#define SRP_INIT_NONBLOCK_MODE 1 + +#define SRP_PENDING_STATE_RUNNING 0 +#define SRP_PENDING_STATE_PENDING 1 + +struct srp_buf_info { + void *mmapped_addr; + void *addr; + unsigned int mmapped_size; + unsigned int size; + int num; +}; + +struct srp_dec_info { + unsigned int sample_rate; + unsigned int channels; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int SRP_Create(int block_mode); +int SRP_Init(); +int SRP_Decode(void *buff, int size_byte); +int SRP_Send_EOS(void); +int SRP_SetParams(int id, unsigned long val); +int SRP_GetParams(int id, unsigned long *pval); +int SRP_Deinit(void); +int SRP_Terminate(void); +int SRP_IsOpen(void); + +int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num); +int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num); +int SRP_Get_Dec_Info(struct srp_dec_info *dec_info); +int SRP_Get_PCM(void **addr, unsigned int *size); +int SRP_Flush(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__SRP_API_H__ */ diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_error.h b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_error.h new file mode 100644 index 0000000..7f79452 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_error.h @@ -0,0 +1,22 @@ +#ifndef _SRP_ERROR_H_ +#define _SRP_ERROR_H_ + +typedef enum { + SRP_RETURN_OK = 0, + + SRP_ERROR_OPEN_FAIL = -1000, + SRP_ERROR_ALREADY_OPEN = -1001, + SRP_ERROR_NOT_READY = -1002, + + SRP_ERROR_IBUF_OVERFLOW = -2000, + SRP_ERROR_IBUF_INFO = -2001, + + SRP_ERROR_OBUF_READ = -3000, + SRP_ERROR_OBUF_INFO = -3001, + SRP_ERROR_OBUF_MMAP = -3002, + + SRP_ERROR_INVALID_SETTING = -4000, + SRP_ERROR_GETINFO_FAIL = -4001 +} SRP_ERRORTYPE; + +#endif /* _SRP_ERROR_H_ */ diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_ioctl.h b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_ioctl.h new file mode 100644 index 0000000..21d55df --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/alp/include/srp_ioctl.h @@ -0,0 +1,23 @@ +#ifndef __SRP_IOCTL_H__ +#define __SRP_IOCTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRP_INIT (0x10000) +#define SRP_DEINIT (0x10001) +#define SRP_GET_MMAP_SIZE (0x10002) +#define SRP_FLUSH (0x20002) +#define SRP_SEND_EOS (0x20005) +#define SRP_GET_IBUF_INFO (0x20007) +#define SRP_GET_OBUF_INFO (0x20008) +#define SRP_STOP_EOS_STATE (0x30007) +#define SRP_GET_DEC_INFO (0x30008) + +#ifdef __cplusplus +} +#endif + +#endif /* __SRP_IOCTL_H__ */ + diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/alp/src/srp_api.c b/exynos/multimedia/codecs/audio/exynos4/srp/alp/src/srp_api.c new file mode 100644 index 0000000..56125fb --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/alp/src/srp_api.c @@ -0,0 +1,265 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "srp_api.h" + +#define LOG_NDEBUG 1 +#define LOG_TAG "libsrpapi" +#include + +static struct srp_buf_info ibuf_info; +static struct srp_buf_info obuf_info; +static struct srp_buf_info pcm_info; + +static int srp_dev = -1; +static int srp_block_mode = SRP_INIT_BLOCK_MODE; + +int SRP_Create(int block_mode) +{ + if (srp_dev == -1) { + srp_block_mode = block_mode; + srp_dev = open(SRP_DEV_NAME, O_RDWR | + ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); + if (srp_dev > 0) + return srp_dev; + else + return SRP_ERROR_OPEN_FAIL; + } + + LOGE("%s: Device is already opened", __func__); + return SRP_ERROR_ALREADY_OPEN; +} + +int SRP_Init() +{ + int ret = SRP_RETURN_OK; + unsigned int mmapped_size = 0; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_INIT); + if (ret < 0) + return ret; + + /* mmap for OBUF */ + ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size); + if (ret < 0) { + LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__); + return SRP_ERROR_OBUF_MMAP; + } + obuf_info.mmapped_addr = mmap(0, mmapped_size, + PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0); + if (!obuf_info.mmapped_addr) { + LOGE("%s: mmap is failed", __func__); + return SRP_ERROR_OBUF_MMAP; + } + obuf_info.mmapped_size = mmapped_size; + + ret = SRP_RETURN_OK; + } else { + LOGE("%s: Device is not ready", __func__); + ret = SRP_ERROR_NOT_READY; /* device is not created */ + } + + return ret; +} + +int SRP_Decode(void *buff, int size_byte) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + if (size_byte > 0) { + LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte); + + ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ + if (ret < 0) { + if (ret != SRP_ERROR_IBUF_OVERFLOW) + LOGE("SRP_Decode returned error code: %d", ret); + } + return ret; /* Write Success */ + } else { + return ret; + } + } + + LOGE("%s: Device is not ready", __func__); + return SRP_ERROR_NOT_READY; +} + +int SRP_Send_EOS(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_SEND_EOS); + + return SRP_ERROR_NOT_READY; +} + +int SRP_SetParams(int id, unsigned long val) +{ + if (srp_dev != -1) + return 0; /* not yet */ + + return SRP_ERROR_NOT_READY; +} + +int SRP_GetParams(int id, unsigned long *pval) +{ + if (srp_dev != -1) + return ioctl(srp_dev, id, pval); + + return SRP_ERROR_NOT_READY; +} + +int SRP_Flush(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_FLUSH); + + return SRP_ERROR_NOT_READY; +} + +int SRP_Get_PCM(void **addr, unsigned int *size) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + ret = read(srp_dev, &pcm_info, 0); + if (ret == -1) { + *size = 0; + LOGE("%s: PCM read fail", __func__); + return SRP_ERROR_OBUF_READ; + } + + *addr = pcm_info.addr; + *size = pcm_info.size; + } else { + return SRP_ERROR_NOT_READY; + } + + return ret; /* Read Success */ +} + +int SRP_Get_Dec_Info(struct srp_dec_info *dec_info) +{ + int ret; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info); + if (ret < 0) { + LOGE("%s: Failed to get dec info", __func__); + return SRP_ERROR_GETINFO_FAIL; + } + + LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate); + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info); + if (ret == -1) { + LOGE("%s: Failed to get Ibuf info", __func__); + return SRP_ERROR_IBUF_INFO; + } + + *addr = ibuf_info.addr; + *size = ibuf_info.size; + *num = ibuf_info.num; + + if (*num == 0) { + LOGE("%s: IBUF num is 0", __func__); + return SRP_ERROR_INVALID_SETTING; + } + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + if (obuf_info.addr == NULL) { + ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info); + if (ret < 0) { + LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__); + return SRP_ERROR_OBUF_INFO; + } + } + + *addr = obuf_info.addr; + *size = obuf_info.size; + *num = obuf_info.num; + + if (*num == 0) { + LOGE("%s: OBUF num is 0", __func__); + return SRP_ERROR_INVALID_SETTING; + } + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Deinit(void) +{ + if (srp_dev != -1) { + munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size); + return ioctl(srp_dev, SRP_DEINIT); + } + + return SRP_ERROR_NOT_READY; +} + +int SRP_Terminate(void) +{ + int ret; + + if (srp_dev != -1) { + ret = close(srp_dev); + + if (ret == 0) { + srp_dev = -1; /* device closed */ + return SRP_RETURN_OK; + } + } + + return SRP_ERROR_NOT_READY; +} + +int SRP_IsOpen(void) +{ + if (srp_dev == -1) { + LOGV("%s: Device is not opened", __func__); + return 0; + } + + LOGV("%s: Device is opened", __func__); + return 1; +} diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/Android.mk b/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/Android.mk new file mode 100644 index 0000000..8450845 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_MODULE := libsa_jni +LOCAL_SRC_FILES := SACtrl.c + +LOCAL_SHARED_LIBRARIES := libcutils +LOCAL_STATIC_LIBRARIES := libsrpapi + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/SACtrl.c b/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/SACtrl.c new file mode 100644 index 0000000..6b99dc3 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/libsa_jni/SACtrl.c @@ -0,0 +1,33 @@ +#include +#include + +#include +#include +#include + +#include "srp_api_ctrl.h" + +#define LOG_TAG "libsa_jni" +#include + +void Java_com_android_music_SetSACtrlJNI_set(JNIEnv * env, jobject obj, int effect_num) +{ + unsigned long effect_enable = effect_num ? 1 : 0; + unsigned int ret; + + LOGD("Sound effect[%d]", effect_num); + + ret = SRP_Ctrl_Enable_Effect(effect_enable); + if (ret < 0) { + LOGE("%s: Couldn't enabled effect\n", __func__); + return; + } + + SRP_Ctrl_Set_Effect_Def(effect_num << 5); + if (ret < 0) { + LOGE("%s: Couldn't defined effect\n", __func__); + return; + } + + return; +} diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/Android.mk b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/Android.mk new file mode 100644 index 0000000..5b1d397 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + src/srp_api.c \ + src/srp_api_ctrl.c + +LOCAL_MODULE := libsrpapi + +LOCAL_MODULE_TAGS := optional + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_COPY_HEADERS := \ + include/srp_api.h \ + include/srp_api_ctrl.h \ + include/srp_ioctl.h + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api.h b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api.h new file mode 100644 index 0000000..74598e5 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api.h @@ -0,0 +1,55 @@ +#ifndef __SRP_API_H__ +#define __SRP_API_H__ + +#include "srp_ioctl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int SRP_Create(int block_mode); +int SRP_Init(unsigned int ibuf_size); +int SRP_Decode(void *buff, int size_byte); +int SRP_Send_EOS(void); +int SRP_Resume_EOS(void); +int SRP_Pause(void); +int SRP_Stop(void); +int SRP_Flush(void); +int SRP_SetParams(int id, unsigned long val); +int SRP_GetParams(int id, unsigned long *pval); +int SRP_Deinit(void); +int SRP_Terminate(void); +int SRP_IsOpen(void); + +#define SRP_DEV_NAME "dev/srp" + +#define SRP_INIT_BLOCK_MODE 0 +#define SRP_INIT_NONBLOCK_MODE 1 + +#define SRP_PENDING_STATE_RUNNING 0 +#define SRP_PENDING_STATE_PENDING 1 + +#define SRP_ERROR_LOSTSYNC 0x00101 +#define SRP_ERROR_BADLAYER 0x00102 +#define SRP_ERROR_BADBITRATE 0x00103 +#define SRP_ERROR_BADSAMPLERATE 0x00104 +#define SRP_ERROR_BADEMPHASIS 0x00105 + +#define SRP_ERROR_BADCRC 0x00201 +#define SRP_ERROR_BADBITALLOC 0x00211 +#define SRP_ERROR_BADBADSCALEFACTOR 0x00221 +#define SRP_ERROR_BADFRAMELEN 0x00231 +#define SRP_ERROR_BADBIGVALUES 0x00232 +#define SRP_ERROR_BADBLOCKTYPE 0x00233 +#define SRP_ERROR_BADSCFSI 0x00234 +#define SRP_ERROR_BADDATAPTR 0x00235 +#define SRP_ERROR_BADPART3LEN 0x00236 +#define SRP_ERROR_BADHUFFTABLE 0x00237 +#define SRP_ERROR_BADHUFFDATA 0x00238 +#define SRP_ERROR_BADSTEREO 0x00239 + +#ifdef __cplusplus +} +#endif + +#endif /*__SRP_API_H__ */ diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h new file mode 100644 index 0000000..3b17acf --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h @@ -0,0 +1,25 @@ +#ifndef __SRP_API_CTRL_H__ +#define __SRP_API_CTRL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRP_CTRL_DEV_NAME "dev/srp_ctrl" + +int SRP_Ctrl_Set_Effect(int effect); /* test only */ +int SRP_Ctrl_Enable_Effect(int on); +int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def); +int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user); +int SRP_Ctrl_Set_Pcm_Dump(int on); +int SRP_Ctrl_Get_Pcm_Dump_State(void); +int SRP_Ctrl_Set_Gain(float value); +int SRP_Ctrl_Get_Running_Stat(void); +int SRP_Ctrl_Get_Open_Stat(void); +short *SRP_Ctrl_Get_Pcm(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SRP_API_CTRL_H__ */ diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h new file mode 100644 index 0000000..a20b1ac --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h @@ -0,0 +1,66 @@ +#ifndef __SRP_IOCTL_H__ +#define __SRP_IOCTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* constants for srp device node */ +#define SRP_INIT (0x10000) +#define SRP_DEINIT (0x10001) + +#define SRP_PAUSE (0x20000) +#define SRP_STOP (0x20001) +#define SRP_FLUSH (0x20002) +#define SRP_WAIT_EOS (0x20003) +#define SRP_EFFECT (0x20004) +#define SRP_SEND_EOS (0x20005) +#define SRP_RESUME_EOS (0x20006) + +#define SRP_PENDING_STATE (0x30000) +#define SRP_ERROR_STATE (0x30001) +#define SRP_DECODED_FRAME_NO (0x30002) +#define SRP_DECODED_ONE_FRAME_SIZE (0x30003) +#define SRP_DECODED_FRAME_SIZE (0x30004) +#define SRP_DECODED_PCM_SIZE (0x30005) +#define SRP_CHANNEL_COUNT (0x30006) +#define SRP_STOP_EOS_STATE (0x30007) + +/* constants for srp_ctrl device node*/ +#define SRP_CTRL_SET_GAIN (0xFF000) +#define SRP_CTRL_SET_EFFECT (0xFF001) +#define SRP_CTRL_GET_PCM_1KFRAME (0xFF002) +#define SRP_CTRL_PCM_DUMP_OP (0xFF003) + +#define SRP_CTRL_EFFECT_ENABLE (0xFF010) +#define SRP_CTRL_EFFECT_DEF (0xFF011) +#define SRP_CTRL_EFFECT_EQ_USR (0xFF012) +#define SRP_CTRL_EFFECT_SPEAKER (0xFF013) + +#define SRP_CTRL_IS_RUNNING (0xFF100) +#define SRP_CTRL_IS_OPENED (0xFF101) +#define SRP_CTRL_GET_OP_LEVEL (0xFF102) +#define SRP_CTRL_IS_PCM_DUMP (0xFF103) + +#define SRP_CTRL_ALTFW_STATE (0xFF200) +#define SRP_CTRL_ALTFW_LOAD (0xFF201) + +/* constants for SRP firmware */ +#define SRP_FW_CODE1 0 +#define SRP_FW_CODE20 1 +#define SRP_FW_CODE21 2 +#define SRP_FW_CODE22 3 +#define SRP_FW_CODE30 4 +#define SRP_FW_CODE31 5 + +#define SRP_FW_VLIW 0 +#define SRP_FW_CGA 1 +#define SRP_FW_CGA_SA 2 +#define SRP_FW_DATA 3 + +#ifdef __cplusplus +} +#endif + +#endif /* __SRP_IOCTL_H__ */ + diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api.c b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api.c new file mode 100644 index 0000000..b0c0e5e --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api.c @@ -0,0 +1,381 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "srp_api.h" + +#define LOG_TAG "libsrpapi" +#include + +/* Disable LOGD message */ +#ifdef LOGD +#undef LOGD +#endif +#define LOGD(...) + +//#define _USE_WBUF_ /* Buffering before writing srp-rp device */ +//#define _DUMP_TO_FILE_ +//#define _USE_FW_FROM_DISK_ + +#ifdef _USE_WBUF_ +#define WBUF_LEN_MUL 2 +#endif + +static int srp_dev = -1; +static int srp_ibuf_size = 0; +static int srp_block_mode = SRP_INIT_BLOCK_MODE; + +static unsigned char *wbuf; +static int wbuf_size; +static int wbuf_pos; + +#ifdef _DUMP_TO_FILE_ +static FILE *fp_dump = NULL; +#endif + +#ifdef _USE_WBUF_ +static int WriteBuff_Init(void) +{ + if (wbuf == NULL) { + wbuf_size = srp_ibuf_size * WBUF_LEN_MUL; + wbuf_pos = 0; + wbuf = (unsigned char *)malloc(wbuf_size); + LOGD("%s: WriteBuffer %dbytes allocated", __func__, wbuf_size); + return 0; + } + + LOGE("%s: WriteBuffer already allocated", __func__); + return -1; +} + +static int WriteBuff_Deinit(void) +{ + if (wbuf != NULL) { + free(wbuf); + wbuf = NULL; + return 0; + } + + LOGE("%s: WriteBuffer is not ready", __func__); + return -1; +} + +static int WriteBuff_Write(unsigned char *buff, int size_byte) +{ + int write_byte; + + if ((wbuf_pos + size_byte) < wbuf_size) { + memcpy(&wbuf[wbuf_pos], buff, size_byte); + wbuf_pos += size_byte; + } else { + LOGE("%s: WriteBuffer is filled [%d], ignoring write [%d]", __func__, wbuf_pos, size_byte); + return -1; /* Insufficient buffer */ + } + + return wbuf_pos; +} + +static void WriteBuff_Consume(void) +{ + memcpy(wbuf, &wbuf[srp_ibuf_size], srp_ibuf_size * (WBUF_LEN_MUL - 1)); + wbuf_pos -= srp_ibuf_size; +} + +static void WriteBuff_Flush(void) +{ + wbuf_pos = 0; +} +#endif + +int SRP_Create(int block_mode) +{ + if (srp_dev == -1) { +#ifdef _USE_FW_FROM_DISK_ + SRP_Check_AltFirmware(); +#endif + + srp_block_mode = block_mode; + srp_dev = open(SRP_DEV_NAME, O_RDWR | + ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); + + return srp_dev; + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device alreay opened */ +} + +int SRP_Init(unsigned int ibuf_size) +{ + int ret; + + if (srp_dev != -1) { + srp_ibuf_size = ibuf_size; + ret = ioctl(srp_dev, SRP_INIT, srp_ibuf_size); /* Initialize IBUF size (4KB ~ 18KB) */ + +#ifdef _DUMP_TO_FILE_ + char outname[256]; + int cnt = 0; + + while (1) { + sprintf(outname, "/data/rp_dump_%04d.mp3", cnt++); + if (fp_dump = fopen(outname, "rb")) { /* file exist? */ + fclose(fp_dump); + } else { + break; + } + } + + LOGD("%s: Dump MP3 to %s", __func__, outname); + if (fp_dump = fopen(outname, "wb")) + LOGD("%s: Success to open %s", __func__, outname); + else + LOGD("%s: Fail to open %s", __func__, outname); +#endif + +#ifdef _USE_WBUF_ + if (ret != -1) + return WriteBuff_Init(); +#else + return ret; +#endif + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device is not created */ +} + +#ifdef _USE_WBUF_ +int SRP_Decode(void *buff, int size_byte) +{ + int ret; + int val; + int err_code = 0; + + if (srp_dev != -1) { + /* Check wbuf before writing buff */ + while (wbuf_pos >= srp_ibuf_size) { /* Write_Buffer filled? (IBUF Size)*/ + LOGD("%s: Write Buffer is full, Send data to RP", __func__); + + ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ + if (ret == -1) { /* Fail? */ + ioctl(srp_dev, SRP_ERROR_STATE, &val); + if (!val) { /* Write error? */ + LOGE("%s: IBUF write fail", __func__); + return -1; + } else { /* Write OK, but RP decode error? */ + err_code = val; + LOGE("%s: RP decode error [0x%05X]", __func__, err_code); + } + } +#ifdef _DUMP_TO_FILE_ + if (fp_dump) + fwrite(wbuf, srp_ibuf_size, 1, fp_dump); +#endif + WriteBuff_Consume(); + } + + ret = WriteBuff_Write((unsigned char *)buff, size_byte); + if (ret == -1) + return -1; /* Buffering error */ + + LOGD("%s: Write Buffer remain [%d]", __func__, wbuf_pos); + return err_code; /* Write Success */ + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device is not created */ +} + +int SRP_Send_EOS(void) +{ + int ret; + int val; + + if (srp_dev != -1) { + /* Check wbuf before writing buff */ + while (wbuf_pos) { /* Write_Buffer ramain?*/ + if (wbuf_pos < srp_ibuf_size) { + memset(wbuf + wbuf_pos, 0xFF, srp_ibuf_size - wbuf_pos); /* Fill dummy data */ + wbuf_pos = srp_ibuf_size; + } + + ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ + if (ret == -1) { /* Fail? */ + ret = ioctl(srp_dev, SRP_ERROR_STATE, &val); + if (!val) { /* Write error? */ + LOGE("%s: IBUF write fail", __func__); + return -1; + } else { /* RP decoe error? */ + LOGE("%s: RP decode error [0x%05X]", __func__, val); + return -1; + } + } else { /* Success? */ +#ifdef _DUMP_TO_FILE_ + if (fp_dump) + fwrite(wbuf, srp_ibuf_size, 1, fp_dump); +#endif + WriteBuff_Consume(); + } + } + + memset(wbuf, 0xFF, srp_ibuf_size); /* Fill dummy data */ + write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ + + /* Wait until RP decoding over */ + return ioctl(srp_dev, SRP_WAIT_EOS); + } + + return -1; /* device is not created */ +} +#else /* Without WBUF */ +int SRP_Decode(void *buff, int size_byte) +{ + int ret; + int val; + int err_code = 0; + + if (srp_dev != -1) { + LOGD("%s: Send data to RP (%d bytes)", __func__, size_byte); + + ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ + if (ret == -1) { /* Fail? */ + ioctl(srp_dev, SRP_ERROR_STATE, &val); + if (!val) { /* Write error? */ + LOGE("%s: IBUF write fail", __func__); + return -1; + } else { /* Write OK, but RP decode error? */ + err_code = val; + LOGE("%s: RP decode error [0x%05X]", __func__, err_code); + } + } +#ifdef _DUMP_TO_FILE_ + if (fp_dump) + fwrite(buff, size_byte, 1, fp_dump); +#endif + + return err_code; /* Write Success */ + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device is not created */ +} + +int SRP_Send_EOS(void) +{ + /* Wait until RP decoding over */ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_SEND_EOS); + + return -1; /* device is not created */ +} + +int SRP_Resume_EOS(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_RESUME_EOS); + + return -1; /* device is not created */ +} +#endif + +int SRP_Pause(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_PAUSE); + + return -1; /* device is not created */ +} + +int SRP_Stop(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_STOP); + + return -1; /* device is not created */ +} + +int SRP_Flush(void) +{ + if (srp_dev != -1) { + if (ioctl(srp_dev, SRP_FLUSH) != -1) { +#ifdef _USE_WBUF_ + WriteBuff_Flush(); +#endif + return 0; + } + } + + return -1; /* device is not created */ +} + + +int SRP_SetParams(int id, unsigned long val) +{ + if (srp_dev != -1) + return 0; /* not yet */ + + return -1; /* device is not created */ +} + +int SRP_GetParams(int id, unsigned long *pval) +{ + if (srp_dev != -1) + return ioctl(srp_dev, id, pval); + + return -1; /* device is not created */ +} + +int SRP_Deinit(void) +{ + if (srp_dev != -1) { +#ifdef _DUMP_TO_FILE_ + if (fp_dump) + fclose(fp_dump); +#endif + +#ifdef _USE_WBUF_ + WriteBuff_Deinit(); +#endif + return ioctl(srp_dev, SRP_DEINIT); /* Deinialize */ + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device is not created */ +} + +int SRP_Terminate(void) +{ + int ret; + + if (srp_dev != -1) { + ret = close(srp_dev); + + if (ret == 0) { + srp_dev = -1; /* device closed */ + return 0; + } + } + + LOGE("%s: Device is not ready", __func__); + return -1; /* device is not created or close error*/ +} + +int SRP_IsOpen(void) +{ + if (srp_dev == -1) { + LOGD("%s: Device is not opened", __func__); + return 0; + } + + LOGD("%s: Device is opened", __func__); + return 1; +} diff --git a/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c new file mode 100644 index 0000000..bdc2310 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c @@ -0,0 +1,331 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "srp_api_ctrl.h" +#include "srp_ioctl.h" + +#define LOG_TAG "libsrpapi" +#include + +/* Disable LOGD message */ +#ifdef LOGD +#undef LOGD +#endif +#define LOGD(...) + +static int srp_ctrl = -1; +static int srp_ctrl_cnt = 0; +static short pcm_buf[2048]; /* 4KBytes data, 1K frames (16bit stereo data) */ + +#ifdef _USE_FW_FROM_DISK_ +static char srp_alt_fw_name_pre[6][32] = { + "sdcard/rp_fw/rp_fw_code1", + "sdcard/rp_fw/rp_fw_code20", + "sdcard/rp_fw/rp_fw_code21", + "sdcard/rp_fw/rp_fw_code22", + "sdcard/rp_fw/rp_fw_code30", + "sdcard/rp_fw/rp_fw_code31", +}; +#endif + +static int SRP_Ctrl_Open(void) +{ + if (srp_ctrl_cnt == 0) { + srp_ctrl = open(SRP_CTRL_DEV_NAME, O_RDWR | O_NDELAY); + if (srp_ctrl < 0) { + LOGE("%s: Failed open device file %d", __func__, srp_ctrl); + return -1; + } + srp_ctrl_cnt++; + LOGV("%s: Device is opened[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt); + } + + return srp_ctrl; +} + +static int SRP_Ctrl_Close(void) +{ + int ret = 0; + + if (srp_ctrl_cnt == 1) { + ret = close(srp_ctrl); + if (ret < 0) { + LOGE("%s: Failed closen device file %d", __func__, srp_ctrl); + return -1; + } + srp_ctrl_cnt--; + LOGV("%s: Device is closed[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt); + srp_ctrl = -1; + } + + return ret; +} + +#ifdef _USE_FW_FROM_DISK_ +/* This will check & download alternate firmware */ +static int SRP_Check_AltFirmware(void) +{ + unsigned long *temp_buff; + FILE *fp = NULL; + + char alt_fw_name[128]; + unsigned long alt_fw_set; + unsigned long alt_fw_loaded = 0; + int alt_fw_text_ok,alt_fw_data_ok; + + if ((srp_ctrl = SRP_Ctrl_Open()) >= 0) { + ioctl(srp_ctrl, SRP_CTRL_ALTFW_STATE, &alt_fw_loaded); + + if (!alt_fw_loaded) { /* Not loaded yet? */ + LOGE("Try to download alternate RP firmware"); + temp_buff = (unsigned long *)malloc(256*1024); /* temp buffer */ + + for (alt_fw_set = 0; alt_fw_set < 6; alt_fw_set++) { + sprintf(alt_fw_name, "%s_text.bin", srp_alt_fw_name_pre[alt_fw_set]); + if (fp = fopen(alt_fw_name, "rb")) { + LOGE("RP Alt-Firmware Loading: %s", alt_fw_name); + fread(temp_buff, 64*1024, 1, fp); + close(fp); + alt_fw_text_ok = 1; + } else { + alt_fw_text_ok = 0; + } + + sprintf(alt_fw_name, "%s_data.bin", srp_alt_fw_name_pre[alt_fw_set]); + if (fp = fopen(alt_fw_name, "rb")) { + LOGE("RP Alt-Firmware Loading: %s", alt_fw_name); + fread(&temp_buff[64*1024/4], 96*1024, 1, fp); + close(fp); + alt_fw_data_ok = 1; + } else { + alt_fw_data_ok = 0; + } + + if (alt_fw_text_ok && alt_fw_data_ok) { + temp_buff[160*1024/4] = alt_fw_set; + ioctl(srp_ctrl, SRP_CTRL_ALTFW_LOAD, temp_buff); + } + } + free(temp_buff); + } + SRP_Ctrl_Close(); + } + + return 0; +} +#endif + +int SRP_Ctrl_Set_Effect(int effect) +{ + int ret; + unsigned long effect_mode = (unsigned long)effect; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_SET_EFFECT, effect_mode); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Enable_Effect(int on) +{ + int ret; + unsigned long effect_switch = on ? 1 : 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_EFFECT_ENABLE, effect_switch); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def) +{ + int ret; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_EFFECT_DEF, effect_def); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user) +{ + int ret; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_EFFECT_EQ_USR, eq_user); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Set_Pcm_Dump(int on) +{ + int ret; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, on); + + LOGV("dump_op: %d", on); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Get_Pcm_Dump_State(void) +{ + int ret; + int srp_dump_stat = 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &srp_dump_stat); + + LOGV("srp_dump_stat: %d", srp_dump_stat); + + SRP_Ctrl_Close(); + + return srp_dump_stat; +} + +int SRP_Ctrl_Set_Gain(float value) +{ + int ret; + unsigned long gain = 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + gain = (unsigned long)((1 << 24) * value); + ioctl(srp_ctrl, SRP_CTRL_SET_GAIN, gain); + + SRP_Ctrl_Close(); + + return 0; +} + +int SRP_Ctrl_Get_Running_Stat(void) +{ + int ret; + int srp_running_stat = 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &srp_running_stat); + + LOGV("srp_running_stat: %d", srp_running_stat); + + SRP_Ctrl_Close(); + + return srp_running_stat; +} + +int SRP_Ctrl_Get_Open_Stat(void) +{ + int ret; + int srp_open_stat = 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return -1; + } + + ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &srp_open_stat); + + LOGV("srp_open_stat: %d", srp_open_stat); + + SRP_Ctrl_Close(); + + return srp_open_stat; +} + +short *SRP_Ctrl_Get_Pcm(void) +{ + int ret; + int rp_is_running = 0; + int dump_is_on = 0; + int rp_is_opened = 0; + + ret = SRP_Ctrl_Open(); + if (ret < 0) { + LOGE("%s: SRP_Ctrl_Open error", __func__); + return NULL; + } + + ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &rp_is_running); + if (rp_is_running) { + ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &dump_is_on); + if (dump_is_on == 0) { + ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 1); + dump_is_on = 1; + } + + ioctl(srp_ctrl, SRP_CTRL_GET_PCM_1KFRAME, pcm_buf); + return pcm_buf; + } + + /* SRP is not running */ + if (srp_ctrl > 0) { + if (dump_is_on) { + ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &rp_is_opened); + if (rp_is_opened) + ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 0); + } + SRP_Ctrl_Close(); + } + + return NULL; +} diff --git a/exynos/multimedia/codecs/audio/exynos5/Android.mk b/exynos/multimedia/codecs/audio/exynos5/Android.mk new file mode 100644 index 0000000..4b113e7 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/Android.mk @@ -0,0 +1,9 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_AUDIO_PATH :=$(LOCAL_PATH) + +ifeq ($(BOARD_USE_ALP_AUDIO), true) + include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk +endif diff --git a/exynos/multimedia/codecs/audio/exynos5/srp/alp/Android.mk b/exynos/multimedia/codecs/audio/exynos5/srp/alp/Android.mk new file mode 100644 index 0000000..7393f68 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/srp/alp/Android.mk @@ -0,0 +1,26 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + include/srp_api.h \ + include/srp_ioctl.h \ + include/srp_error.h + +LOCAL_SRC_FILES := \ + src/srp_api.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include + +LOCAL_MODULE := libsrpapi + +LOCAL_MODULE_TAGS := optional + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_api.h b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_api.h new file mode 100644 index 0000000..ad65b90 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_api.h @@ -0,0 +1,52 @@ +#ifndef __SRP_API_H__ +#define __SRP_API_H__ + +#include "srp_ioctl.h" +#include "srp_error.h" + +#define SRP_DEV_NAME "dev/srp" + +#define SRP_INIT_BLOCK_MODE 0 +#define SRP_INIT_NONBLOCK_MODE 1 + +#define SRP_PENDING_STATE_RUNNING 0 +#define SRP_PENDING_STATE_PENDING 1 + +struct srp_buf_info { + void *mmapped_addr; + void *addr; + unsigned int mmapped_size; + unsigned int size; + int num; +}; + +struct srp_dec_info { + unsigned int sample_rate; + unsigned int channels; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int SRP_Create(int block_mode); +int SRP_Init(); +int SRP_Decode(void *buff, int size_byte); +int SRP_Send_EOS(void); +int SRP_SetParams(int id, unsigned long val); +int SRP_GetParams(int id, unsigned long *pval); +int SRP_Deinit(void); +int SRP_Terminate(void); +int SRP_IsOpen(void); + +int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num); +int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num); +int SRP_Get_Dec_Info(struct srp_dec_info *dec_info); +int SRP_Get_PCM(void **addr, unsigned int *size); +int SRP_Flush(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__SRP_API_H__ */ diff --git a/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_error.h b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_error.h new file mode 100644 index 0000000..7f79452 --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_error.h @@ -0,0 +1,22 @@ +#ifndef _SRP_ERROR_H_ +#define _SRP_ERROR_H_ + +typedef enum { + SRP_RETURN_OK = 0, + + SRP_ERROR_OPEN_FAIL = -1000, + SRP_ERROR_ALREADY_OPEN = -1001, + SRP_ERROR_NOT_READY = -1002, + + SRP_ERROR_IBUF_OVERFLOW = -2000, + SRP_ERROR_IBUF_INFO = -2001, + + SRP_ERROR_OBUF_READ = -3000, + SRP_ERROR_OBUF_INFO = -3001, + SRP_ERROR_OBUF_MMAP = -3002, + + SRP_ERROR_INVALID_SETTING = -4000, + SRP_ERROR_GETINFO_FAIL = -4001 +} SRP_ERRORTYPE; + +#endif /* _SRP_ERROR_H_ */ diff --git a/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_ioctl.h b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_ioctl.h new file mode 100644 index 0000000..21d55df --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/srp/alp/include/srp_ioctl.h @@ -0,0 +1,23 @@ +#ifndef __SRP_IOCTL_H__ +#define __SRP_IOCTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRP_INIT (0x10000) +#define SRP_DEINIT (0x10001) +#define SRP_GET_MMAP_SIZE (0x10002) +#define SRP_FLUSH (0x20002) +#define SRP_SEND_EOS (0x20005) +#define SRP_GET_IBUF_INFO (0x20007) +#define SRP_GET_OBUF_INFO (0x20008) +#define SRP_STOP_EOS_STATE (0x30007) +#define SRP_GET_DEC_INFO (0x30008) + +#ifdef __cplusplus +} +#endif + +#endif /* __SRP_IOCTL_H__ */ + diff --git a/exynos/multimedia/codecs/audio/exynos5/srp/alp/src/srp_api.c b/exynos/multimedia/codecs/audio/exynos5/srp/alp/src/srp_api.c new file mode 100644 index 0000000..56125fb --- /dev/null +++ b/exynos/multimedia/codecs/audio/exynos5/srp/alp/src/srp_api.c @@ -0,0 +1,265 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "srp_api.h" + +#define LOG_NDEBUG 1 +#define LOG_TAG "libsrpapi" +#include + +static struct srp_buf_info ibuf_info; +static struct srp_buf_info obuf_info; +static struct srp_buf_info pcm_info; + +static int srp_dev = -1; +static int srp_block_mode = SRP_INIT_BLOCK_MODE; + +int SRP_Create(int block_mode) +{ + if (srp_dev == -1) { + srp_block_mode = block_mode; + srp_dev = open(SRP_DEV_NAME, O_RDWR | + ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); + if (srp_dev > 0) + return srp_dev; + else + return SRP_ERROR_OPEN_FAIL; + } + + LOGE("%s: Device is already opened", __func__); + return SRP_ERROR_ALREADY_OPEN; +} + +int SRP_Init() +{ + int ret = SRP_RETURN_OK; + unsigned int mmapped_size = 0; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_INIT); + if (ret < 0) + return ret; + + /* mmap for OBUF */ + ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size); + if (ret < 0) { + LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__); + return SRP_ERROR_OBUF_MMAP; + } + obuf_info.mmapped_addr = mmap(0, mmapped_size, + PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0); + if (!obuf_info.mmapped_addr) { + LOGE("%s: mmap is failed", __func__); + return SRP_ERROR_OBUF_MMAP; + } + obuf_info.mmapped_size = mmapped_size; + + ret = SRP_RETURN_OK; + } else { + LOGE("%s: Device is not ready", __func__); + ret = SRP_ERROR_NOT_READY; /* device is not created */ + } + + return ret; +} + +int SRP_Decode(void *buff, int size_byte) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + if (size_byte > 0) { + LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte); + + ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ + if (ret < 0) { + if (ret != SRP_ERROR_IBUF_OVERFLOW) + LOGE("SRP_Decode returned error code: %d", ret); + } + return ret; /* Write Success */ + } else { + return ret; + } + } + + LOGE("%s: Device is not ready", __func__); + return SRP_ERROR_NOT_READY; +} + +int SRP_Send_EOS(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_SEND_EOS); + + return SRP_ERROR_NOT_READY; +} + +int SRP_SetParams(int id, unsigned long val) +{ + if (srp_dev != -1) + return 0; /* not yet */ + + return SRP_ERROR_NOT_READY; +} + +int SRP_GetParams(int id, unsigned long *pval) +{ + if (srp_dev != -1) + return ioctl(srp_dev, id, pval); + + return SRP_ERROR_NOT_READY; +} + +int SRP_Flush(void) +{ + if (srp_dev != -1) + return ioctl(srp_dev, SRP_FLUSH); + + return SRP_ERROR_NOT_READY; +} + +int SRP_Get_PCM(void **addr, unsigned int *size) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + ret = read(srp_dev, &pcm_info, 0); + if (ret == -1) { + *size = 0; + LOGE("%s: PCM read fail", __func__); + return SRP_ERROR_OBUF_READ; + } + + *addr = pcm_info.addr; + *size = pcm_info.size; + } else { + return SRP_ERROR_NOT_READY; + } + + return ret; /* Read Success */ +} + +int SRP_Get_Dec_Info(struct srp_dec_info *dec_info) +{ + int ret; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info); + if (ret < 0) { + LOGE("%s: Failed to get dec info", __func__); + return SRP_ERROR_GETINFO_FAIL; + } + + LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate); + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info); + if (ret == -1) { + LOGE("%s: Failed to get Ibuf info", __func__); + return SRP_ERROR_IBUF_INFO; + } + + *addr = ibuf_info.addr; + *size = ibuf_info.size; + *num = ibuf_info.num; + + if (*num == 0) { + LOGE("%s: IBUF num is 0", __func__); + return SRP_ERROR_INVALID_SETTING; + } + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num) +{ + int ret = SRP_RETURN_OK; + + if (srp_dev != -1) { + if (obuf_info.addr == NULL) { + ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info); + if (ret < 0) { + LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__); + return SRP_ERROR_OBUF_INFO; + } + } + + *addr = obuf_info.addr; + *size = obuf_info.size; + *num = obuf_info.num; + + if (*num == 0) { + LOGE("%s: OBUF num is 0", __func__); + return SRP_ERROR_INVALID_SETTING; + } + + ret = SRP_RETURN_OK; + } else { + ret = SRP_ERROR_NOT_READY; + } + + return ret; +} + +int SRP_Deinit(void) +{ + if (srp_dev != -1) { + munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size); + return ioctl(srp_dev, SRP_DEINIT); + } + + return SRP_ERROR_NOT_READY; +} + +int SRP_Terminate(void) +{ + int ret; + + if (srp_dev != -1) { + ret = close(srp_dev); + + if (ret == 0) { + srp_dev = -1; /* device closed */ + return SRP_RETURN_OK; + } + } + + return SRP_ERROR_NOT_READY; +} + +int SRP_IsOpen(void) +{ + if (srp_dev == -1) { + LOGV("%s: Device is not opened", __func__); + return 0; + } + + LOGV("%s: Device is opened", __func__); + return 1; +} diff --git a/exynos/multimedia/codecs/video/Android.mk b/exynos/multimedia/codecs/video/Android.mk new file mode 100644 index 0000000..3bc3577 --- /dev/null +++ b/exynos/multimedia/codecs/video/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos4/Android.mk +endif + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos5/Android.mk +endif diff --git a/exynos/multimedia/codecs/video/exynos4/Android.mk b/exynos/multimedia/codecs/video/exynos4/Android.mk new file mode 100644 index 0000000..1a8c419 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_VIDEO_PATH :=$(LOCAL_PATH) + +ifeq ($(BOARD_USE_V4L2), true) +include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk +else +include $(LOCAL_VIDEO_PATH)/mfc/Android.mk +endif diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/Android.mk b/exynos/multimedia/codecs/video/exynos4/mfc/Android.mk new file mode 100644 index 0000000..b23f603 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/Android.mk @@ -0,0 +1,38 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + include/mfc_errno.h \ + include/mfc_interface.h \ + include/SsbSipMfcApi.h + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + dec/src/SsbSipMfcDecAPI.c \ + enc/src/SsbSipMfcEncAPI.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include/ + +LOCAL_MODULE := libsecmfcapi + +LOCAL_PRELINK_MODULE := false + +ifeq ($(BOARD_USES_MFC_FPS),true) +LOCAL_CFLAGS := -DCONFIG_MFC_FPS +#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_LOG +endif + +ifeq ($(BOARD_USE_S3D_SUPPORT), true) +LOCAL_CFLAGS += -DS3D_SUPPORT +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := liblog + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c b/exynos/multimedia/codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c new file mode 100644 index 0000000..92a8ca6 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c @@ -0,0 +1,1100 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +#include +/*#define LOG_NDEBUG 0*/ +#undef LOG_TAG +#define LOG_TAG "MFC_DEC_APP" + +#ifdef CONFIG_MFC_FPS +#include +#endif + +#define _MFCLIB_MAGIC_NUMBER 0x92241000 + +#define USR_DATA_START_CODE (0x000001B2) +#define VOP_START_CODE (0x000001B6) +#define MP4_START_CODE (0x000001) + +#ifdef CONFIG_MFC_FPS +unsigned int framecount, over30ms; +struct timeval mDec1, mDec2, mAvg; +#endif + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; + +static void getAByte(char *buff, int *code) +{ + int byte; + + *code = (*code << 8); + byte = (int)*buff; + byte &= 0xFF; + *code |= byte; +} + +static int isPBPacked(_MFCLIB *pCtx, int Frameleng) +{ + char *strmBuffer = NULL; + int startCode = 0xFFFFFFFF; + int leng_idx = 1; + + strmBuffer = (char*)pCtx->virStrmBuf; + + while (1) { + while (startCode != USR_DATA_START_CODE) { + if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { + LOGI("isPBPacked] VOP START Found !!.....return"); + LOGW("isPBPacked] Non Packed PB"); + return 0; + } + getAByte(strmBuffer, &startCode); + LOGV(">> StartCode = 0x%08x <<\n", startCode); + strmBuffer++; + leng_idx++; + } + LOGI("isPBPacked] User Data Found !!"); + + do { + if (*strmBuffer == 'p') { + /*LOGI(">> peter strmBuffer = 0x%08x <<\n", *strmBuffer);*/ + LOGW("isPBPacked] Packed PB\n"); + return 1; + } + getAByte(strmBuffer, &startCode); + strmBuffer++; leng_idx++; + } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); + + if (leng_idx > Frameleng) + break; + } + + LOGW("isPBPacked] Non Packed PB"); + + return 0; +} + +void SsbSipMfcDecSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcDecOpen(void) +{ + int hMFCOpen; + unsigned int mapped_addr; + _MFCLIB *pCTX = NULL; + int mapped_size; + struct mfc_common_args CommonArg; + + LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); +#ifdef CONFIG_MFC_FPS + framecount = 0; + over30ms = 0; + mAvg.tv_sec = 0; + mAvg.tv_usec = 0; +#endif + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcDecOpen] malloc failed.\n"); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("SsbSipMfcDecOpen] MFC device node not exists"); + free(pCTX); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcDecOpen] MFC Open failure"); + free(pCTX); + return NULL; + } + + mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); + if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcDecOpen] IOCTL_MFC_GET_MMAP_SIZE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcDecOpen] FIMV5.x driver address mapping failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->mapped_size = mapped_size; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *)pCTX; +} + +void *SsbSipMfcDecOpenExt(void *value) +{ + int hMFCOpen; + unsigned int mapped_addr; + _MFCLIB *pCTX = NULL; + int mapped_size; + int err; + struct mfc_common_args CommonArg; + + LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcDecOpenExt] malloc failed.\n"); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("SsbSipMfcDecOpen] MFC device node not exists"); + free(pCTX); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcDecOpenExt] MFC Open failure"); + free(pCTX); + return NULL; + } + + CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value; + + err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg); + if ((err < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_SET_BUF_CACHE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); + if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcDecOpenExt] FIMV5.x driver address mapping failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->mapped_size = mapped_size; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit (void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) +{ + int r; + int packedPB = 0; + struct mfc_common_args DecArg; + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecInit] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + if ((codec_type != MPEG4_DEC) && + (codec_type != H264_DEC) && + (codec_type != H263_DEC) && + (codec_type != MPEG1_DEC) && + (codec_type != MPEG2_DEC) && + (codec_type != FIMV1_DEC) && + (codec_type != FIMV2_DEC) && + (codec_type != FIMV3_DEC) && + (codec_type != FIMV4_DEC) && + (codec_type != XVID_DEC) && + (codec_type != VC1RCV_DEC) && + (codec_type != VC1_DEC)) { + LOGE("SsbSipMfcDecInit] Undefined codec type"); + return MFC_RET_INVALID_PARAM; + } + pCTX->codecType = codec_type; + + if ((pCTX->codecType == MPEG4_DEC) || + (pCTX->codecType == XVID_DEC) || + (pCTX->codecType == FIMV1_DEC) || + (pCTX->codecType == FIMV2_DEC) || + (pCTX->codecType == FIMV3_DEC) || + (pCTX->codecType == FIMV4_DEC)) + packedPB = isPBPacked(pCTX, Frameleng); + + /* init args */ + DecArg.args.dec_init.in_codec_type = pCTX->codecType; + DecArg.args.dec_init.in_strm_size = Frameleng; + DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf; + + DecArg.args.dec_init.in_numextradpb = pCTX->dec_numextradpb; + DecArg.args.dec_init.in_slice= pCTX->dec_slice; + DecArg.args.dec_init.in_crc = pCTX->dec_crc; + DecArg.args.dec_init.in_pixelcache = pCTX->dec_pixelcache; + + DecArg.args.dec_init.in_packed_PB = packedPB; + + /* mem alloc args */ + DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr; + + /* get pyhs addr args */ + /* no needs */ + + /* sequence start args */ + /* no needs */ + + r = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg); + if (DecArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcDecInit] IOCTL_MFC_DEC_INIT failed"); + return MFC_RET_DEC_INIT_FAIL; + } + + pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_frm_width; + pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_frm_height; + pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width; + pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height; + + pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset; + pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset; + pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset; + pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset; + + /* + pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma; + pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma; + + pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma; + pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma; + pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma; + pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma; + */ + + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) +{ + int ret; + int Yoffset; + int Coffset; + _MFCLIB *pCTX; + struct mfc_common_args DecArg; + +#ifdef CONFIG_MFC_FPS + long int diffTime, avgTime; +#endif + if (openHandle == NULL) { + LOGE("SsbSipMfcDecExe] openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("SsbSipMfcDecExe] lengthBufFill is invalid. (lengthBufFill=%d)", lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + DecArg.args.dec_exe.in_codec_type = pCTX->codecType; + DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf; + DecArg.args.dec_exe.in_strm_size = lengthBufFill; + DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma; + DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma; + DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma; + DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma; + DecArg.args.dec_exe.in_frametag = pCTX->inframetag; + DecArg.args.dec_exe.in_immediately_disp = pCTX->immediatelydisp; + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec1, NULL); + +#ifdef CONFIG_MFC_PERF_LOG + if (framecount != 0) { + if (mDec2.tv_sec == mDec1.tv_sec) + LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (mDec1.tv_usec - mDec2.tv_usec)); + else + LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (1000000 + (mDec1.tv_usec - mDec2.tv_usec))); + } +#endif +#endif + + ret = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg); + + if (DecArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcDecExe] IOCTL_MFC_DEC_EXE failed(ret : %d)", DecArg.ret_code); + return MFC_RET_DEC_EXE_ERR; + } + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec2, NULL); + framecount++; + + if (mDec1.tv_sec == mDec2.tv_sec) { + if (mDec2.tv_usec - mDec1.tv_usec > 30000) + over30ms++; +#ifdef CONFIG_MFC_PERF_LOG + LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", ((mDec2.tv_usec - mDec1.tv_usec))); +#endif + } else { + if (1000000 + mDec2.tv_usec - mDec1.tv_usec > 30000) + over30ms++; +#ifdef CONFIG_MFC_PERF_LOG + LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", (1000000 + (mDec2.tv_usec - mDec1.tv_usec))); +#endif + } + + diffTime = ((mDec2.tv_sec * 1000000) + mDec2.tv_usec) - ((mDec1.tv_sec * 1000000) + mDec1.tv_usec); + avgTime = (mAvg.tv_sec * 1000000) + mAvg.tv_usec; + avgTime = ((framecount - 1) * avgTime + diffTime) / framecount; + + mAvg.tv_sec = avgTime / 1000000; + mAvg.tv_usec = avgTime % 1000000; +#endif + + /* FIXME: dynamic resolution change */ + if (DecArg.args.dec_exe.out_display_status == 4) { + LOGI("SsbSipMfcDecExe] Resolution is chagned"); + /* + pCTX->virFrmBuf.chroma = DecArg.args.dec_exe.out_u_addr.chroma; + pCTX->virFrmBuf.luma = DecArg.args.dec_exe.out_u_addr.luma; + pCTX->phyFrmBuf.chroma = DecArg.args.dec_exe.out_p_addr.chroma; + pCTX->phyFrmBuf.luma = DecArg.args.dec_exe.out_p_addr.luma; + pCTX->sizeFrmBuf.chroma = DecArg.args.dec_exe.out_frame_buf_size.chroma; + pCTX->sizeFrmBuf.luma = DecArg.args.dec_exe.out_frame_buf_size.luma; + */ + pCTX->decOutInfo.img_width = DecArg.args.dec_exe.out_img_width; + pCTX->decOutInfo.img_height = DecArg.args.dec_exe.out_img_height; + pCTX->decOutInfo.buf_width = DecArg.args.dec_exe.out_buf_width; + pCTX->decOutInfo.buf_height = DecArg.args.dec_exe.out_buf_height; + } + + Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma; + Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma; + + pCTX->decOutInfo.YPhyAddr = (void*)(DecArg.args.dec_exe.out_display_Y_addr); + pCTX->decOutInfo.CPhyAddr = (void*)(DecArg.args.dec_exe.out_display_C_addr); + + pCTX->decOutInfo.YVirAddr = (void*)(pCTX->virFrmBuf.luma + Yoffset); + pCTX->decOutInfo.CVirAddr = (void*)(pCTX->virFrmBuf.chroma + Coffset); + + /* for new driver */ + pCTX->decOutInfo.YVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_y_offset); + pCTX->decOutInfo.CVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_c_offset); + + pCTX->displayStatus = DecArg.args.dec_exe.out_display_status; + + pCTX->decOutInfo.disp_pic_frame_type = DecArg.args.dec_exe.out_disp_pic_frame_type; + + /* clear immediately display flag */ + pCTX->immediatelydisp = 0; + pCTX->outframetagtop = DecArg.args.dec_exe.out_frametag_top; + pCTX->outframetagbottom = DecArg.args.dec_exe.out_frametag_bottom; + pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_pic_time_top; + pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_pic_time_bottom; + pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consumed_byte; + + pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset; + pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset; + pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset; + pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) +{ + int ret; + _MFCLIB *pCTX; + struct mfc_common_args free_arg; + +#ifdef CONFIG_MFC_FPS + LOGI(">>> Statistics in MFC API:"); + LOGI(">>> Total number of IOCTL_MFC_DEC_EXE = %d", framecount); + LOGI(">>> Number of IOCTL_MFC_DEC_EXE taking more than 30ms = %d", over30ms); + LOGI(">>> Avg IOCTL_MFC_DEC_EXE time = %dsec %.2fmsec", (int)mAvg.tv_sec, (float)(mAvg.tv_usec / 1000.0)); +#endif + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecClose] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + /* FIXME: free buffer? */ +#if 0 + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + free_arg.args.mem_free.key = pCTX->virFrmBuf.luma; + ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + free_arg.args.mem_free.key = pCTX->virFrmBuf.chroma; + ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } +#endif + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + free_arg.args.mem_free.key = pCTX->virStrmBuf; + ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + pCTX->inter_buff_status = MFC_USE_NONE; + + munmap((void *)pCTX->mapped_addr, pCTX->mapped_size); + close(pCTX->hMFC); + free(pCTX); + + return MFC_RET_OK; +} + + +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args user_addr_arg, phys_addr_arg; + + if (inputBufferSize < 0) { + LOGE("SsbSipMfcDecGetInBuf] inputBufferSize = %d is invalid", inputBufferSize); + return NULL; + } + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetInBuf] openHandle is NULL\n"); + return NULL; + } + + pCTX = (_MFCLIB *) openHandle; + + /*user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; */ + user_addr_arg.args.mem_alloc.type = DECODER; + user_addr_arg.args.mem_alloc.buff_size = inputBufferSize; + user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_IN_BUF failed"); + return NULL; + } + + phys_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &phys_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_PHYS_ADDR failed"); + return NULL; + } + + /* + pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.offset; + */ + pCTX->virStrmBuf = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset; + pCTX->phyStrmBuf = phys_addr_arg.args.real_addr.addr; + + pCTX->sizeStrmBuf = inputBufferSize; + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + *phyInBuf = (void *)pCTX->phyStrmBuf; + + return (void *)pCTX->virStrmBuf; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecSetInBuf] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + pCTX->phyStrmBuf = (int)phyInBuf; + pCTX->virStrmBuf = (int)virInBuf; + pCTX->sizeStrmBuf = size; + return MFC_RET_OK; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetOutBuf] openHandle is NULL"); + return MFC_GETOUTBUF_DISPLAY_END; + } + + pCTX = (_MFCLIB *) openHandle; + + output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; + output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; + + output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; + output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; + + output_info->img_width = pCTX->decOutInfo.img_width; + output_info->img_height= pCTX->decOutInfo.img_height; + + output_info->buf_width = pCTX->decOutInfo.buf_width; + output_info->buf_height= pCTX->decOutInfo.buf_height; + + output_info->timestamp_top = pCTX->decOutInfo.timestamp_top; + output_info->timestamp_bottom = pCTX->decOutInfo.timestamp_bottom; + output_info->consumedByte = pCTX->decOutInfo.consumedByte; + + output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + + output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; + + if (pCTX->displayStatus == 3) + return MFC_GETOUTBUF_DISPLAY_END; + else if (pCTX->displayStatus == 1) + return MFC_GETOUTBUF_DISPLAY_DECODING; + else if (pCTX->displayStatus == 2) + return MFC_GETOUTBUF_DISPLAY_ONLY; + else if (pCTX->displayStatus == 0) + return MFC_GETOUTBUF_DECODING_ONLY; + else if (pCTX->displayStatus == 4) + return MFC_GETOUTBUF_CHANGE_RESOL; + else + return MFC_GETOUTBUF_DISPLAY_END; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args DecArg; + struct mfc_dec_fimv1_info *fimv1_res; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecSetConfig] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("SsbSipMfcDecSetConfig] value is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); +#ifdef S3D_SUPPORT + DecArg.args.config.type = conf_type; +#else + DecArg.args.set_config.in_config_param = conf_type; +#endif + switch (conf_type) { + case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: + pCTX->dec_numextradpb = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_SLICE_ENABLE: + pCTX->dec_slice = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_CRC_ENABLE: + pCTX->dec_crc = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_PIXEL_CACHE: + pCTX->dec_pixelcache = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_FRAME_TAG: /* be set before calling SsbSipMfcDecExe */ + pCTX->inframetag = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY: /* be set before calling SsbSipMfcDecExe */ + pCTX->immediatelydisp = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: + fimv1_res = (struct mfc_dec_fimv1_info *)value; + LOGI("fimv1->width = %d\n", fimv1_res->width); + LOGI("fimv1->height = %d\n", fimv1_res->height); +#ifdef S3D_SUPPORT + DecArg.args.config.args.basic.values[0] = (int)(fimv1_res->width); + DecArg.args.config.args.basic.values[1] = (int)(fimv1_res->height); +#else + DecArg.args.set_config.in_config_value[0] = (int)(fimv1_res->width); + DecArg.args.set_config.in_config_value[1] = (int)(fimv1_res->height); +#endif + break; + case MFC_DEC_SETCONF_IS_LAST_FRAME: + case MFC_DEC_SETCONF_DPB_FLUSH: +#ifdef S3D_SUPPORT + case MFC_DEC_SETCONF_SEI_PARSE: + default: + DecArg.args.config.args.basic.values[0] = *((int *) value); + DecArg.args.config.args.basic.values[1] = 0; +#else + default: + DecArg.args.set_config.in_config_value[0] = *((unsigned int *) value); + DecArg.args.set_config.in_config_value[1] = 0; +#endif + break; + } + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg); + if (DecArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcDecSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); + return MFC_RET_DEC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args DecArg; + + /* + s3c_mfc_common_args phys_addr_arg; + SSBSIP_MFC_BUFFER_ADDR *buf_addr; + */ + + SSBSIP_MFC_IMG_RESOLUTION *img_resolution; + SSBSIP_MFC_CRC_DATA *crc_data; + SSBSIP_MFC_CROP_INFORMATION *crop_information; +#ifdef S3D_SUPPORT + SSBSIP_MFC_FRAME_PACKING *frame_packing; +#endif + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetConfig] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("SsbSipMfcDecGetConfig] value is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + switch (conf_type) { +#if 0 + case MFC_DEC_GETCONF_PHYS_ADDR: + buf_addr = (SSBSIP_MFC_BUFFER_ADDR *)value; + phys_addr_arg.args.get_phys_addr.u_addr = buf_addr->u_addr; + r = ioctl(pCTX->hMFC, IOCTL_MFC_GET_PHYS_ADDR, &phys_addr_arg); + if (r < 0) { + LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_PHYS_ADDR failed"); + return MFC_API_FAIL; + } + buf_addr->p_addr = phys_addr_arg.args.get_phys_addr.p_addr; + break; +#endif + case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: + img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; + img_resolution->width = pCTX->decOutInfo.img_width; + img_resolution->height = pCTX->decOutInfo.img_height; + img_resolution->buf_width = pCTX->decOutInfo.buf_width; + img_resolution->buf_height = pCTX->decOutInfo.buf_height; + break; + case MFC_DEC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->outframetagtop; + break; + case MFC_DEC_GETCONF_CROP_INFO: + crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; + crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + break; + case MFC_DEC_GETCONF_CRC_DATA: +#ifdef S3D_SUPPORT + case MFC_DEC_GETCONF_FRAME_PACKING: + memset(&DecArg, 0x00, sizeof(DecArg)); + DecArg.args.config.type = conf_type; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); + if (DecArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); + return MFC_RET_DEC_GET_CONF_FAIL; + } + + if (conf_type == MFC_DEC_GETCONF_CRC_DATA) { + crc_data = (SSBSIP_MFC_CRC_DATA *)value; + + crc_data->luma0 = DecArg.args.config.args.basic.values[0]; + crc_data->chroma0 = DecArg.args.config.args.basic.values[1]; + } else { + frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value; + memcpy(frame_packing, &DecArg.args.config.args.frame_packing, + sizeof(SSBSIP_MFC_FRAME_PACKING)); + } +#else + crc_data = (SSBSIP_MFC_CRC_DATA *)value; + + memset(&DecArg, 0x00, sizeof(DecArg)); + DecArg.args.get_config.in_config_param = conf_type; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); + if (DecArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); + return MFC_RET_DEC_GET_CONF_FAIL; + } + crc_data->luma0 = DecArg.args.get_config.out_config_value[0]; + crc_data->chroma0 = DecArg.args.get_config.out_config_value[1]; +#endif + break; + default: + LOGE("SsbSipMfcDecGetConfig] No such conf_type is supported"); + return MFC_RET_DEC_GET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +/* CRESPO */ +#if 1 +int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) +{ + int pixel_x_m1, pixel_y_m1; + int roundup_x, roundup_y; + int linear_addr0, linear_addr1, bank_addr ; + int x_addr; + int trans_addr; + + pixel_x_m1 = x_size -1; + pixel_y_m1 = y_size -1; + + roundup_x = ((pixel_x_m1 >> 7) + 1); + roundup_y = ((pixel_x_m1 >> 6) + 1); + + x_addr = x_pos >> 2; + + if ((y_size <= y_pos+32) && ( y_pos < y_size) && + (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) { + linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } else { + linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } + + linear_addr0 = linear_addr0 << 2; + trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; + + return trans_addr; +} + +void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) +{ + int trans_addr; + unsigned int i, j, k, index; + unsigned char data8[4]; + unsigned int max_index = x_size * y_size; + + for (i = 0; i < y_size; i = i + 16) { + for (j = 0; j < x_size; j = j + 16) { + trans_addr = tile_4x2_read(x_size, y_size, j, i); + for (k = 0; k < 16; k++) { + /* limit check - prohibit segmentation fault */ + index = (i * x_size) + (x_size * k) + j; + /* remove equal condition to solve thumbnail bug */ + if (index + 16 > max_index) { + continue; + } + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; + + p_linear_addr[index] = data8[0]; + p_linear_addr[index + 1] = data8[1]; + p_linear_addr[index + 2] = data8[2]; + p_linear_addr[index + 3] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; + + p_linear_addr[index + 4] = data8[0]; + p_linear_addr[index + 5] = data8[1]; + p_linear_addr[index + 6] = data8[2]; + p_linear_addr[index + 7] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; + + p_linear_addr[index + 8] = data8[0]; + p_linear_addr[index + 9] = data8[1]; + p_linear_addr[index + 10] = data8[2]; + p_linear_addr[index + 11] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; + + p_linear_addr[index + 12] = data8[0]; + p_linear_addr[index + 13] = data8[1]; + p_linear_addr[index + 14] = data8[2]; + p_linear_addr[index + 15] = data8[3]; + } + } + } +} + +void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) +{ + int trans_addr; + unsigned int i, j, k, index; + unsigned char data8[4]; + unsigned int half_y_size = y_size / 2; + unsigned int max_index = x_size * half_y_size; + unsigned char *pUVAddr[2]; + + pUVAddr[0] = p_linear_addr; + pUVAddr[1] = p_linear_addr + ((x_size * half_y_size) / 2); + + for (i = 0; i < half_y_size; i = i + 16) { + for (j = 0; j < x_size; j = j + 16) { + trans_addr = tile_4x2_read(x_size, half_y_size, j, i); + for (k = 0; k < 16; k++) { + /* limit check - prohibit segmentation fault */ + index = (i * x_size) + (x_size * k) + j; + /* remove equal condition to solve thumbnail bug */ + if (index + 16 > max_index) { + continue; + } + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; + + pUVAddr[index%2][index/2] = data8[0]; + pUVAddr[(index+1)%2][(index+1)/2] = data8[1]; + pUVAddr[(index+2)%2][(index+2)/2] = data8[2]; + pUVAddr[(index+3)%2][(index+3)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; + + pUVAddr[(index+4)%2][(index+4)/2] = data8[0]; + pUVAddr[(index+5)%2][(index+5)/2] = data8[1]; + pUVAddr[(index+6)%2][(index+6)/2] = data8[2]; + pUVAddr[(index+7)%2][(index+7)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; + + pUVAddr[(index+8)%2][(index+8)/2] = data8[0]; + pUVAddr[(index+9)%2][(index+9)/2] = data8[1]; + pUVAddr[(index+10)%2][(index+10)/2] = data8[2]; + pUVAddr[(index+11)%2][(index+11)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; + + pUVAddr[(index+12)%2][(index+12)/2] = data8[0]; + pUVAddr[(index+13)%2][(index+13)/2] = data8[1]; + pUVAddr[(index+14)%2][(index+14)/2] = data8[2]; + pUVAddr[(index+15)%2][(index+15)/2] = data8[3]; + } + } + } +} +#else +int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) +{ + int pixel_x_m1, pixel_y_m1; + int roundup_x, roundup_y; + int linear_addr0, linear_addr1, bank_addr; + int x_addr; + int trans_addr; + + pixel_x_m1 = x_size -1; + pixel_y_m1 = y_size -1; + + roundup_x = ((pixel_x_m1 >> 7) + 1); + roundup_y = ((pixel_x_m1 >> 6) + 1); + + x_addr = x_pos >> 2; + + if ((y_size <= y_pos+32) && + ( y_pos < y_size) && + (((pixel_y_m1 >> 5) & 0x1) == 0) && + (((y_pos >> 5) & 0x1) == 0)) { + linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } else { + linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } + + linear_addr0 = linear_addr0 << 2; + trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; + + return trans_addr; +} + + +void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) +{ + int trans_addr; + unsigned int i, j, k, nn, mm; + unsigned int ix,iy, nx, ny; + + nx = x_size % 16; + ny = y_size % 16; + + if (nx != 0) + ix = 16; + else + ix = 1; + + if (ny != 0) + iy = 16; + else + iy = 1; + + for (i = 0; i < y_size - iy; i = i + 16) { + for (j = 0; j < x_size -ix; j = j + 16) { + trans_addr = tile_4x2_read(x_size, y_size, j, i); + + k = 0; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 1; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 2; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 3; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 4; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 5; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 6; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 7; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 8; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 9; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 10; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 11; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 12; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 13; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 14; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + + k = 15; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; + memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); + } + } +} +#endif diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c b/exynos/multimedia/codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c new file mode 100644 index 0000000..797baad --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c @@ -0,0 +1,862 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +#include +/* #define LOG_NDEBUG 0 */ +#undef LOG_TAG +#define LOG_TAG "MFC_ENC_APP" + +#define _MFCLIB_MAGIC_NUMBER 0x92241001 + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; + +void SsbSipMfcEncSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcEncOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX = NULL; + unsigned int mapped_addr; + int mapped_size; + struct mfc_common_args CommonArg; + + LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); + +#if 0 + if ((codecType != MPEG4_ENC) && + (codecType != H264_ENC) && + (codecType != H263_ENC)) { + LOGE("SsbSipMfcEncOpen] Undefined codec type"); + return NULL; + } +#endif + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("SsbSipMfcEncOpen] MFC device node not exists"); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcEncOpen] MFC Open failure"); + return NULL; + } + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcEncOpen] malloc failed."); + close(hMFCOpen); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); + if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcEncOpen] IOCTL_MFC_GET_MMAP_SIZE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcEncOpen] FIMV5.x driver address mapping failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->mapped_size = mapped_size; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *) pCTX; +} + + +void *SsbSipMfcEncOpenExt(void *value) +{ + int hMFCOpen; + _MFCLIB *pCTX = NULL; + unsigned int mapped_addr; + int mapped_size; + int err; + struct mfc_common_args CommonArg; + + LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); + +#if 0 + if ((codecType != MPEG4_ENC) && + (codecType != H264_ENC) && + (codecType != H263_ENC)) { + LOGE("SsbSipMfcEncOpen] Undefined codec type"); + return NULL; + } +#endif + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("SsbSipMfcEncOpenExt] MFC device node not exists"); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcEncOpenExt] MFC Open failure"); + return NULL; + } + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcEncOpenExt] malloc failed."); + close(hMFCOpen); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value; + + err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg); + if ((err < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_SET_BUF_CACHE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); + if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { + LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcEncOpenExt] FIMV5.x driver address mapping failed"); + free(pCTX); + close(hMFCOpen); + return NULL; + } + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->mapped_size = mapped_size; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *) pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) +{ + int ret_code; + + _MFCLIB *pCTX; + struct mfc_common_args EncArg; + SSBSIP_MFC_ENC_H264_PARAM *h264_arg; + SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; + SSBSIP_MFC_ENC_H263_PARAM *h263_arg; + + pCTX = (_MFCLIB *) openHandle; + memset(&EncArg, 0, sizeof(struct mfc_common_args)); + + pCTX->encode_cnt = 0; + + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; + if (mpeg4_arg->codecType == MPEG4_ENC) { + pCTX->codecType= MPEG4_ENC; + } else { + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; + if (h263_arg->codecType == H263_ENC) { + pCTX->codecType = H263_ENC; + } else { + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; + if (h264_arg->codecType == H264_ENC) { + pCTX->codecType = H264_ENC; + } else { + LOGE("SsbSipMfcEncInit] Undefined codec type"); + return MFC_RET_INVALID_PARAM; + } + } + } + + LOGI("SsbSipMfcEncInit] Encode Init start"); + + switch (pCTX->codecType) { + case MPEG4_ENC: + LOGI("SsbSipMfcEncInit] MPEG4 Encode"); + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; + + pCTX->width = mpeg4_arg->SourceWidth; + pCTX->height = mpeg4_arg->SourceHeight; + break; + + case H263_ENC: + LOGI("SsbSipMfcEncInit] H263 Encode"); + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; + + pCTX->width = h263_arg->SourceWidth; + pCTX->height = h263_arg->SourceHeight; + break; + + case H264_ENC: + LOGI("SsbSipMfcEncInit] H264 Encode"); + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; + + pCTX->width = h264_arg->SourceWidth; + pCTX->height = h264_arg->SourceHeight; + break; + + default: + break; + } + + switch (pCTX->codecType) { + case MPEG4_ENC: + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; + + EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType; + + EncArg.args.enc_init.cmn.in_width = mpeg4_arg->SourceWidth; + EncArg.args.enc_init.cmn.in_height = mpeg4_arg->SourceHeight; + EncArg.args.enc_init.cmn.in_gop_num = mpeg4_arg->IDRPeriod; + + EncArg.args.enc_init.cmn.in_ms_mode = mpeg4_arg->SliceMode; + EncArg.args.enc_init.cmn.in_ms_arg = mpeg4_arg->SliceArgument; + + EncArg.args.enc_init.cmn.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh; + + /* rate control*/ + EncArg.args.enc_init.cmn.in_rc_fr_en = mpeg4_arg->EnableFRMRateControl; + if ((mpeg4_arg->QSCodeMin > 31) || (mpeg4_arg->QSCodeMax > 31)) { + LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_rc_qbound_min = mpeg4_arg->QSCodeMin; + EncArg.args.enc_init.cmn.in_rc_qbound_max = mpeg4_arg->QSCodeMax; + EncArg.args.enc_init.cmn.in_rc_rpara = mpeg4_arg->CBRPeriodRf; + + /* pad control */ + EncArg.args.enc_init.cmn.in_pad_ctrl_on = mpeg4_arg->PadControlOn; + if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit] No such Pad value is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_y_pad_val = mpeg4_arg->LumaPadVal; + EncArg.args.enc_init.cmn.in_cb_pad_val = mpeg4_arg->CbPadVal; + EncArg.args.enc_init.cmn.in_cr_pad_val = mpeg4_arg->CrPadVal; + + /* Input stream Mode NV12_Linear or NV12_Tile*/ + EncArg.args.enc_init.cmn.in_frame_map = mpeg4_arg->FrameMap; + + EncArg.args.enc_init.cmn.in_rc_bitrate = mpeg4_arg->Bitrate; + if ((mpeg4_arg->FrameQp > 31) || (mpeg4_arg->FrameQp_P > 31)) { + LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_vop_quant = mpeg4_arg->FrameQp; + EncArg.args.enc_init.cmn.in_vop_quant_p = mpeg4_arg->FrameQp_P; + + /* MPEG4 only */ + EncArg.args.enc_init.codec.mpeg4.in_profile = mpeg4_arg->ProfileIDC; + EncArg.args.enc_init.codec.mpeg4.in_level = mpeg4_arg->LevelIDC; + + if (mpeg4_arg->FrameQp_B > 31) { + LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.mpeg4.in_vop_quant_b = mpeg4_arg->FrameQp_B; + + if (mpeg4_arg->NumberBFrames > 2) { + LOGE("SsbSipMfcEncInit] No such BframeNum is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.mpeg4.in_bframenum = mpeg4_arg->NumberBFrames; + + EncArg.args.enc_init.codec.mpeg4.in_quart_pixel = mpeg4_arg->DisableQpelME; + + EncArg.args.enc_init.codec.mpeg4.in_TimeIncreamentRes = mpeg4_arg->TimeIncreamentRes; + EncArg.args.enc_init.codec.mpeg4.in_VopTimeIncreament = mpeg4_arg->VopTimeIncreament; + + break; + + case H263_ENC: + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; + + EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType; + + EncArg.args.enc_init.cmn.in_width = h263_arg->SourceWidth; + EncArg.args.enc_init.cmn.in_height = h263_arg->SourceHeight; + EncArg.args.enc_init.cmn.in_gop_num = h263_arg->IDRPeriod; + + EncArg.args.enc_init.cmn.in_ms_mode = h263_arg->SliceMode; + EncArg.args.enc_init.cmn.in_ms_arg = 0; + + EncArg.args.enc_init.cmn.in_mb_refresh = h263_arg->RandomIntraMBRefresh; + + /* rate control*/ + EncArg.args.enc_init.cmn.in_rc_fr_en = h263_arg->EnableFRMRateControl; + if ((h263_arg->QSCodeMin > 31) || (h263_arg->QSCodeMax > 31)) { + LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_rc_qbound_min = h263_arg->QSCodeMin; + EncArg.args.enc_init.cmn.in_rc_qbound_max = h263_arg->QSCodeMax; + EncArg.args.enc_init.cmn.in_rc_rpara = h263_arg->CBRPeriodRf; + + /* pad control */ + EncArg.args.enc_init.cmn.in_pad_ctrl_on = h263_arg->PadControlOn; + if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit] No such Pad value is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_y_pad_val = h263_arg->LumaPadVal; + EncArg.args.enc_init.cmn.in_cb_pad_val = h263_arg->CbPadVal; + EncArg.args.enc_init.cmn.in_cr_pad_val = h263_arg->CrPadVal; + + /* Input stream Mode NV12_Linear or NV12_Tile*/ + EncArg.args.enc_init.cmn.in_frame_map = h263_arg->FrameMap; + + EncArg.args.enc_init.cmn.in_rc_bitrate = h263_arg->Bitrate; + if ((h263_arg->FrameQp > 31) || (h263_arg->FrameQp_P > 31)) { + LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_vop_quant = h263_arg->FrameQp; + EncArg.args.enc_init.cmn.in_vop_quant_p = h263_arg->FrameQp_P; + + /* H.263 only */ + EncArg.args.enc_init.codec.h263.in_rc_framerate = h263_arg->FrameRate; + + break; + + case H264_ENC: + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; + + EncArg.args.enc_init.cmn.in_codec_type = H264_ENC; + + EncArg.args.enc_init.cmn.in_width = h264_arg->SourceWidth; + EncArg.args.enc_init.cmn.in_height = h264_arg->SourceHeight; + EncArg.args.enc_init.cmn.in_gop_num = h264_arg->IDRPeriod; + + if ((h264_arg->SliceMode == 0)||(h264_arg->SliceMode == 1)|| + (h264_arg->SliceMode == 2)||(h264_arg->SliceMode == 4)) { + EncArg.args.enc_init.cmn.in_ms_mode = h264_arg->SliceMode; + } else { + LOGE("SsbSipMfcEncInit] No such slice mode is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_ms_arg = h264_arg->SliceArgument; + + EncArg.args.enc_init.cmn.in_mb_refresh = h264_arg->RandomIntraMBRefresh; + /* pad control */ + EncArg.args.enc_init.cmn.in_pad_ctrl_on = h264_arg->PadControlOn; + if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit] No such Pad value is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_y_pad_val = h264_arg->LumaPadVal; + EncArg.args.enc_init.cmn.in_cb_pad_val = h264_arg->CbPadVal; + EncArg.args.enc_init.cmn.in_cr_pad_val = h264_arg->CrPadVal; + + /* Input stream Mode NV12_Linear or NV12_Tile*/ + EncArg.args.enc_init.cmn.in_frame_map = h264_arg->FrameMap; + + /* rate control*/ + EncArg.args.enc_init.cmn.in_rc_fr_en = h264_arg->EnableFRMRateControl; + EncArg.args.enc_init.cmn.in_rc_bitrate = h264_arg->Bitrate; + if ((h264_arg->FrameQp > 51) || (h264_arg->FrameQp_P > 51)) { + LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_vop_quant = h264_arg->FrameQp; + EncArg.args.enc_init.cmn.in_vop_quant_p = h264_arg->FrameQp_P; + + if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) { + LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.cmn.in_rc_qbound_min = h264_arg->QSCodeMin; + EncArg.args.enc_init.cmn.in_rc_qbound_max = h264_arg->QSCodeMax; + EncArg.args.enc_init.cmn.in_rc_rpara = h264_arg->CBRPeriodRf; + + + /* H.264 Only */ + EncArg.args.enc_init.codec.h264.in_profile = h264_arg->ProfileIDC; + EncArg.args.enc_init.codec.h264.in_level = h264_arg->LevelIDC; + + if (h264_arg->FrameQp_B > 51) { + LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.h264.in_vop_quant_b = h264_arg->FrameQp_B; + + if (h264_arg->NumberBFrames > 2) { + LOGE("SsbSipMfcEncInit] No such BframeNum is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.h264.in_bframenum = h264_arg->NumberBFrames; + + EncArg.args.enc_init.codec.h264.in_interlace_mode = h264_arg->PictureInterlace; + + if ((h264_arg->NumberRefForPframes > 2)||(h264_arg->NumberReferenceFrames >2)) { + LOGE("SsbSipMfcEncInit] No such ref Num is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.h264.in_reference_num = h264_arg->NumberReferenceFrames; + EncArg.args.enc_init.codec.h264.in_ref_num_p = h264_arg->NumberRefForPframes; + + EncArg.args.enc_init.codec.h264.in_rc_framerate = h264_arg->FrameRate; + + EncArg.args.enc_init.codec.h264.in_rc_mb_en = h264_arg->EnableMBRateControl; + EncArg.args.enc_init.codec.h264.in_rc_mb_dark_dis = h264_arg->DarkDisable; + EncArg.args.enc_init.codec.h264.in_rc_mb_smooth_dis = h264_arg->SmoothDisable; + EncArg.args.enc_init.codec.h264.in_rc_mb_static_dis = h264_arg->StaticDisable; + EncArg.args.enc_init.codec.h264.in_rc_mb_activity_dis = h264_arg->ActivityDisable; + + EncArg.args.enc_init.codec.h264.in_deblock_dis = h264_arg->LoopFilterDisable; + if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) { + LOGE("SsbSipMfcEncInit] No such AlphaC0Offset or BetaOffset is supported"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init.codec.h264.in_deblock_alpha_c0 = h264_arg->LoopFilterAlphaC0Offset; + EncArg.args.enc_init.codec.h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset; + + EncArg.args.enc_init.codec.h264.in_symbolmode = h264_arg->SymbolMode; + EncArg.args.enc_init.codec.h264.in_transform8x8_mode = h264_arg->Transform8x8Mode; + + /* FIXME: is it removed? */ + EncArg.args.enc_init.codec.h264.in_md_interweight_pps = 300; + EncArg.args.enc_init.codec.h264.in_md_intraweight_pps = 170; + + break; + + default: + LOGE("SsbSipMfcEncInit] No such codec type is supported"); + return MFC_RET_INVALID_PARAM; + } + + EncArg.args.enc_init.cmn.in_mapped_addr = pCTX->mapped_addr; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg); + if (EncArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcEncInit] IOCTL_MFC_ENC_INIT failed"); + return MFC_RET_ENC_INIT_FAIL; + } + + pCTX->virStrmBuf = EncArg.args.enc_init.cmn.out_u_addr.strm_ref_y; + pCTX->phyStrmBuf = EncArg.args.enc_init.cmn.out_p_addr.strm_ref_y; + + pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; + pCTX->encodedHeaderSize = EncArg.args.enc_init.cmn.out_header_size; + + pCTX->virMvRefYC = EncArg.args.enc_init.cmn.out_u_addr.mv_ref_yc; + + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args EncArg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncExe] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + memset(&EncArg, 0x00, sizeof(struct mfc_common_args)); + + EncArg.args.enc_exe.in_codec_type = pCTX->codecType; + EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma; + EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma; +#if 0 /* peter for debug */ + EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma; + EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma; +#endif + EncArg.args.enc_exe.in_frametag = pCTX->inframetag; + if (pCTX->encode_cnt == 0) { + EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; + EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; + } else { + EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); + EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); + } + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg); + if (EncArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcEncExe] IOCTL_MFC_ENC_EXE failed(ret : %d)", EncArg.ret_code); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size; + pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type; + pCTX->encodedphyFrmBuf.luma = EncArg.args.enc_exe.out_Y_addr; + pCTX->encodedphyFrmBuf.chroma = EncArg.args.enc_exe.out_CbCr_addr; + pCTX->outframetagtop = EncArg.args.enc_exe.out_frametag_top; + pCTX->outframetagbottom = EncArg.args.enc_exe.out_frametag_bottom; + + LOGV("SsbSipMfcEncExe] Encode success =================="); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args free_arg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncClose] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + /* FIXME: free buffer? */ + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + free_arg.args.mem_free.key = pCTX->virFrmBuf.luma; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + free_arg.args.mem_free.key = pCTX->virStrmBuf; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + free_arg.args.mem_free.key = pCTX->virMvRefYC; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + pCTX->inter_buff_status = MFC_USE_NONE; + + munmap((void *)pCTX->mapped_addr, pCTX->mapped_size); + + close(pCTX->hMFC); + + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args user_addr_arg, real_addr_arg; + int y_size, c_size; + int aligned_y_size, aligned_c_size; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetInBuf] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + /* FIXME: */ + y_size = pCTX->width * pCTX->height; + c_size = (pCTX->width * pCTX->height) >> 1; + + /* lenear: 2KB, tile: 8KB */ + aligned_y_size = Align(y_size, 64 * BUF_L_UNIT); + aligned_c_size = Align(c_size, 64 * BUF_L_UNIT); + + /* Allocate luma & chroma buf */ + user_addr_arg.args.mem_alloc.type = ENCODER; + user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size; + user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_IN_BUF failed"); + return MFC_RET_ENC_GET_INBUF_FAIL; + } + + pCTX->virFrmBuf.luma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset; + pCTX->virFrmBuf.chroma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset + (unsigned int)aligned_y_size; + + real_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &real_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_REAL_ADDR failed"); + return MFC_RET_ENC_GET_INBUF_FAIL; + } + pCTX->phyFrmBuf.luma = real_addr_arg.args.real_addr.addr; + pCTX->phyFrmBuf.chroma = real_addr_arg.args.real_addr.addr + (unsigned int)aligned_y_size; + + pCTX->sizeFrmBuf.luma = (unsigned int)y_size; + pCTX->sizeFrmBuf.chroma = (unsigned int)c_size; + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma; + input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma; + input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma; + input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + int ret_code; + struct mfc_common_args user_addr_arg, real_addr_arg; + int y_size, c_size; + int aligned_y_size, aligned_c_size; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetInBuf] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + LOGV("SsbSipMfcEncSetInBuf] input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned"); + + pCTX = (_MFCLIB *) openHandle; + + /* FIXME: */ + y_size = pCTX->width * pCTX->height; + c_size = (pCTX->width * pCTX->height) >> 1; + + /* lenear: 2KB, tile: 8KB */ + aligned_y_size = Align(y_size, 64 * BUF_L_UNIT); + aligned_c_size = Align(c_size, 64 * BUF_L_UNIT); + + pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr; + pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr; + + pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize; + pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetOutBuf] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + output_info->headerSize = pCTX->encodedHeaderSize; + output_info->dataSize = pCTX->encodedDataSize; + output_info->frameType = pCTX->encodedframeType; + + if (pCTX->encode_cnt == 0) { + output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; + output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr; + } else { + output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); + output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); + } + + pCTX->encode_cnt ++; + pCTX->encode_cnt %= 2; + + output_info->encodedYPhyAddr = (void*)pCTX->encodedphyFrmBuf.luma; + output_info->encodedCPhyAddr = (void*)pCTX->encodedphyFrmBuf.chroma; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetOutBuf] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + pCTX->phyStrmBuf = (int)phyOutbuf; + pCTX->virStrmBuf = (int)virOutbuf; + pCTX->sizeStrmBuf = outputBufferSize; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + struct mfc_common_args EncArg; + struct mfc_enc_vui_info vui_info; + struct mfc_enc_hier_p_qp hier_p_qp; +#ifdef S3D_SUPPORT + struct mfc_enc_set_config set_info; + struct mfc_frame_packing *frame_packing; +#endif + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetConfig] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("SsbSipMfcEncSetConfig] value is NULL"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + memset(&EncArg, 0x00, sizeof(struct mfc_common_args)); + +#ifdef S3D_SUPPORT + EncArg.args.config.type = conf_type; + + switch (conf_type) { + case MFC_ENC_SETCONF_FRAME_TAG: + pCTX->inframetag = *((unsigned int *)value); + return MFC_RET_OK; + case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: + set_info = *((struct mfc_enc_set_config *) value); + EncArg.args.config.args.basic.values[0] = set_info.enable; + if (set_info.enable == 2) + EncArg.args.config.args.basic.values[1] = set_info.number; + else + EncArg.args.config.args.basic.values[1] = 0; + break; + case MFC_ENC_SETCONF_VUI_INFO: + set_info = *((struct mfc_enc_set_config *) value); + EncArg.args.config.args.basic.values[0] = set_info.enable; + if (set_info.enable == 255) //Re-check this part of code with Jeongtae Park + EncArg.args.config.args.basic.values[1] = set_info.number; + else + EncArg.args.config.args.basic.values[1] = 0; + + EncArg.args.config.args.basic.values[1] = set_info.number; + break; + case MFC_ENC_SETCONF_FRAME_PACKING: + frame_packing = (struct mfc_frame_packing *)value; + /* + memcpy(&EncArg.args.config.args.frame_packing, frame_packing, + sizeof(struct mfc_frame_packing)); + */ + EncArg.args.config.args.basic.values[0] = frame_packing->arrangement_type; + EncArg.args.config.args.basic.values[1] = frame_packing->current_frame_is_frame0_flag; + break; + case MFC_ENC_SETCONF_FRAME_TYPE: + case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: + case MFC_ENC_SETCONF_CHANGE_BIT_RATE: + case MFC_ENC_SETCONF_I_PERIOD: + case MFC_ENC_SETCONF_HIER_P: + case MFC_ENC_SETCONF_SEI_GEN: + EncArg.args.config.args.basic.values[0] = *((int *) value); + EncArg.args.config.args.basic.values[1] = 0; + break; + default: + LOGE("SsbSipMfcEncSetConfig] not supported type"); + return MFC_RET_ENC_SET_CONF_FAIL; + } +#else + EncArg.args.set_config.in_config_param = conf_type; + switch (conf_type) { + case MFC_ENC_SETCONF_FRAME_TAG: + pCTX->inframetag = *((unsigned int *)value); + return MFC_RET_OK; + case MFC_ENC_SETCONF_VUI_INFO: + vui_info = *((struct mfc_enc_vui_info *) value); + EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); + EncArg.args.set_config.in_config_value[1] = 0; + break; + case MFC_ENC_SETCONF_HIER_P: + hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); + EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp); + EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp); + EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp); + break; + default: + EncArg.args.set_config.in_config_value[0] = *((int *) value); + EncArg.args.set_config.in_config_value[1] = 0; + break; + } +#endif + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg); + if (EncArg.ret_code != MFC_OK) { + LOGE("SsbSipMfcEncSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d)", EncArg.ret_code); + return MFC_RET_ENC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + /* + unsigned int *encoded_header_size; + */ + + pCTX = (_MFCLIB *)openHandle; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetConfig] openHandle is NULL"); + return MFC_RET_INVALID_PARAM; + } + if (value == NULL) { + LOGE("SsbSipMfcEncGetConfig] value is NULL"); + return MFC_RET_INVALID_PARAM; + } + + switch (conf_type) { + case MFC_ENC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->outframetagtop; + break; +#if 0 + case MFC_ENC_GETCONF_HEADER_SIZE: + encoded_header_size = (unsigned int *)value; + *encoded_header_size = pCTX->encodedHeaderSize; + break; +#endif + default: + LOGE("SsbSipMfcEncGetConfig] No such conf_type is supported."); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} + diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/include/SsbSipMfcApi.h b/exynos/multimedia/codecs/video/exynos4/mfc/include/SsbSipMfcApi.h new file mode 100644 index 0000000..462c45d --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/include/SsbSipMfcApi.h @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SSBSIP_MFC_API_H_ +#define _SSBSIP_MFC_API_H_ + +/*--------------------------------------------------------------------------------*/ +/* Definition */ +/*--------------------------------------------------------------------------------*/ +#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) +#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) + +#define SUPPORT_1080P 1 + +#if SUPPORT_1080P +#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ +#else +#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) +#endif + +#define SAMSUNG_MFC_DEV_NAME "/dev/s3c-mfc" + + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + H264_DEC, + VC1_DEC, /* VC1 advaced Profile decoding */ + MPEG4_DEC, + XVID_DEC, + MPEG1_DEC, + MPEG2_DEC, + H263_DEC, + VC1RCV_DEC, /* VC1 simple/main profile decoding */ + FIMV1_DEC, + FIMV2_DEC, + FIMV3_DEC, + FIMV4_DEC, + H264_ENC, + MPEG4_ENC, + H263_ENC, + UNKNOWN_TYPE +} SSBSIP_MFC_CODEC_TYPE; + +typedef enum { + DONT_CARE = 0, + I_FRAME = 1, + NOT_CODED = 2 +} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; + +typedef enum { + NV12_LINEAR = 0, + NV12_TILE +} SSBSIP_MFC_INSTRM_MODE_TYPE; + +typedef enum { + NO_CACHE = 0, + CACHE = 1 +} SSBIP_MFC_BUFFER_TYPE; + +typedef enum { + MFC_DEC_SETCONF_POST_ENABLE = 1, + MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, + MFC_DEC_SETCONF_DISPLAY_DELAY, + MFC_DEC_SETCONF_IS_LAST_FRAME, + MFC_DEC_SETCONF_SLICE_ENABLE, + MFC_DEC_SETCONF_CRC_ENABLE, + MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, + MFC_DEC_SETCONF_FRAME_TAG, + MFC_DEC_GETCONF_CRC_DATA, + MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, + MFC_DEC_GETCONF_CROP_INFO, + MFC_DEC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, + MFC_DEC_SETCONF_DPB_FLUSH, + MFC_DEC_SETCONF_PIXEL_CACHE, +#ifndef S3D_SUPPORT + MFC_DEC_GETCONF_WIDTH_HEIGHT +#else + MFC_DEC_GETCONF_WIDTH_HEIGHT, + MFC_DEC_SETCONF_SEI_PARSE, + MFC_DEC_GETCONF_FRAME_PACKING +#endif +} SSBSIP_MFC_DEC_CONF; + +typedef enum { + MFC_ENC_SETCONF_FRAME_TYPE = 100, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + MFC_ENC_SETCONF_FRAME_TAG, + MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, + MFC_ENC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_ENC_SETCONF_VUI_INFO, + MFC_ENC_SETCONF_I_PERIOD, +#ifndef S3D_SUPPORT + MFC_ENC_SETCONF_HIER_P +#else + MFC_ENC_SETCONF_HIER_P, + MFC_ENC_SETCONF_SEI_GEN, + MFC_ENC_SETCONF_FRAME_PACKING +#endif +} SSBSIP_MFC_ENC_CONF; + +typedef enum { + MFC_GETOUTBUF_STATUS_NULL = 0, + MFC_GETOUTBUF_DECODING_ONLY = 1, + MFC_GETOUTBUF_DISPLAY_DECODING, + MFC_GETOUTBUF_DISPLAY_ONLY, + MFC_GETOUTBUF_DISPLAY_END, + MFC_GETOUTBUF_CHANGE_RESOL +} SSBSIP_MFC_DEC_OUTBUF_STATUS; + +typedef enum { + MFC_FRAME_TYPE_NOT_CODED, + MFC_FRAME_TYPE_I_FRAME, + MFC_FRAME_TYPE_P_FRAME, + MFC_FRAME_TYPE_B_FRAME, + MFC_FRAME_TYPE_OTHERS +} SSBSIP_MFC_FRAME_TYPE; + +typedef enum { + MFC_RET_OK = 1, + MFC_RET_FAIL = -1000, + MFC_RET_OPEN_FAIL = -1001, + MFC_RET_CLOSE_FAIL = -1002, + + MFC_RET_DEC_INIT_FAIL = -2000, + MFC_RET_DEC_EXE_TIME_OUT = -2001, + MFC_RET_DEC_EXE_ERR = -2002, + MFC_RET_DEC_GET_INBUF_FAIL = -2003, + MFC_RET_DEC_SET_INBUF_FAIL = -2004, + MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, + MFC_RET_DEC_GET_CONF_FAIL = -2006, + MFC_RET_DEC_SET_CONF_FAIL = -2007, + + MFC_RET_ENC_INIT_FAIL = -3000, + MFC_RET_ENC_EXE_TIME_OUT = -3001, + MFC_RET_ENC_EXE_ERR = -3002, + MFC_RET_ENC_GET_INBUF_FAIL = -3003, + MFC_RET_ENC_SET_INBUF_FAIL = -3004, + MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, + MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, + MFC_RET_ENC_GET_CONF_FAIL = -3007, + MFC_RET_ENC_SET_CONF_FAIL = -3008, + + MFC_RET_INVALID_PARAM = -4000 +} SSBSIP_MFC_ERROR_CODE; + +typedef struct { + void *YPhyAddr; /* [OUT] physical address of Y */ + void *CPhyAddr; /* [OUT] physical address of CbCr */ + void *YVirAddr; /* [OUT] virtual address of Y */ + void *CVirAddr; /* [OUT] virtual address of CbCr */ + + int img_width; /* [OUT] width of real image */ + int img_height; /* [OUT] height of real image */ + int buf_width; /* [OUT] width aligned to 16 */ + int buf_height; /* [OUT] height alighed to 16 */ + + int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ + int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ + int consumedByte; /* [OUT] the number of byte consumed during decoding */ + int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ + int crop_top_offset; /* [OUT] crop information, top_offset */ + int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ + int crop_left_offset; /* [OUT] crop information, left_offset */ + int crop_right_offset; /* [OUT] crop information, right_offset */ + int disp_pic_frame_type; /* [OUT] display picture frame type information */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_DEC_OUTPUT_INFO; + +typedef struct { + void *YPhyAddr; /* [IN/OUT] physical address of Y */ + void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ + void *YVirAddr; /* [IN/OUT] virtual address of Y */ + void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ + int YSize; /* [IN/OUT] input size of Y data */ + int CSize; /* [IN/OUT] input size of CbCr data */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_INPUT_INFO; + +typedef struct { + unsigned int dataSize; /* [OUT] encoded data size(without header) */ + unsigned int headerSize; /* [OUT] encoded header size */ + unsigned int frameType; /* [OUT] frame type of encoded stream */ + void *StrmPhyAddr; /* [OUT] physical address of Y */ + void *StrmVirAddr; /* [OUT] virtual address of Y */ + void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ + void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ + + /* C210 UMP feature */ + unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ + unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ + unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_OUTPUT_INFO; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* H.264 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int NumberReferenceFrames; /* [IN] The number of reference pictures used */ + int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ + int LoopFilterDisable; /* [IN] disable the loop filter */ + int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ + int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ + int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ + int PictureInterlace; /* [IN] Enables the interlace mode */ + int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ + int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ + int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ + int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ + int StaticDisable; /* [IN] Disable adaptive rate control on static region */ + int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ +} SSBSIP_MFC_ENC_H264_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* MPEG4 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int TimeIncreamentRes; /* [IN] frame rate */ + int VopTimeIncreament; /* [IN] frame rate */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ +} SSBSIP_MFC_ENC_MPEG4_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* H.263 specific parameters */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ +} SSBSIP_MFC_ENC_H263_PARAM; + +typedef struct { + int width; + int height; + int buf_width; + int buf_height; +} SSBSIP_MFC_IMG_RESOLUTION; + +typedef struct { + int crop_top_offset; + int crop_bottom_offset; + int crop_left_offset; + int crop_right_offset; +} SSBSIP_MFC_CROP_INFORMATION; + +#ifdef S3D_SUPPORT +typedef struct { + int available; + unsigned int arrangement_id; + int arrangement_cancel_flag; + unsigned char arrangement_type; + int quincunx_sampling_flag; + unsigned char content_interpretation_type; + int spatial_flipping_flag; + int frame0_flipped_flag; + int field_views_flag; + int current_frame_is_frame0_flag; + unsigned char frame0_grid_pos_x; + unsigned char frame0_grid_pos_y; + unsigned char frame1_grid_pos_x; + unsigned char frame1_grid_pos_y; +} SSBSIP_MFC_FRAME_PACKING; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------------*/ +/* Decoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcDecOpen(void); +void *SsbSipMfcDecOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); + + +#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); +#else +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); +#endif + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); + +/*--------------------------------------------------------------------------------*/ +/* Encoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcEncOpen(void); +void *SsbSipMfcEncOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_errno.h b/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_errno.h new file mode 100644 index 0000000..305a28e --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_errno.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_ERRNO_H +#define __MFC_ERRNO_H __FILE__ + +enum mfc_ret_code { + MFC_OK = 1, + MFC_FAIL = -1000, + MFC_OPEN_FAIL = -1001, + MFC_CLOSE_FAIL = -1002, + + MFC_DEC_INIT_FAIL = -2000, + MFC_DEC_EXE_TIME_OUT = -2001, + MFC_DEC_EXE_ERR = -2002, + MFC_DEC_GET_INBUF_FAIL = 2003, + MFC_DEC_SET_INBUF_FAIL = 2004, + MFC_DEC_GET_OUTBUF_FAIL = -2005, + MFC_DEC_GET_CONF_FAIL = -2006, + MFC_DEC_SET_CONF_FAIL = -2007, + + MFC_ENC_INIT_FAIL = -3000, + MFC_ENC_EXE_TIME_OUT = -3001, + MFC_ENC_EXE_ERR = -3002, + MFC_ENC_GET_INBUF_FAIL = -3003, + MFC_ENC_SET_INBUF_FAIL = -3004, + MFC_ENC_GET_OUTBUF_FAIL = -3005, + MFC_ENC_SET_OUTBUF_FAIL = -3006, + MFC_ENC_GET_CONF_FAIL = -3007, + MFC_ENC_SET_CONF_FAIL = -3008, + + MFC_STATE_INVALID = -4000, + MFC_DEC_HEADER_FAIL = -4001, + MFC_DEC_INIT_BUF_FAIL = -4002, + MFC_ENC_HEADER_FAIL = -5000, + MFC_ENC_PARAM_FAIL = -5001, + MFC_FRM_BUF_SIZE_FAIL = -6000, + MFC_FW_LOAD_FAIL = -6001, + MFC_FW_INIT_FAIL = -6002, + MFC_INST_NUM_EXCEEDED_FAIL = -6003, + MFC_MEM_ALLOC_FAIL = -6004, + MFC_MEM_INVALID_ADDR_FAIL = -6005, + MFC_MEM_MAPPING_FAIL = -6006, + MFC_GET_CONF_FAIL = -6007, + MFC_SET_CONF_FAIL = -6008, + MFC_INVALID_PARAM_FAIL = -6009, + MFC_API_FAIL = -9000, + + MFC_CMD_FAIL = -1003, + MFC_SLEEP_FAIL = -1010, + MFC_WAKEUP_FAIL = -1020, + + MFC_CLK_ON_FAIL = -1030, + MFC_CLK_OFF_FAIL = -1030, + MFC_PWR_ON_FAIL = -1040, + MFC_PWR_OFF_FAIL = -1041, +} ; + +#endif /* __MFC_ERRNO_H */ diff --git a/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_interface.h b/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_interface.h new file mode 100644 index 0000000..7fa6b94 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc/include/mfc_interface.h @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_INTERFACE_H +#define __MFC_INTERFACE_H __FILE__ + +#include "mfc_errno.h" +#include "SsbSipMfcApi.h" + +#define IOCTL_MFC_DEC_INIT (0x00800001) +#define IOCTL_MFC_ENC_INIT (0x00800002) +#define IOCTL_MFC_DEC_EXE (0x00800003) +#define IOCTL_MFC_ENC_EXE (0x00800004) + +#define IOCTL_MFC_GET_IN_BUF (0x00800010) +#define IOCTL_MFC_FREE_BUF (0x00800011) +#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) +#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) +#define IOCTL_MFC_SET_IN_BUF (0x00800018) + +#define IOCTL_MFC_SET_CONFIG (0x00800101) +#define IOCTL_MFC_GET_CONFIG (0x00800102) + +#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) + +/* MFC H/W support maximum 32 extra DPB. */ +#define MFC_MAX_EXTRA_DPB 5 +#define MFC_MAX_DISP_DELAY 0xF + +#define MFC_LIB_VER_MAJOR 1 +#define MFC_LIB_VER_MINOR 00 + +#define BUF_L_UNIT (1024) +#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) + +enum inst_type { + DECODER = 0x1, + ENCODER = 0x2, +}; + +typedef enum { + MFC_UNPACKED_PB = 0, + MFC_PACKED_PB = 1 +} mfc_packed_mode; + + +typedef enum +{ + MFC_USE_NONE = 0x00, + MFC_USE_YUV_BUFF = 0x01, + MFC_USE_STRM_BUFF = 0x10 +} s3c_mfc_interbuff_status; + +typedef struct +{ + int luma0; /* per frame (or top field) */ + int chroma0; /* per frame (or top field) */ + int luma1; /* per frame (or bottom field) */ + int chroma1; /* per frame (or bottom field) */ +} SSBSIP_MFC_CRC_DATA; + +struct mfc_strm_ref_buf_arg { + unsigned int strm_ref_y; + unsigned int mv_ref_yc; +}; + +struct mfc_frame_buf_arg { + unsigned int luma; + unsigned int chroma; +}; + + +struct mfc_enc_init_common_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + + int in_width; /* [IN] width of YUV420 frame to be encoded */ + int in_height; /* [IN] height of YUV420 frame to be encoded */ + + int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ + int in_vop_quant; /* [IN] VOP quant */ + int in_vop_quant_p; /* [IN] VOP quant for P frame */ + + /* [IN] RC enable */ + /* [IN] RC enable (0:disable, 1:frame level RC) */ + int in_rc_fr_en; + int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ + + int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ + int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ + int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ + + /* [IN] Multi-slice mode (0:single, 1:multiple) */ + int in_ms_mode; + /* [IN] Multi-slice size (in num. of mb or byte) */ + int in_ms_arg; + + int in_mb_refresh; /* [IN] Macroblock refresh */ + + /* [IN] Enable (1) / Disable (0) padding with the specified values */ + int in_pad_ctrl_on; + + /* [IN] pad value if pad_ctrl_on is Enable */ + int in_y_pad_val; + int in_cb_pad_val; + int in_cr_pad_val; + + /* linear or tiled */ + int in_frame_map; + + unsigned int in_pixelcache; + + unsigned int in_mapped_addr; + struct mfc_strm_ref_buf_arg out_u_addr; + struct mfc_strm_ref_buf_arg out_p_addr; + struct mfc_strm_ref_buf_arg out_buf_size; + unsigned int out_header_size; +}; + +struct mfc_enc_init_h263_arg { + int in_rc_framerate; /* [IN] RC parameter (framerate) */ +}; + +struct mfc_enc_init_mpeg4_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ + int in_quart_pixel; + + int in_TimeIncreamentRes; /* [IN] VOP time resolution */ + int in_VopTimeIncreament; /* [IN] Frame delta */ +}; + +struct mfc_enc_init_h264_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] interlace mode(0:progressive, 1:interlace) */ + int in_interlace_mode; + + /* [IN] reference number */ + int in_reference_num; + /* [IN] reference number of P frame */ + int in_ref_num_p; + + int in_rc_framerate; /* [IN] RC parameter (framerate) */ + int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ + /* [IN] MB level rate control dark region adaptive feature */ + int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control smooth region adaptive feature */ + int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control static region adaptive feature */ + int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control activity region adaptive feature */ + int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ + + /* [IN] disable deblocking filter idc */ + int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ + /* [IN] slice alpha c0 offset of deblocking filter */ + int in_deblock_alpha_c0; + /* [IN] slice beta offset of deblocking filter */ + int in_deblock_beta; + + /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ + int in_symbolmode; + /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ + int in_transform8x8_mode; + + /* [IN] Inter weighted parameter for mode decision */ + int in_md_interweight_pps; + /* [IN] Intra weighted parameter for mode decision */ + int in_md_intraweight_pps; +}; + +struct mfc_enc_init_arg { + struct mfc_enc_init_common_arg cmn; + union { + struct mfc_enc_init_h264_arg h264; + struct mfc_enc_init_mpeg4_arg mpeg4; + struct mfc_enc_init_h263_arg h263; + } codec; +}; + +struct mfc_enc_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ + unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ + unsigned int in_frametag; /* [IN] unique frame ID */ + + unsigned int out_frame_type; /* [OUT] frame type */ + int out_encoded_size; /* [OUT] Length of Encoded video stream */ + unsigned int out_Y_addr; /* [OUT]Out-buffer addr of encoded Y component */ + unsigned int out_CbCr_addr; /* [OUT]Out-buffer addr of encoded CbCr component */ + unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */ + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif +}; + +struct mfc_dec_init_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] address of stream buffer */ + int in_strm_size; /* [IN] filled size in stream buffer */ + int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ + + unsigned int in_crc; /* [IN] */ + unsigned int in_pixelcache; /* [IN] */ + unsigned int in_slice; /* [IN] */ + unsigned int in_numextradpb; /* [IN] */ + + unsigned int in_mapped_addr; + + int out_frm_width; /* [OUT] width of YUV420 frame */ + int out_frm_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ + + int out_crop_right_offset; /* [OUT] crop information for h264 */ + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; +}; + +struct mfc_dec_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] the physical address of STRM_BUF */ + /* [IN] Size of video stream filled in STRM_BUF */ + int in_strm_size; + /* [IN] the address of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_buf; + /* [IN] size of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_size; + /* [IN] Unique frame ID eg. application specific timestamp */ + unsigned int in_frametag; + /* [IN] immdiate Display for seek,thumbnail and one frame */ + int in_immediately_disp; + /* [OUT] the physical address of display buf */ + int out_display_Y_addr; + /* [OUT] the physical address of display buf */ + int out_display_C_addr; + int out_display_status; + /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_top; + /* [OUT] unique frame ID of bottom field */ + unsigned int out_frametag_bottom; + int out_pic_time_top; + int out_pic_time_bottom; + int out_consumed_byte; + + int out_crop_right_offset; + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; + + /* in new driver, each buffer offset must be return to the user */ + int out_y_offset; + int out_c_offset; + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif + int out_img_width; /* [OUT] width of YUV420 frame */ + int out_img_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ +}; + +#ifdef S3D_SUPPORT +struct mfc_basic_config { + int values[4]; +}; + +struct mfc_frame_packing { + int available; + unsigned int arrangement_id; + int arrangement_cancel_flag; + unsigned char arrangement_type; + int quincunx_sampling_flag; + unsigned char content_interpretation_type; + int spatial_flipping_flag; + int frame0_flipped_flag; + int field_views_flag; + int current_frame_is_frame0_flag; + unsigned char frame0_grid_pos_x; + unsigned char frame0_grid_pos_y; + unsigned char frame1_grid_pos_x; + unsigned char frame1_grid_pos_y; +}; + +union _mfc_config_arg { + struct mfc_basic_config basic; + struct mfc_frame_packing frame_packing; +}; + +struct mfc_config_arg { + int type; + union _mfc_config_arg args; +}; +#else +struct mfc_get_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to get for the configurable parameter. */ + /* Maximum four integer values can be obtained; */ + int out_config_value[4]; +}; + +struct mfc_set_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to be set for the configurable parameter. */ + /* Maximum four integer values can be set. */ + int in_config_value[4]; +}; +#endif + +struct mfc_get_real_addr_arg { + unsigned int key; + unsigned int addr; +}; + +struct mfc_buf_alloc_arg { + enum inst_type type; + int size; + /* + unsigned int mapped; + */ + unsigned int align; + + unsigned int addr; + /* + unsigned int phys; + */ +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + /* FIMXE: invalid secure id == -1 */ + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_buf_free_arg { + unsigned int addr; +}; + + +/* RMVME */ +struct mfc_mem_alloc_arg { + enum inst_type type; + int buff_size; + SSBIP_MFC_BUFFER_TYPE buf_cache_type; + unsigned int mapped_addr; +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_mem_free_arg { + unsigned int key; +}; +/* RMVME */ + +union mfc_args { + /* + struct mfc_enc_init_arg enc_init; + + struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; + struct mfc_enc_init_mpeg4_arg enc_init_h263; + struct mfc_enc_init_h264_arg enc_init_h264; + */ + struct mfc_enc_init_arg enc_init; + struct mfc_enc_exe_arg enc_exe; + + struct mfc_dec_init_arg dec_init; + struct mfc_dec_exe_arg dec_exe; + +#ifdef S3D_SUPPORT + struct mfc_config_arg config; +#else + struct mfc_get_config_arg get_config; + struct mfc_set_config_arg set_config; +#endif + + struct mfc_buf_alloc_arg buf_alloc; + struct mfc_buf_free_arg buf_free; + struct mfc_get_real_addr_arg real_addr; + + /* RMVME */ + struct mfc_mem_alloc_arg mem_alloc; + struct mfc_mem_free_arg mem_free; + /* RMVME */ +}; + +struct mfc_common_args { + enum mfc_ret_code ret_code; /* [OUT] error code */ + union mfc_args args; +}; + +struct mfc_enc_vui_info { + int aspect_ratio_idc; +}; + +struct mfc_dec_fimv1_info { + int width; + int height; +}; + +struct mfc_enc_hier_p_qp { + int t0_frame_qp; + int t2_frame_qp; + int t3_frame_qp; +}; + +#ifdef S3D_SUPPORT +struct mfc_enc_set_config { + int enable; + int number; +}; +#endif + +typedef struct +{ + int magic; + int hMFC; + int hVMEM; + int width; + int height; + int sizeStrmBuf; + struct mfc_frame_buf_arg sizeFrmBuf; + int displayStatus; + int inter_buff_status; + unsigned int virFreeStrmAddr; + unsigned int phyStrmBuf; + unsigned int virStrmBuf; + unsigned int virMvRefYC; + struct mfc_frame_buf_arg phyFrmBuf; + struct mfc_frame_buf_arg virFrmBuf; + unsigned int mapped_addr; + unsigned int mapped_size; + struct mfc_common_args MfcArg; + SSBSIP_MFC_CODEC_TYPE codecType; + SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; + unsigned int inframetag; + unsigned int outframetagtop; + unsigned int outframetagbottom; + unsigned int immediatelydisp; + unsigned int encodedHeaderSize; + int encodedDataSize; + unsigned int encodedframeType; + struct mfc_frame_buf_arg encodedphyFrmBuf; + + unsigned int dec_crc; + unsigned int dec_pixelcache; + unsigned int dec_slice; + unsigned int dec_numextradpb; + + int input_cookie; + int input_secure_id; + int input_size; + + /* to support non-blocking mode */ + unsigned int encode_cnt; +} _MFCLIB; + +#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) +#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) + +#endif /* __MFC_INTERFACE_H */ diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/Android.mk b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/Android.mk new file mode 100644 index 0000000..6025b43 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/Android.mk @@ -0,0 +1,34 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + include/mfc_errno.h \ + include/mfc_interface.h \ + include/SsbSipMfcApi.h + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + dec/src/SsbSipMfcDecAPI.c \ + enc/src/SsbSipMfcEncAPI.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + device/samsung/$(TARGET_BOARD_PLATFORM)/include + +LOCAL_MODULE := libsecmfcapi + +LOCAL_PRELINK_MODULE := false + +ifeq ($(BOARD_USES_MFC_FPS),true) +LOCAL_CFLAGS := -DCONFIG_MFC_FPS +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := liblog + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c new file mode 100644 index 0000000..510a351 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c @@ -0,0 +1,1352 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "videodev2.h" + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "MFC_DEC_APP" +#include + +#ifdef CONFIG_MFC_FPS +#include +#endif + +/*#define CRC_ENABLE +#define SLICE_MODE_ENABLE */ +#define POLL_DEC_WAIT_TIMEOUT 25 + +#define USR_DATA_START_CODE (0x000001B2) +#define VOP_START_CODE (0x000001B6) +#define MP4_START_CODE (0x000001) + +#ifdef CONFIG_MFC_FPS +unsigned int framecount, over30ms; +struct timeval mTS1, mTS2, mDec1, mDec2; +#endif + +#define DEFAULT_NUMBER_OF_EXTRA_DPB 5 + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; +static int mfc_dev_node = 6; + +static void getAByte(char *buff, int *code) +{ + int byte; + + *code = (*code << 8); + byte = (int)*buff; + byte &= 0xFF; + *code |= byte; +} + +static int isPBPacked(_MFCLIB *pCtx, int Frameleng) +{ + char *strmBuffer = NULL; + int startCode = 0xFFFFFFFF; + int leng_idx = 1; + + strmBuffer = (char*)pCtx->virStrmBuf; + + while (1) { + while (startCode != USR_DATA_START_CODE) { + if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { + LOGI("[%s] VOP START Found !!.....return",__func__); + LOGW("[%s] Non Packed PB",__func__); + return 0; + } + getAByte(strmBuffer, &startCode); + LOGV(">> StartCode = 0x%08x <<\n", startCode); + strmBuffer++; + leng_idx++; + } + LOGI("[%s] User Data Found !!",__func__); + + do { + if (*strmBuffer == 'p') { + LOGW("[%s] Packed PB",__func__); + return 1; + } + getAByte(strmBuffer, &startCode); + strmBuffer++; leng_idx++; + } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); + + if (leng_idx > Frameleng) + break; + } + + LOGW("[%s] Non Packed PB",__func__); + + return 0; +} + +static void getMFCName(char *devicename, int size) +{ + snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); +} + +void SsbSipMfcDecSetMFCNode(int devicenode) +{ + mfc_dev_node = devicenode; +} + +void SsbSipMfcDecSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcDecOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX; + + char mfc_dev_name[64]; + + int ret; + unsigned int i, j; + struct v4l2_capability cap; + struct v4l2_format fmt; + + struct v4l2_requestbuffers reqbuf; + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); +#ifdef CONFIG_MFC_FPS + framecount = 0; + over30ms = 0; + gettimeofday(&mTS1, NULL); +#endif + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("[%s] malloc failed.",__func__); + return NULL; + } + + memset(pCTX, 0, sizeof(_MFCLIB)); + + getMFCName(mfc_dev_name, 64); + LOGI("[%s] dev name is %s",__func__,mfc_dev_name); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("[%s] MFC device node not exists",__func__); + goto error_case1; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR|O_NONBLOCK, 0); + if (hMFCOpen < 0) { + LOGE("[%s] Failed to open MFC device",__func__); + goto error_case1; + } + + pCTX->hMFC = hMFCOpen; + + memset(&cap, 0, sizeof(cap)); + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); + goto error_case2; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("[%s] Device does not support capture",__func__); + goto error_case2; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOGE("[%s] Device does not support output",__func__); + goto error_case2; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("[%s] Device does not support streaming",__func__); + goto error_case2; + } + + pCTX->inter_buff_status = MFC_USE_NONE; + memset(&fmt, 0, sizeof(fmt)); + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; /* Default is set to H264 */ + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed",__func__); + goto error_case2; + } + + pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE; + + memset(&(reqbuf), 0, sizeof (reqbuf)); + reqbuf.count = MFC_DEC_NUM_SRC_BUFS; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_REQBUFS failed",__func__); + goto error_case2; + } + + pCTX->v4l2_dec.mfc_num_src_bufs = reqbuf.count; + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; ++i) { + memset(&(buf), 0, sizeof (buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + buf.m.planes = planes; + buf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYBUF failed",__func__); + goto error_case3; + } + + pCTX->v4l2_dec.mfc_src_bufs[i] = mmap(NULL, buf.m.planes[0].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_dec.mfc_src_bufs[i] == MAP_FAILED) { + LOGE("[%s] mmap failed (%d)",__func__,i); + goto error_case3; + } + } + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + /* set extra DPB size to 5 as default for optimal performce (heuristic method) */ + pCTX->dec_numextradpb = DEFAULT_NUMBER_OF_EXTRA_DPB; + + pCTX->v4l2_dec.bBeingFinalized = 0; + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED; + + pCTX->cacheablebuffer = NO_CACHE; + + for (i = 0; iv4l2_dec.mfc_src_buf_flags[i] = BUF_DEQUEUED; + + pCTX->v4l2_dec.beingUsedIndex = 0; + + return (void *) pCTX; + +error_case3: + for (j = 0; j < i; j++) + munmap(pCTX->v4l2_dec.mfc_src_bufs[j], pCTX->v4l2_dec.mfc_src_bufs_len); + +error_case2: + close(pCTX->hMFC); + +error_case1: + free(pCTX); + + return NULL; +} + +void *SsbSipMfcDecOpenExt(void *value) +{ + _MFCLIB *pCTX; + + pCTX = SsbSipMfcDecOpen(); + + if (pCTX == NULL) + return NULL; + + if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { + pCTX->cacheablebuffer = NO_CACHE; + LOGI("[%s] non cacheable buffer",__func__); + } else { + pCTX->cacheablebuffer = CACHE; + LOGI("[%s] cacheable buffer",__func__); + } + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) +{ + int ret, i; + _MFCLIB *pCTX; + + enum v4l2_buf_type type; +#ifdef CONFIG_MFC_FPS + LOGI(">>> MFC"); + gettimeofday(&mTS2, NULL); + LOGI(">>> time=%d", mTS2.tv_sec-mTS1.tv_sec); + LOGI(">>> framecount=%d", framecount); + LOGI(">>> 30ms over=%d", over30ms); +#endif + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + } + + if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); + } + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; i++) + munmap(pCTX->v4l2_dec.mfc_src_bufs[i], pCTX->v4l2_dec.mfc_src_bufs_len); + pCTX->inter_buff_status &= ~(MFC_USE_STRM_BUFF); + } + + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); + } + pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); + } + + close(pCTX->hMFC); + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) +{ + int packedPB = 0; + _MFCLIB *pCTX; + int ret; + unsigned int i, j; + + struct v4l2_requestbuffers reqbuf; + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + struct v4l2_format fmt; + struct v4l2_pix_format_mplane pix_mp; + struct v4l2_control ctrl; + struct v4l2_crop crop; + enum v4l2_buf_type type; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + pCTX->codecType = codec_type; + + if ((pCTX->codecType == MPEG4_DEC) || (pCTX->codecType == XVID_DEC) || + (pCTX->codecType == FIMV1_DEC) || (pCTX->codecType == FIMV2_DEC) || + (pCTX->codecType == FIMV3_DEC) || (pCTX->codecType == FIMV4_DEC)) + packedPB = isPBPacked(pCTX, Frameleng); + + memset(&fmt, 0, sizeof(fmt)); + + switch (pCTX->codecType) { + case H264_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + break; + case MPEG4_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case H263_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; + break; + case XVID_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_XVID; + break; + case MPEG2_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG12; + break; + case FIMV1_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV1; + fmt.fmt.pix_mp.width = pCTX->fimv1_res.width; + fmt.fmt.pix_mp.height = pCTX->fimv1_res.height; + break; + case FIMV2_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV2; + break; + case FIMV3_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV3; + break; + case FIMV4_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV4; + break; + case VC1_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1; + break; + case VC1RCV_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1_RCV; + break; + default: + LOGE("[%s] Does NOT support the standard (%d)",__func__,pCTX->codecType); + ret = MFC_RET_INVALID_PARAM; + goto error_case1; + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + memset(&qbuf, 0, sizeof(qbuf)); + + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_dec.beingUsedIndex; + qbuf.m.planes = planes; + qbuf.length = 1; + qbuf.m.planes[0].bytesused = Frameleng; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + // Processing the header requires running streamon + // on OUTPUT queue + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_FMT failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pix_mp = fmt.fmt.pix_mp; + pCTX->decOutInfo.buf_width = pix_mp.plane_fmt[0].bytesperline; + pCTX->decOutInfo.buf_height = + pix_mp.plane_fmt[0].sizeimage / pix_mp.plane_fmt[0].bytesperline; + + pCTX->decOutInfo.img_width = pix_mp.width; + pCTX->decOutInfo.img_height = pix_mp.height; + + memset(&crop, 0, sizeof(crop)); + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CROP, &crop); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CROP failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->decOutInfo.crop_left_offset = crop.c.left; + pCTX->decOutInfo.crop_top_offset = crop.c.top; + pCTX->decOutInfo.crop_right_offset = + pix_mp.width - crop.c.width - crop.c.left; + pCTX->decOutInfo.crop_bottom_offset = + pix_mp.height - crop.c.height - crop.c.top; + + memset(&ctrl, 0, sizeof(ctrl)); + ctrl.id = V4L2_CID_CODEC_REQ_NUM_BUFS; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl.value + pCTX->dec_numextradpb; + + /* Cacheable buffer */ + ctrl.id = V4L2_CID_CACHEABLE; + if(pCTX->cacheablebuffer == NO_CACHE) + ctrl.value = 0; + else + ctrl.value = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + memset(&reqbuf, 0, sizeof(reqbuf)); + reqbuf.count = pCTX->v4l2_dec.mfc_num_dst_bufs; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_REQBUFS failed (destination buffers)",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->v4l2_dec.mfc_num_dst_bufs = reqbuf.count; + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = i; + qbuf.m.planes = planes; + qbuf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYBUF failed (destination buffers)",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->v4l2_dec.mfc_dst_bufs_len[0] = qbuf.m.planes[0].length; + pCTX->v4l2_dec.mfc_dst_bufs_len[1] = qbuf.m.planes[1].length; + + pCTX->v4l2_dec.mfc_dst_phys[i][0] = qbuf.m.planes[0].cookie; + pCTX->v4l2_dec.mfc_dst_phys[i][1] = qbuf.m.planes[1].cookie; + + pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, qbuf.m.planes[0].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.m.planes[0].m.mem_offset); + + if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) { + LOGE("[%s] mmap failed (destination buffers (Y))",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_dec.mfc_dst_bufs[i][1] = mmap(NULL, qbuf.m.planes[1].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.m.planes[1].m.mem_offset); + if (pCTX->v4l2_dec.mfc_dst_bufs[i][1] == MAP_FAILED) { + LOGE("[%s] mmap failed (destination buffers (UV))",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } + } + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if(ret != 0) { + LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + return MFC_RET_OK; + +error_case2: + for (j = 0; j < i; j++) { + munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); + munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); + } +error_case1: + SsbSipMfcDecClose(openHandle); + return ret; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) +{ + _MFCLIB *pCTX; + int ret; + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + struct pollfd poll_events; + int poll_state; + +#ifdef CONFIG_MFC_FPS + framecount++; +#endif + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec1, NULL); +#endif + pCTX = (_MFCLIB *) openHandle; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLOUT | POLLERR; + poll_events.revents = 0; + + if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { + /* Queue the stream frame */ + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_dec.beingUsedIndex; + qbuf.m.planes = planes; + qbuf.length = 1; + qbuf.m.planes[0].bytesused = lengthBufFill; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = 1; + + /* wait for decoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLOUT) { /* POLLOUT */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret == 0) { + if (qbuf.flags & V4L2_BUF_FLAG_ERROR) + return MFC_RET_DEC_EXE_ERR; + break; + } + } else if (poll_events.revents & POLLERR) { /* POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + return MFC_RET_DEC_EXE_ERR; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + return MFC_RET_DEC_EXE_ERR; + } + } else if (0 > poll_state) { + return MFC_RET_DEC_EXE_ERR; + } + } while (0 == poll_state); + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + + if (ret != 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return MFC_RET_OK; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + + if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + + } else if(pCTX->v4l2_dec.bBeingFinalized == 0) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + + /* Queue the stream frame */ + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_dec.beingUsedIndex; + qbuf.m.planes = planes; + qbuf.length = 1; + qbuf.m.planes[0].bytesused = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + + pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + /* FIXME + wait for decoding */ + do { + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + } while (ret != 0); + + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + } else { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + + if (qbuf.m.planes[0].bytesused == 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return MFC_RET_OK; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + } + + pCTX->decOutInfo.disp_pic_frame_type = (qbuf.flags & (0x7 << 3)); + + switch (pCTX->decOutInfo.disp_pic_frame_type) { + case V4L2_BUF_FLAG_KEYFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 1; + break; + case V4L2_BUF_FLAG_PFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 2; + break; + case V4L2_BUF_FLAG_BFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 3; + break; + default: + pCTX->decOutInfo.disp_pic_frame_type = 0; + break; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec2, NULL); + if (mDec2.tv_usec-mDec1.tv_usec > 30000) over30ms++; +#endif + return MFC_RET_OK; +} + +#if 0 +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill) +{ + _MFCLIB *pCTX; + int ret; + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + +#ifdef CONFIG_MFC_FPS + framecount++; +#endif + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { + /* Queue the stream frame */ + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_dec.beingUsedIndex; + qbuf.m.planes = planes; + qbuf.length = 1; + qbuf.m.planes[0].bytesused = lengthBufFill; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + } else if(pCTX->v4l2_dec.bBeingFinalized == 0) { + /* Queue the stream frame */ + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_dec.beingUsedIndex; + qbuf.m.planes = planes; + qbuf.length = 1; + qbuf.m.planes[0].bytesused = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + } + + if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0)) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; + + return MFC_RET_OK; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + int ret; + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + struct pollfd poll_events; + int poll_state; + + pCTX = (_MFCLIB *) openHandle; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLOUT | POLLERR; + poll_events.revents = 0; + + if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = 1; + + /* wait for decoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLOUT) { /* POLLOUT */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret == 0) { + if (qbuf.flags & V4L2_BUF_FLAG_ERROR) + return MFC_GETOUTBUF_STATUS_NULL; + break; + } + } else if (poll_events.revents & POLLERR) { /* POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + return MFC_GETOUTBUF_STATUS_NULL; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + return MFC_GETOUTBUF_STATUS_NULL; + } + } else if (0 > poll_state) { + return MFC_GETOUTBUF_STATUS_NULL; + } + } while (0 == poll_state); + + pCTX->v4l2_dec.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + + if (ret != 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return SsbSipMfcDecGetOutBuf(pCTX, output_info);; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + + if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + + pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + + /* wait for decoding */ + do { + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + } while (ret != 0); + + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + } else { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = MFC_DEC_NUM_PLANES; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + + if (qbuf.m.planes[0].bytesused == 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return SsbSipMfcDecGetOutBuf(pCTX, output_info);; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; + } + + pCTX->decOutInfo.disp_pic_frame_type = (qbuf.flags & (0x7 << 3)); + + switch (pCTX->decOutInfo.disp_pic_frame_type) { + case V4L2_BUF_FLAG_KEYFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 1; + break; + case V4L2_BUF_FLAG_PFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 2; + break; + case V4L2_BUF_FLAG_BFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 3; + break; + default: + pCTX->decOutInfo.disp_pic_frame_type = 0; + break; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + + return SsbSipMfcDecGetOutBuf(pCTX, output_info); +} +#endif + +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) +{ + _MFCLIB *pCTX; + int i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return NULL; + } + + if ((inputBufferSize < 0) || (inputBufferSize > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] inputBufferSize = %d is invalid",__func__, inputBufferSize); + return NULL; + } + + pCTX = (_MFCLIB *) openHandle; + + for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) + if (BUF_DEQUEUED == pCTX->v4l2_dec.mfc_src_buf_flags[i]) + break; + + if (i == MFC_DEC_NUM_SRC_BUFS) { + LOGV("[%s] No buffer is available.",__func__); + return NULL; + } else { + pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_dec.mfc_src_bufs[i]; + /* Set the buffer flag as Enqueued for NB_mode_process*/ + /* FIXME: Check this assignment in case of using New API ExeNb() */ + pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + + return (void *)pCTX->virStrmBuf; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) +{ + _MFCLIB *pCTX; + int i; + + LOGV("[%s] Enter",__func__); + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + for (i = 0; iv4l2_dec.mfc_src_bufs[i] == virInBuf) + break; + + if (i == MFC_DEC_NUM_SRC_BUFS) { + LOGE("[%s] Can not use the buffer",__func__); + return MFC_RET_INVALID_PARAM; + } else { + pCTX->virStrmBuf = (unsigned int)virInBuf; + pCTX->v4l2_dec.beingUsedIndex = i; + pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + LOGV("[%s] Exit idx %d",__func__,pCTX->v4l2_dec.beingUsedIndex); + return MFC_RET_OK; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + int ret; + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_GETOUTBUF_DISPLAY_END; + } + + pCTX = (_MFCLIB *) openHandle; + + output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; + output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; + + output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; + output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; + + output_info->img_width = pCTX->decOutInfo.img_width; + output_info->img_height= pCTX->decOutInfo.img_height; + + output_info->buf_width = pCTX->decOutInfo.buf_width; + output_info->buf_height= pCTX->decOutInfo.buf_height; + + output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + + output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; + + switch (pCTX->displayStatus) { + case MFC_GETOUTBUF_DISPLAY_ONLY: + case MFC_GETOUTBUF_DISPLAY_DECODING: + case MFC_GETOUTBUF_DISPLAY_END: +#ifdef SSB_UMP + ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.YVirAddr, &output_info->y_cookie); + if (ret) { + LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \ + output_info->y_cookie, pCTX->decOutInfo.YVirAddr); + } + + ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.CVirAddr, &output_info->c_cookie); + if (ret) { + LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \ + output_info->c_cookie, pCTX->decOutInfo.CVirAddr); + } + break; +#endif + case MFC_GETOUTBUF_DECODING_ONLY: + case MFC_GETOUTBUF_CHANGE_RESOL: + break; + default: + return MFC_GETOUTBUF_DISPLAY_END; + } + + return pCTX->displayStatus; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret, i; + + _MFCLIB *pCTX; + struct mfc_dec_fimv1_info *fimv1_res; + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + struct v4l2_control ctrl; + + enum v4l2_buf_type type; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((value == NULL) && (MFC_DEC_SETCONF_IS_LAST_FRAME !=conf_type)) { + LOGE("[%s] value is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + /* First, process non-ioctl calling settings */ + switch (conf_type) { + case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: + pCTX->dec_numextradpb = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: /* be set before calling SsbSipMfcDecInit */ + fimv1_res = (struct mfc_dec_fimv1_info *)value; + LOGI("fimv1->width = %d\n", fimv1_res->width); + LOGI("fimv1->height = %d\n", fimv1_res->height); + pCTX->fimv1_res.width = (int)(fimv1_res->width); + pCTX->fimv1_res.height = (int)(fimv1_res->height); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_IS_LAST_FRAME: + if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; + return MFC_RET_OK; + } else { + return MFC_RET_FAIL; + } + + case MFC_DEC_SETCONF_DPB_FLUSH: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { + memset(&qbuf, 0, sizeof(qbuf)); + + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = i; + qbuf.m.planes = planes; + qbuf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + } + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + return MFC_RET_OK; + default: + /* Others will be processed next */ + break; + } + + /* Process ioctl calling settings */ + memset(&ctrl, 0, sizeof(ctrl)); + switch (conf_type) { + case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */ + ctrl.id = V4L2_CID_CODEC_DISPLAY_DELAY; + ctrl.value = *((unsigned int *) value); + break; + + case MFC_DEC_SETCONF_CRC_ENABLE: + ctrl.id = V4L2_CID_CODEC_CRC_ENABLE; + ctrl.value = 1; + break; + + case MFC_DEC_SETCONF_SLICE_ENABLE: + ctrl.id = V4L2_CID_CODEC_SLICE_INTERFACE; + ctrl.value = 1; + break; + + case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */ + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = *((unsigned int*)value); + break; + + case MFC_DEC_SETCONF_POST_ENABLE: + ctrl.id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE; + ctrl.value = *((unsigned int*)value); + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); + return MFC_RET_DEC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + + SSBSIP_MFC_IMG_RESOLUTION *img_resolution; + int ret; + SSBSIP_MFC_CRC_DATA *crc_data; + SSBSIP_MFC_CROP_INFORMATION *crop_information; + struct v4l2_control ctrl; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + switch (conf_type) { + case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: + img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; + img_resolution->width = pCTX->decOutInfo.img_width; + img_resolution->height = pCTX->decOutInfo.img_height; + img_resolution->buf_width = pCTX->decOutInfo.buf_width; + img_resolution->buf_height = pCTX->decOutInfo.buf_height; + break; + + case MFC_DEC_GETCONF_CRC_DATA: + crc_data = (SSBSIP_MFC_CRC_DATA *) value; + + ctrl.id = V4L2_CID_CODEC_CRC_DATA_LUMA; + ctrl.value = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + crc_data->luma0 = ctrl.value; + + ctrl.id = V4L2_CID_CODEC_CRC_DATA_CHROMA; + ctrl.value = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + crc_data->chroma0 = ctrl.value; + + LOGI("[%s] crc_data->luma0=%d",__func__,ctrl.value); + LOGI("[%s] crc_data->chroma0=%d",__func__,ctrl.value); + break; + + case MFC_DEC_GETCONF_FRAME_TAG: + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + printf("Error to do g_ctrl.\n"); + } + *((unsigned int *)value) = ctrl.value; + break; + + case MFC_DEC_GETCONF_CROP_INFO: + crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; + crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c new file mode 100644 index 0000000..45888c6 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c @@ -0,0 +1,1206 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "videodev2.h" + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "MFC_ENC_APP" +#include + +#define POLL_ENC_WAIT_TIMEOUT 25 + +#ifndef true +#define true (1) +#endif + +#ifndef false +#define false (0) +#endif + +#define MAX_STREAM_SIZE (2*1024*1024) + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; +static int mfc_dev_node = 7; + +static void getMFCName(char *devicename, int size) +{ + snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); +} + +void SsbSipMfcEncSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcEncOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX; + + char mfc_dev_name[64]; + + int ret; + struct v4l2_capability cap; + + getMFCName(mfc_dev_name, 64); + LOGI("[%s] dev name is %s\n",__func__,mfc_dev_name); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("[%s] MFC device node not exists",__func__); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NONBLOCK, 0); + if (hMFCOpen < 0) { + LOGE("[%s] Failed to open MFC device",__func__); + return NULL; + } + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("[%s] malloc failed.",__func__); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + pCTX->hMFC = hMFCOpen; + + memset(&cap, 0, sizeof(cap)); + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("[%s] Device does not support capture",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOGE("[%s] Device does not support output",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("[%s] Device does not support streaming",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + pCTX->v4l2_enc.bRunning = 0; + /* physical address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 1; + + pCTX->cacheablebuffer = NO_CACHE; + + return (void *)pCTX; +} + +void *SsbSipMfcEncOpenExt(void *value) +{ + _MFCLIB *pCTX; + + pCTX = SsbSipMfcEncOpen(); + if (pCTX == NULL) + return NULL; + + if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { + pCTX->cacheablebuffer = NO_CACHE; + /* physical address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 1; + LOGI("[%s] non cacheable buffer",__func__); + } + else { + pCTX->cacheablebuffer = CACHE; + /* vitual address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 0; + LOGI("[%s] cacheable buffer",__func__); + } + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) +{ + _MFCLIB *pCTX; + int i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (!pCTX->v4l2_enc.bInputPhyVir) { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); + } + } + + for (i = 0; i < pCTX->v4l2_enc.mfc_num_dst_bufs; i++) + munmap(pCTX->v4l2_enc.mfc_dst_bufs[i], pCTX->v4l2_enc.mfc_dst_bufs_len); + + pCTX->inter_buff_status = MFC_USE_NONE; + + close(pCTX->hMFC); + + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) +{ + int ret, i, j,index; + _MFCLIB *pCTX; + + enum v4l2_buf_type type; + struct v4l2_format fmt; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + + struct v4l2_buffer buf; + struct v4l2_requestbuffers reqbuf; + + struct v4l2_control ctrl; + + struct pollfd poll_events; + int poll_state; + + struct v4l2_ext_control ext_ctrl_mpeg4[27]; + struct v4l2_ext_control ext_ctrl_h263[19]; + struct v4l2_ext_control ext_ctrl[44]; + struct v4l2_ext_controls ext_ctrls; + + SSBSIP_MFC_ENC_H264_PARAM *h264_arg; + SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; + SSBSIP_MFC_ENC_H263_PARAM *h263_arg; + + if (openHandle == NULL) { + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; + if (mpeg4_arg->codecType == MPEG4_ENC) { + pCTX->codecType= MPEG4_ENC; + pCTX->width = mpeg4_arg->SourceWidth; + pCTX->height = mpeg4_arg->SourceHeight; + pCTX->framemap = mpeg4_arg->FrameMap; + } else { + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; + if (h263_arg->codecType == H263_ENC) { + pCTX->codecType = H263_ENC; + pCTX->width = h263_arg->SourceWidth; + pCTX->height = h263_arg->SourceHeight; + pCTX->framemap = h263_arg->FrameMap; + } else { + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; + if (h264_arg->codecType == H264_ENC) { + pCTX->codecType = H264_ENC; + pCTX->width = h264_arg->SourceWidth; + pCTX->height = h264_arg->SourceHeight; + pCTX->framemap = h264_arg->FrameMap; + } else { + LOGE("[%s] Undefined codec type \n",__func__); + ret = MFC_RET_INVALID_PARAM; + goto error_case1; + } + } + } + + switch (pCTX->codecType) { + case MPEG4_ENC: + ext_ctrl_mpeg4[0].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE; + ext_ctrl_mpeg4[0].value = mpeg4_arg->ProfileIDC; + ext_ctrl_mpeg4[1].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL; + ext_ctrl_mpeg4[1].value = mpeg4_arg->LevelIDC; + ext_ctrl_mpeg4[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl_mpeg4[2].value = mpeg4_arg->IDRPeriod; + ext_ctrl_mpeg4[3].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL; + ext_ctrl_mpeg4[3].value = mpeg4_arg->DisableQpelME; + + ext_ctrl_mpeg4[4].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl_mpeg4[4].value = mpeg4_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ + if (mpeg4_arg->SliceMode == 0) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = 1; /* default */ + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = 1900; /* default */ + } else if (mpeg4_arg->SliceMode == 1) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = mpeg4_arg->SliceArgument; + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = 1900; /* default */ + } else if (mpeg4_arg->SliceMode == 3) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = 1; /* default */ + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = mpeg4_arg->SliceArgument; + } + /* + It should be set using mpeg4_arg->NumberBFrames after being handled by appl. + */ + ext_ctrl_mpeg4[7].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES; + ext_ctrl_mpeg4[7].value = mpeg4_arg->NumberBFrames; + ext_ctrl_mpeg4[8].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl_mpeg4[8].value = mpeg4_arg->RandomIntraMBRefresh; + + ext_ctrl_mpeg4[9].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl_mpeg4[9].value = mpeg4_arg->PadControlOn; + ext_ctrl_mpeg4[10].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl_mpeg4[10].value = mpeg4_arg->LumaPadVal; + ext_ctrl_mpeg4[11].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl_mpeg4[11].value = mpeg4_arg->CbPadVal; + ext_ctrl_mpeg4[12].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl_mpeg4[12].value = mpeg4_arg->CrPadVal; + + ext_ctrl_mpeg4[13].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl_mpeg4[13].value = mpeg4_arg->EnableFRMRateControl; + ext_ctrl_mpeg4[14].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES; + ext_ctrl_mpeg4[14].value = mpeg4_arg->TimeIncreamentRes; + ext_ctrl_mpeg4[15].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA; + ext_ctrl_mpeg4[15].value = mpeg4_arg->VopTimeIncreament; + ext_ctrl_mpeg4[16].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + ext_ctrl_mpeg4[16].value = mpeg4_arg->Bitrate; + + ext_ctrl_mpeg4[17].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP; + ext_ctrl_mpeg4[17].value = mpeg4_arg->FrameQp; + ext_ctrl_mpeg4[18].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP; + ext_ctrl_mpeg4[18].value = mpeg4_arg->FrameQp_P; + ext_ctrl_mpeg4[19].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP; + ext_ctrl_mpeg4[19].value = mpeg4_arg->FrameQp_B; + + ext_ctrl_mpeg4[20].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP; + ext_ctrl_mpeg4[20].value = mpeg4_arg->QSCodeMax; + ext_ctrl_mpeg4[21].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP; + ext_ctrl_mpeg4[21].value = mpeg4_arg->QSCodeMin; + ext_ctrl_mpeg4[22].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl_mpeg4[22].value = mpeg4_arg->CBRPeriodRf; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl_mpeg4[24].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl_mpeg4[24].value = 0; + + ext_ctrl_mpeg4[25].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl_mpeg4[25].value = 0; + + ext_ctrl_mpeg4[26].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; + ext_ctrl_mpeg4[26].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + break; + + case H263_ENC: + ext_ctrl_h263[0].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl_h263[0].value = h263_arg->IDRPeriod; + + ext_ctrl_h263[1].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl_h263[1].value = h263_arg->SliceMode; /* 0: one, Check is needed if h264 support multi-slice */ + + ext_ctrl_h263[2].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl_h263[2].value = h263_arg->RandomIntraMBRefresh; + + ext_ctrl_h263[3].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl_h263[3].value = h263_arg->PadControlOn; + ext_ctrl_h263[4].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl_h263[4].value = h263_arg->LumaPadVal; + ext_ctrl_h263[5].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl_h263[5].value = h263_arg->CbPadVal; + ext_ctrl_h263[6].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl_h263[6].value = h263_arg->CrPadVal; + + ext_ctrl_h263[7].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl_h263[7].value = h263_arg->EnableFRMRateControl; + + ext_ctrl_h263[8].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE; + ext_ctrl_h263[8].value = h263_arg->FrameRate; + + ext_ctrl_h263[9].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + ext_ctrl_h263[9].value = h263_arg->Bitrate; + + ext_ctrl_h263[10].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP; + ext_ctrl_h263[10].value = h263_arg->FrameQp; + ext_ctrl_h263[11].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP; + ext_ctrl_h263[11].value = h263_arg->FrameQp_P; + + ext_ctrl_h263[12].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP; + ext_ctrl_h263[12].value = h263_arg->QSCodeMax; + ext_ctrl_h263[13].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP; + ext_ctrl_h263[13].value = h263_arg->QSCodeMin; + ext_ctrl_h263[14].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl_h263[14].value = h263_arg->CBRPeriodRf; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE== pCTX->enc_frameskip) { + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl_h263[16].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl_h263[16].value = 0; + + ext_ctrl_h263[17].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl_h263[17].value = 0; + + ext_ctrl_h263[18].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; + ext_ctrl_h263[18].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + break; + + case H264_ENC: + ext_ctrl[0].id = V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE; + ext_ctrl[0].value = h264_arg->ProfileIDC; + ext_ctrl[1].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL; + ext_ctrl[1].value = h264_arg->LevelIDC; + ext_ctrl[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl[2].value = h264_arg->IDRPeriod; + ext_ctrl[3].id = V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC; + ext_ctrl[3].value = h264_arg->NumberReferenceFrames; + ext_ctrl[4].id = V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P; + ext_ctrl[4].value = h264_arg->NumberRefForPframes; + ext_ctrl[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl[5].value = h264_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ + if (h264_arg->SliceMode == 0) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = 1; /* default */ + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = 1900; /* default */ + } else if (h264_arg->SliceMode == 1) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = h264_arg->SliceArgument; + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = 1900; /* default */ + } else if (h264_arg->SliceMode == 3) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = 1; /* default */ + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = h264_arg->SliceArgument; + } + /* + It should be set using h264_arg->NumberBFrames after being handled by appl. + */ + ext_ctrl[8].id = V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES; + ext_ctrl[8].value = h264_arg->NumberBFrames; + ext_ctrl[9].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE; + ext_ctrl[9].value = h264_arg->LoopFilterDisable; + ext_ctrl[10].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA; + ext_ctrl[10].value = h264_arg->LoopFilterAlphaC0Offset; + ext_ctrl[11].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA; + ext_ctrl[11].value = h264_arg->LoopFilterBetaOffset; + ext_ctrl[12].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE; + ext_ctrl[12].value = h264_arg->SymbolMode; + ext_ctrl[13].id = V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE; + ext_ctrl[13].value = h264_arg->PictureInterlace; + ext_ctrl[14].id = V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM; + ext_ctrl[14].value = h264_arg->Transform8x8Mode; + ext_ctrl[15].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl[15].value = h264_arg->RandomIntraMBRefresh; + ext_ctrl[16].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl[16].value = h264_arg->PadControlOn; + ext_ctrl[17].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl[17].value = h264_arg->LumaPadVal; + ext_ctrl[18].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl[18].value = h264_arg->CbPadVal; + ext_ctrl[19].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl[19].value = h264_arg->CrPadVal; + ext_ctrl[20].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl[20].value = h264_arg->EnableFRMRateControl; + ext_ctrl[21].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE; + ext_ctrl[21].value = h264_arg->EnableMBRateControl; + ext_ctrl[22].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE; + ext_ctrl[22].value = h264_arg->FrameRate; + ext_ctrl[23].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + /* FIXME temporary fix */ + if (h264_arg->Bitrate) + ext_ctrl[23].value = h264_arg->Bitrate; + else + ext_ctrl[23].value = 1; /* just for testing Movi studio */ + ext_ctrl[24].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP; + ext_ctrl[24].value = h264_arg->FrameQp; + ext_ctrl[25].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP; + ext_ctrl[25].value = h264_arg->FrameQp_P; + ext_ctrl[26].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP; + ext_ctrl[26].value = h264_arg->FrameQp_B; + ext_ctrl[27].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP; + ext_ctrl[27].value = h264_arg->QSCodeMax; + ext_ctrl[28].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP; + ext_ctrl[28].value = h264_arg->QSCodeMin; + ext_ctrl[29].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl[29].value = h264_arg->CBRPeriodRf; + ext_ctrl[30].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK; + ext_ctrl[30].value = h264_arg->DarkDisable; + ext_ctrl[31].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH; + ext_ctrl[31].value = h264_arg->SmoothDisable; + ext_ctrl[32].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC; + ext_ctrl[32].value = h264_arg->StaticDisable; + ext_ctrl[33].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY; + ext_ctrl[33].value = h264_arg->ActivityDisable; + + /* doesn't have to be set */ + ext_ctrl[34].id = V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP; + ext_ctrl[34].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; + ext_ctrl[35].id = V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD; + ext_ctrl[35].value = 10; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE== pCTX->enc_frameskip) { + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl[37].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl[37].value = 0; + + ext_ctrl[38].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl[38].value = 0; /* 0: seperated header + 1: header + first frame */ + + ext_ctrl[39].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; + ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + + ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE; + ext_ctrl[40].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; + ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC; + ext_ctrl[41].value = 0; + ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH; + ext_ctrl[42].value = 0; + ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT; + ext_ctrl[43].value = 0; + + break; + + default: + LOGE("[%s] Undefined codec type",__func__); + ret = MFC_RET_INVALID_PARAM; + goto error_case1; + } + + ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC; + if (pCTX->codecType == MPEG4_ENC) { + ext_ctrls.count = 27; + ext_ctrls.controls = ext_ctrl_mpeg4; + } else if (pCTX->codecType == H264_ENC) { + ext_ctrls.count = 44; + ext_ctrls.controls = ext_ctrl; + } else if (pCTX->codecType == H263_ENC) { + ext_ctrls.count = 19; + ext_ctrls.controls = ext_ctrl_h263; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_S_EXT_CTRLS, &ext_ctrls); + if (ret != 0) { + LOGE("[%s] Failed to set extended controls",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + fmt.fmt.pix_mp.width = pCTX->width; + fmt.fmt.pix_mp.height = pCTX->height; + fmt.fmt.pix_mp.num_planes = 2; + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = Align(fmt.fmt.pix_mp.width, 128); + fmt.fmt.pix_mp.plane_fmt[1].bytesperline = Align(fmt.fmt.pix_mp.width, 128); + + if (NV12_TILE == pCTX->framemap) { + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 64x32 Tiles */ + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = + Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height, 32), 8192); /* tiled mode */ + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = + Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height >> 1, 32), 8192); /* tiled mode */ + } else { /* NV12_LINEAR (default) */ + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = + Align((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height), 2048); /* linear mode, 2K align */ + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = + Align((fmt.fmt.pix_mp.width * (fmt.fmt.pix_mp.height >> 1)), 2048); /* linear mode, 2K align */ + } + + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed on MFC output stream",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* capture (dst) */ + memset(&fmt, 0, sizeof(fmt)); + + switch (pCTX->codecType) { + case H264_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + break; + case MPEG4_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case H263_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; + break; + default: + LOGE("[%s] Codec has not been recognised",__func__); + return MFC_RET_ENC_INIT_FAIL; + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed on MFC output stream",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* cacheable buffer */ + ctrl.id = V4L2_CID_CACHEABLE; + if (pCTX->cacheablebuffer == NO_CACHE) + ctrl.value = 0; + else + ctrl.value = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* Initialize streams for input */ + memset(&reqbuf, 0, sizeof(reqbuf)); + reqbuf.count = MFC_ENC_NUM_SRC_BUFS; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (pCTX->v4l2_enc.bInputPhyVir) + reqbuf.memory = V4L2_MEMORY_USERPTR; + else + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] Reqbufs src ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + pCTX->v4l2_enc.mfc_num_src_bufs = reqbuf.count; + + if (!pCTX->v4l2_enc.bInputPhyVir) { + /* Then the buffers have to be queried and mmaped */ + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; ++i) { + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + buf.m.planes = planes; + buf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); + if (ret != 0) { + LOGE("[%s] Querybuf src ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_src_bufs_len[0] = buf.m.planes[0].length; + pCTX->v4l2_enc.mfc_src_bufs_len[1] = buf.m.planes[1].length; + + pCTX->v4l2_enc.mfc_src_phys[i][0] = buf.m.planes[0].cookie; + pCTX->v4l2_enc.mfc_src_phys[i][1] = buf.m.planes[1].cookie; + + pCTX->v4l2_enc.mfc_src_bufs[i][0] = + mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == MAP_FAILED) { + LOGE("[%s] Mmap on src buffer (0) failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_src_bufs[i][1] = + mmap(NULL, buf.m.planes[1].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); + if (pCTX->v4l2_enc.mfc_src_bufs[i][1] == MAP_FAILED) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + LOGE("[%s] Mmap on src buffer (1) failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + } + } else + LOGV("[%s] Camera Phys src buf %d",__func__,reqbuf.count); + + for (i = 0; iv4l2_enc.mfc_num_src_bufs; i++) + pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_DEQUEUED; + + pCTX->v4l2_enc.beingUsedIndex = 0; + + pCTX->sizeFrmBuf.luma = (unsigned int)(pCTX->width * pCTX->height); + pCTX->sizeFrmBuf.chroma = (unsigned int)((pCTX->width * pCTX->height) >> 1); + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + /* Initialize stream for output */ + memset(&reqbuf, 0, sizeof(reqbuf)); + reqbuf.count = MFC_ENC_MAX_DST_BUFS; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] Reqbufs dst ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_num_dst_bufs = reqbuf.count; + + for (i = 0; ihMFC, VIDIOC_QUERYBUF, &buf); + if (ret != 0) { + LOGE("[%s] Querybuf dst ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + pCTX->v4l2_enc.mfc_dst_bufs_len = buf.m.planes[0].length; + pCTX->v4l2_enc.mfc_dst_bufs[i] = + mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_enc.mfc_dst_bufs[i] == MAP_FAILED) { + LOGE("[%s] Mmap on dst buffer failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } + + pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, VIDIOC_STREAMON failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = 1; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLIN | POLLERR; + poll_events.revents = 0; + + /* wait for header encoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLIN) { /* POLLIN */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &buf); + if (ret == 0) + break; + } else if(poll_events.revents & POLLERR) { /*POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } else if(0 > poll_state) { + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } while (0 == poll_state); + + pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused; + pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[buf.index]; + + /* stream dequeued index */ + index = buf.index; + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = index; + buf.m.planes = planes; + buf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + LOGV("[%s] Strm out idx %d",__func__,index); + + return MFC_RET_OK; +error_case3: + for (j = 0; j < i; j++) + munmap(pCTX->v4l2_enc.mfc_dst_bufs[j], pCTX->v4l2_enc.mfc_dst_bufs_len); + + i = pCTX->v4l2_enc.mfc_num_src_bufs; +error_case2: + if (!pCTX->v4l2_enc.bInputPhyVir) { + for (j = 0; j < i; j++) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[j][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + munmap(pCTX->v4l2_enc.mfc_src_bufs[j][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); + } + } +error_case1: + return ret; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + int i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->v4l2_enc.bInputPhyVir) { + input_info->YPhyAddr = (void*)0; + input_info->CPhyAddr = (void*)0; + input_info->YVirAddr = (void*)0; + input_info->CVirAddr = (void*)0; + + if (NV12_TILE == pCTX->framemap) { + /* 4:2:0, 2 Planes, 64x32 Tiles */ + input_info->YSize = Align(Align(pCTX->width, 128) * Align(pCTX->height, 32), 8192); /* tiled mode */ + input_info->CSize = Align(Align(pCTX->width, 128) * Align(pCTX->height >> 1, 32), 8192); /* tiled mode */ + } else { /* NV12_LINEAR (default) */ + /* 4:2:0, 2 Planes, linear */ + input_info->YSize = Align(Align(pCTX->width, 16) * Align(pCTX->height, 16), 2048); /* width = 16B, height = 16B align */ + input_info->CSize = Align(Align(pCTX->width, 16) * Align(pCTX->height >> 1, 8), 2048); /* width = 16B, height = 8B align */ + } + } else { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) + if (BUF_DEQUEUED == pCTX->v4l2_enc.mfc_src_buf_flags[i]) + break; + + if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { + LOGV("[%s] No buffer is available.",__func__); + return MFC_RET_ENC_GET_INBUF_FAIL; + } else { + /* FIXME check this for correct physical address */ + input_info->YPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][0]; + input_info->CPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][1]; + input_info->YVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][0]; + input_info->CVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][1]; + input_info->YSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[0]; + input_info->CSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[1]; + + pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + } + LOGV("[%s] Input Buffer idx %d",__func__,i); + return MFC_RET_OK; +} + + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + int ret,i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + memset(&qbuf, 0, sizeof(qbuf)); + if (pCTX->v4l2_enc.bInputPhyVir) { + qbuf.memory = V4L2_MEMORY_USERPTR; + qbuf.index = pCTX->v4l2_enc.beingUsedIndex; + planes[0].m.userptr = (unsigned long)input_info->YPhyAddr; + planes[0].length = input_info->YSize; + planes[0].bytesused = input_info->YSize; + planes[1].m.userptr = (unsigned long)input_info->CPhyAddr; + planes[1].length = input_info->CSize; + planes[1].bytesused = input_info->CSize; + + /* FIXME, this is only for case of not using B frame, + Camera side should know which buffer is queued() refering to index of + MFC dqbuf() */ + pCTX->v4l2_enc.beingUsedIndex++; + pCTX->v4l2_enc.beingUsedIndex %= MFC_ENC_NUM_SRC_BUFS; + LOGV("[%s] Phy Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); + } else { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) + if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == input_info->YVirAddr) + break; + + if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { + LOGE("[%s] Can not use the buffer",__func__); + return MFC_RET_INVALID_PARAM; + } else { + pCTX->v4l2_enc.beingUsedIndex = i; + //pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_enc.beingUsedIndex; + planes[0].bytesused = pCTX->width * pCTX->height; + planes[1].bytesused = (pCTX->width * pCTX->height) >> 1; + LOGV("[%s] Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); + } + + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.m.planes = planes; + qbuf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_SET_INBUF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->v4l2_enc.bRunning == 0) { + pCTX->encodedHeaderSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; + output_info->dataSize = 0; + } else { + output_info->dataSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; + } + + output_info->headerSize = pCTX->encodedHeaderSize; + output_info->frameType = pCTX->encodedframeType; + output_info->StrmPhyAddr = (void *)0; + output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; + output_info->encodedYPhyAddr = (void*)0; + output_info->encodedCPhyAddr = (void*)0; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) +{ + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_ENC_SET_OUTBUF_FAIL; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) +{ + int ret; + int dequeued_index; + int loopcnt = 0; + _MFCLIB *pCTX; + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + enum v4l2_buf_type type; + + struct v4l2_control ctrl; + + struct pollfd poll_events; + int poll_state; + + LOGV("[%s] Enter \n",__func__); + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = pCTX->inframetag; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + if (pCTX->v4l2_enc.bRunning == 0) { + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->v4l2_enc.bRunning = 1; + } + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = 1; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLIN | POLLERR; + poll_events.revents = 0; + + /* wait for encoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLIN) { /* POLLIN */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret == 0) + break; + } else if (poll_events.revents & POLLERR) { /* POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + return MFC_RET_ENC_EXE_ERR; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + return MFC_RET_ENC_EXE_ERR; + } + } else if (0 > poll_state) { + LOGE("[%s] poll() Encoder POLL Timeout 0x%x\n",__func__, poll_events.revents); + return MFC_RET_ENC_EXE_ERR; + } + loopcnt++; + } while ((0 == poll_state) && (loopcnt < 5)); + + if (pCTX->v4l2_enc.bRunning != 0) { + pCTX->encodedframeType = (qbuf.flags & 0x18) >> 3; /* encoded frame type */ + + LOGV("[%s] encoded frame type = %d\n",__func__, pCTX->encodedframeType); + switch (pCTX->encodedframeType) { + case 1: + pCTX->encodedframeType = MFC_FRAME_TYPE_I_FRAME; + break; + case 2: + pCTX->encodedframeType = MFC_FRAME_TYPE_P_FRAME; + break; + case 4: + pCTX->encodedframeType = MFC_FRAME_TYPE_B_FRAME; + break; + default: + LOGE("[%s] VIDIOC_DQBUF failed, encoded frame type is wrong",__func__); + } + } + + dequeued_index = qbuf.index; + + if (qbuf.m.planes[0].bytesused > 0) { /* FIXME later */ + pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = qbuf.m.planes[0].bytesused; + } + + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->outframetagtop = ctrl.value; + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = dequeued_index; + qbuf.m.planes = planes; + qbuf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + if (pCTX->v4l2_enc.bRunning != 0) { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (pCTX->v4l2_enc.bInputPhyVir) + qbuf.memory = V4L2_MEMORY_USERPTR; + else + qbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + } + pCTX->v4l2_enc.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; + + /* Update context stream buffer address */ + pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[dequeued_index]; + LOGV("[%s] Strm out idx %d",__func__,dequeued_index); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + switch (conf_type) { + case MFC_ENC_SETCONF_FRAME_TAG: + pCTX->inframetag = *((unsigned int *)value); + return MFC_RET_OK; + + case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: + pCTX->enc_frameskip = *((int *)value); + return MFC_RET_OK; +#if 0 + case MFC_ENC_SETCONF_VUI_INFO: + vui_info = *((struct mfc_enc_vui_info *) value); + EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); + EncArg.args.set_config.in_config_value[1] = 0; + break; + + case MFC_ENC_SETCONF_HIER_P: + hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); + EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp); + EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp); + EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp); + break; + + case MFC_ENC_SETCONF_I_PERIOD: +#endif + default: + LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + + pCTX = (_MFCLIB *) openHandle; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + switch (conf_type) { + case MFC_ENC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->outframetagtop; + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} + diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h new file mode 100644 index 0000000..43e4ba0 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SSBSIP_MFC_API_H_ +#define _SSBSIP_MFC_API_H_ + +/*--------------------------------------------------------------------------------*/ +/* Definition */ +/*--------------------------------------------------------------------------------*/ +#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) +#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) + +#define SUPPORT_1080P 1 + +#if SUPPORT_1080P +#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ +#else +#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) +#endif + +#define SAMSUNG_MFC_DEV_NAME "/dev/video" + +#define SSBSIP_MFC_OK (1) +#define SSBSIP_MFC_FAIL (0) + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + H264_DEC, + VC1_DEC, /* VC1 advaced Profile decoding */ + MPEG4_DEC, + XVID_DEC, + MPEG1_DEC, + MPEG2_DEC, + H263_DEC, + VC1RCV_DEC, /* VC1 simple/main profile decoding */ + FIMV1_DEC, + FIMV2_DEC, + FIMV3_DEC, + FIMV4_DEC, + H264_ENC, + MPEG4_ENC, + H263_ENC, + UNKNOWN_TYPE +} SSBSIP_MFC_CODEC_TYPE; + +typedef enum { + DONT_CARE = 0, + I_FRAME = 1, + NOT_CODED = 2 +} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; + +typedef enum { + NV12_LINEAR = 0, + NV12_TILE +} SSBSIP_MFC_INSTRM_MODE_TYPE; + +typedef enum { + NO_CACHE = 0, + CACHE = 1 +} SSBIP_MFC_BUFFER_TYPE; + +typedef enum { + MFC_DEC_SETCONF_POST_ENABLE = 1, + MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, + MFC_DEC_SETCONF_DISPLAY_DELAY, + MFC_DEC_SETCONF_IS_LAST_FRAME, + MFC_DEC_SETCONF_SLICE_ENABLE, + MFC_DEC_SETCONF_CRC_ENABLE, + MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, + MFC_DEC_SETCONF_FRAME_TAG, + MFC_DEC_GETCONF_CRC_DATA, + MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, + MFC_DEC_GETCONF_CROP_INFO, + MFC_DEC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, + MFC_DEC_SETCONF_DPB_FLUSH, + MFC_DEC_SETCONF_PIXEL_CACHE, + MFC_DEC_GETCONF_WIDTH_HEIGHT +} SSBSIP_MFC_DEC_CONF; + +typedef enum { + MFC_ENC_SETCONF_FRAME_TYPE = 100, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + MFC_ENC_SETCONF_FRAME_TAG, + MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, + MFC_ENC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_ENC_SETCONF_VUI_INFO, + MFC_ENC_SETCONF_I_PERIOD, + MFC_ENC_SETCONF_HIER_P +} SSBSIP_MFC_ENC_CONF; + +typedef enum { + MFC_GETOUTBUF_STATUS_NULL = 0, + MFC_GETOUTBUF_DECODING_ONLY = 1, + MFC_GETOUTBUF_DISPLAY_DECODING, + MFC_GETOUTBUF_DISPLAY_ONLY, + MFC_GETOUTBUF_DISPLAY_END, + MFC_GETOUTBUF_CHANGE_RESOL +} SSBSIP_MFC_DEC_OUTBUF_STATUS; + +typedef enum { + MFC_FRAME_TYPE_NOT_CODED, + MFC_FRAME_TYPE_I_FRAME, + MFC_FRAME_TYPE_P_FRAME, + MFC_FRAME_TYPE_B_FRAME, + MFC_FRAME_TYPE_OTHERS +} SSBSIP_MFC_FRAME_TYPE; + +typedef enum { + MFC_RET_OK = 1, + MFC_RET_FAIL = -1000, + MFC_RET_OPEN_FAIL = -1001, + MFC_RET_CLOSE_FAIL = -1002, + + MFC_RET_DEC_INIT_FAIL = -2000, + MFC_RET_DEC_EXE_TIME_OUT = -2001, + MFC_RET_DEC_EXE_ERR = -2002, + MFC_RET_DEC_GET_INBUF_FAIL = -2003, + MFC_RET_DEC_SET_INBUF_FAIL = -2004, + MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, + MFC_RET_DEC_GET_CONF_FAIL = -2006, + MFC_RET_DEC_SET_CONF_FAIL = -2007, + + MFC_RET_ENC_INIT_FAIL = -3000, + MFC_RET_ENC_EXE_TIME_OUT = -3001, + MFC_RET_ENC_EXE_ERR = -3002, + MFC_RET_ENC_GET_INBUF_FAIL = -3003, + MFC_RET_ENC_SET_INBUF_FAIL = -3004, + MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, + MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, + MFC_RET_ENC_GET_CONF_FAIL = -3007, + MFC_RET_ENC_SET_CONF_FAIL = -3008, + + MFC_RET_INVALID_PARAM = -4000 +} SSBSIP_MFC_ERROR_CODE; + +typedef struct { + void *YPhyAddr; /* [OUT] physical address of Y */ + void *CPhyAddr; /* [OUT] physical address of CbCr */ + void *YVirAddr; /* [OUT] virtual address of Y */ + void *CVirAddr; /* [OUT] virtual address of CbCr */ + + int img_width; /* [OUT] width of real image */ + int img_height; /* [OUT] height of real image */ + int buf_width; /* [OUT] width aligned to 16 */ + int buf_height; /* [OUT] height alighed to 16 */ + + int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ + int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ + int consumedByte; /* [OUT] the number of byte consumed during decoding */ + int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ + int crop_top_offset; /* [OUT] crop information, top_offset */ + int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ + int crop_left_offset; /* [OUT] crop information, left_offset */ + int crop_right_offset; /* [OUT] crop information, right_offset */ + int disp_pic_frame_type; /* [OUT] display picture frame type information */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_DEC_OUTPUT_INFO; + +typedef struct { + void *YPhyAddr; /* [IN/OUT] physical address of Y */ + void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ + void *YVirAddr; /* [IN/OUT] virtual address of Y */ + void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ + int YSize; /* [IN/OUT] input size of Y data */ + int CSize; /* [IN/OUT] input size of CbCr data */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_INPUT_INFO; + +typedef struct { + unsigned int dataSize; /* [OUT] encoded data size(without header) */ + unsigned int headerSize; /* [OUT] encoded header size */ + unsigned int frameType; /* [OUT] frame type of encoded stream */ + void *StrmPhyAddr; /* [OUT] physical address of Y */ + void *StrmVirAddr; /* [OUT] virtual address of Y */ + void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ + void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ + + /* C210 UMP feature */ + unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ + unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ + unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_OUTPUT_INFO; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* H.264 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int NumberReferenceFrames; /* [IN] The number of reference pictures used */ + int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ + int LoopFilterDisable; /* [IN] disable the loop filter */ + int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ + int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ + int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ + int PictureInterlace; /* [IN] Enables the interlace mode */ + int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ + int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ + int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ + int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ + int StaticDisable; /* [IN] Disable adaptive rate control on static region */ + int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ +} SSBSIP_MFC_ENC_H264_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* MPEG4 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int TimeIncreamentRes; /* [IN] frame rate */ + int VopTimeIncreament; /* [IN] frame rate */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ +} SSBSIP_MFC_ENC_MPEG4_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* H.263 specific parameters */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ +} SSBSIP_MFC_ENC_H263_PARAM; + +typedef struct { + int width; + int height; + int buf_width; + int buf_height; +} SSBSIP_MFC_IMG_RESOLUTION; + +typedef struct { + int crop_top_offset; + int crop_bottom_offset; + int crop_left_offset; + int crop_right_offset; +} SSBSIP_MFC_CROP_INFORMATION; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------------*/ +/* Decoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcDecOpen(void); +void *SsbSipMfcDecOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); +//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); +//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); +#else +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); +#endif + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); + +/*--------------------------------------------------------------------------------*/ +/* Encoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcEncOpen(void); +void *SsbSipMfcEncOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h new file mode 100644 index 0000000..b8e96ab --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_ERRNO_H +#define __MFC_ERRNO_H __FILE__ + +enum mfc_ret_code { + MFC_OK = 1, + MFC_FAIL = -1000, + MFC_OPEN_FAIL = -1001, + MFC_CLOSE_FAIL = -1002, + + MFC_DEC_INIT_FAIL = -2000, + MFC_DEC_EXE_TIME_OUT = -2001, + MFC_DEC_EXE_ERR = -2002, + MFC_DEC_GET_INBUF_FAIL = 2003, + MFC_DEC_SET_INBUF_FAIL = 2004, + MFC_DEC_GET_OUTBUF_FAIL = -2005, + MFC_DEC_GET_CONF_FAIL = -2006, + MFC_DEC_SET_CONF_FAIL = -2007, + + MFC_ENC_INIT_FAIL = -3000, + MFC_ENC_EXE_TIME_OUT = -3001, + MFC_ENC_EXE_ERR = -3002, + MFC_ENC_GET_INBUF_FAIL = -3003, + MFC_ENC_SET_INBUF_FAIL = -3004, + MFC_ENC_GET_OUTBUF_FAIL = -3005, + MFC_ENC_SET_OUTBUF_FAIL = -3006, + MFC_ENC_GET_CONF_FAIL = -3007, + MFC_ENC_SET_CONF_FAIL = -3008, + + MFC_STATE_INVALID = -4000, + MFC_DEC_HEADER_FAIL = -4001, + MFC_DEC_INIT_BUF_FAIL = -4002, + MFC_ENC_HEADER_FAIL = -5000, + MFC_ENC_PARAM_FAIL = -5001, + MFC_FRM_BUF_SIZE_FAIL = -6000, + MFC_FW_LOAD_FAIL = -6001, + MFC_FW_INIT_FAIL = -6002, + MFC_INST_NUM_EXCEEDED_FAIL = -6003, + MFC_MEM_ALLOC_FAIL = -6004, + MFC_MEM_INVALID_ADDR_FAIL = -6005, + MFC_MEM_MAPPING_FAIL = -6006, + MFC_GET_CONF_FAIL = -6007, + MFC_SET_CONF_FAIL = -6008, + MFC_INVALID_PARAM_FAIL = -6009, + MFC_API_FAIL = -9000, + + MFC_CMD_FAIL = -1003, + MFC_SLEEP_FAIL = -1010, + MFC_WAKEUP_FAIL = -1020, + + MFC_CLK_ON_FAIL = -1030, + MFC_CLK_OFF_FAIL = -1030, + MFC_PWR_ON_FAIL = -1040, + MFC_PWR_OFF_FAIL = -1041, +}; + +#endif /* __MFC_ERRNO_H */ diff --git a/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h new file mode 100644 index 0000000..b7289c4 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h @@ -0,0 +1,541 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_INTERFACE_H +#define __MFC_INTERFACE_H + +#include "mfc_errno.h" +#include "SsbSipMfcApi.h" + +#define IOCTL_MFC_DEC_INIT (0x00800001) +#define IOCTL_MFC_ENC_INIT (0x00800002) +#define IOCTL_MFC_DEC_EXE (0x00800003) +#define IOCTL_MFC_ENC_EXE (0x00800004) + +#define IOCTL_MFC_GET_IN_BUF (0x00800010) +#define IOCTL_MFC_FREE_BUF (0x00800011) +#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) +#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) +#define IOCTL_MFC_SET_IN_BUF (0x00800018) + +#define IOCTL_MFC_SET_CONFIG (0x00800101) +#define IOCTL_MFC_GET_CONFIG (0x00800102) + +#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) + +/* MFC H/W support maximum 32 extra DPB. */ +#define MFC_MAX_EXTRA_DPB 5 +#define MFC_MAX_DISP_DELAY 0xF + +#define MFC_LIB_VER_MAJOR 1 +#define MFC_LIB_VER_MINOR 00 + +#define BUF_L_UNIT (1024) +#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) + +#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ +#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */ +#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */ + +#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ +#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */ +#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */ + +enum inst_type { + DECODER = 0x1, + ENCODER = 0x2, +}; + +typedef enum { + MFC_UNPACKED_PB = 0, + MFC_PACKED_PB = 1 +} mfc_packed_mode; + +typedef enum { + SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0, + SSBSIP_MFC_LAST_FRAME_RECEIVED = 1, + SSBSIP_MFC_LAST_FRAME_PROCESSED = 2 +} SSBSIP_MFC_LAST_FRAME_STATUS; + +typedef enum { + MFC_USE_NONE = 0x0000, + MFC_USE_YUV_BUFF = 0x0001, + MFC_USE_STRM_BUFF = 0x0010, + MFC_USE_SRC_STREAMON = 0x0100, + MFC_USE_DST_STREAMON = 0x1000, +} s3c_mfc_interbuff_status; + +typedef struct { + int luma0; /* per frame (or top field) */ + int chroma0; /* per frame (or top field) */ + int luma1; /* per frame (or bottom field) */ + int chroma1; /* per frame (or bottom field) */ +} SSBSIP_MFC_CRC_DATA; + +struct mfc_strm_ref_buf_arg { + unsigned int strm_ref_y; + unsigned int mv_ref_yc; +}; + +struct mfc_frame_buf_arg { + unsigned int luma; + unsigned int chroma; +}; + +struct mfc_enc_init_common_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + + int in_width; /* [IN] width of YUV420 frame to be encoded */ + int in_height; /* [IN] height of YUV420 frame to be encoded */ + + int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ + int in_vop_quant; /* [IN] VOP quant */ + int in_vop_quant_p; /* [IN] VOP quant for P frame */ + + /* [IN] RC enable */ + /* [IN] RC enable (0:disable, 1:frame level RC) */ + int in_rc_fr_en; + int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ + + int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ + int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ + int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ + + /* [IN] Multi-slice mode (0:single, 1:multiple) */ + int in_ms_mode; + /* [IN] Multi-slice size (in num. of mb or byte) */ + int in_ms_arg; + + int in_mb_refresh; /* [IN] Macroblock refresh */ + + /* [IN] Enable (1) / Disable (0) padding with the specified values */ + int in_pad_ctrl_on; + + /* [IN] pad value if pad_ctrl_on is Enable */ + int in_y_pad_val; + int in_cb_pad_val; + int in_cr_pad_val; + + /* linear or tiled */ + int in_frame_map; + + unsigned int in_pixelcache; + + unsigned int in_mapped_addr; + struct mfc_strm_ref_buf_arg out_u_addr; + struct mfc_strm_ref_buf_arg out_p_addr; + struct mfc_strm_ref_buf_arg out_buf_size; + unsigned int out_header_size; +}; + +struct mfc_enc_init_h263_arg { + int in_rc_framerate; /* [IN] RC parameter (framerate) */ +}; + +struct mfc_enc_init_mpeg4_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ + int in_quart_pixel; + + int in_TimeIncreamentRes; /* [IN] VOP time resolution */ + int in_VopTimeIncreament; /* [IN] Frame delta */ +}; + +struct mfc_enc_init_h264_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] interlace mode(0:progressive, 1:interlace) */ + int in_interlace_mode; + + /* [IN] reference number */ + int in_reference_num; + /* [IN] reference number of P frame */ + int in_ref_num_p; + + int in_rc_framerate; /* [IN] RC parameter (framerate) */ + int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ + /* [IN] MB level rate control dark region adaptive feature */ + int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control smooth region adaptive feature */ + int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control static region adaptive feature */ + int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control activity region adaptive feature */ + int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ + + /* [IN] disable deblocking filter idc */ + int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ + /* [IN] slice alpha c0 offset of deblocking filter */ + int in_deblock_alpha_c0; + /* [IN] slice beta offset of deblocking filter */ + int in_deblock_beta; + + /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ + int in_symbolmode; + /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ + int in_transform8x8_mode; + + /* [IN] Inter weighted parameter for mode decision */ + int in_md_interweight_pps; + /* [IN] Intra weighted parameter for mode decision */ + int in_md_intraweight_pps; +}; + +struct mfc_enc_init_arg { + struct mfc_enc_init_common_arg cmn; + union { + struct mfc_enc_init_h264_arg h264; + struct mfc_enc_init_mpeg4_arg mpeg4; + struct mfc_enc_init_h263_arg h263; + } codec; +}; + +struct mfc_enc_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ + unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ + unsigned int in_frametag; /* [IN] unique frame ID */ + + unsigned int out_frame_type; /* [OUT] frame type */ + int out_encoded_size; /* [OUT] Length of Encoded video stream */ + unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */ + unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */ + unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */ + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif +}; + +struct mfc_dec_init_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] address of stream buffer */ + int in_strm_size; /* [IN] filled size in stream buffer */ + int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ + + unsigned int in_crc; /* [IN] */ + unsigned int in_pixelcache; /* [IN] */ + unsigned int in_slice; /* [IN] */ + unsigned int in_numextradpb; /* [IN] */ + + unsigned int in_mapped_addr; + + int out_frm_width; /* [OUT] width of YUV420 frame */ + int out_frm_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ + + int out_crop_right_offset; /* [OUT] crop information for h264 */ + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; +}; + +struct mfc_dec_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] the physical address of STRM_BUF */ + /* [IN] Size of video stream filled in STRM_BUF */ + int in_strm_size; + /* [IN] the address of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_buf; + /* [IN] size of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_size; + /* [IN] Unique frame ID eg. application specific timestamp */ + unsigned int in_frametag; + /* [IN] immdiate Display for seek,thumbnail and one frame */ + int in_immediately_disp; + /* [OUT] the physical address of display buf */ + int out_display_Y_addr; + /* [OUT] the physical address of display buf */ + int out_display_C_addr; + int out_display_status; + /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_top; + /* [OUT] unique frame ID of bottom field */ + unsigned int out_frametag_bottom; + int out_pic_time_top; + int out_pic_time_bottom; + int out_consumed_byte; + + int out_crop_right_offset; + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; + + /* in new driver, each buffer offset must be return to the user */ + int out_y_offset; + int out_c_offset; + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif + int out_img_width; /* [OUT] width of YUV420 frame */ + int out_img_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ +}; + +struct mfc_get_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to get for the configurable parameter. */ + /* Maximum four integer values can be obtained; */ + int out_config_value[4]; +}; + +struct mfc_set_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to be set for the configurable parameter. */ + /* Maximum four integer values can be set. */ + int in_config_value[4]; +}; + +struct mfc_get_real_addr_arg { + unsigned int key; + unsigned int addr; +}; + +struct mfc_buf_alloc_arg { + enum inst_type type; + int size; + /* + unsigned int mapped; + */ + unsigned int align; + + unsigned int addr; + /* + unsigned int phys; + */ +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + /* FIMXE: invalid secure id == -1 */ + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_buf_free_arg { + unsigned int addr; +}; + +/* RMVME */ +struct mfc_mem_alloc_arg { + enum inst_type type; + int buff_size; + SSBIP_MFC_BUFFER_TYPE buf_cache_type; + unsigned int mapped_addr; +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_mem_free_arg { + unsigned int key; +}; +/* RMVME */ + +union mfc_args { + /* + struct mfc_enc_init_arg enc_init; + + struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; + struct mfc_enc_init_mpeg4_arg enc_init_h263; + struct mfc_enc_init_h264_arg enc_init_h264; + */ + struct mfc_enc_init_arg enc_init; + struct mfc_enc_exe_arg enc_exe; + + struct mfc_dec_init_arg dec_init; + struct mfc_dec_exe_arg dec_exe; + + struct mfc_get_config_arg get_config; + struct mfc_set_config_arg set_config; + + struct mfc_buf_alloc_arg buf_alloc; + struct mfc_buf_free_arg buf_free; + struct mfc_get_real_addr_arg real_addr; + + /* RMVME */ + struct mfc_mem_alloc_arg mem_alloc; + struct mfc_mem_free_arg mem_free; + /* RMVME */ +}; + +struct mfc_common_args { + enum mfc_ret_code ret_code; /* [OUT] error code */ + union mfc_args args; +}; + +struct mfc_enc_vui_info { + int aspect_ratio_idc; +}; + +struct mfc_dec_fimv1_info { + int width; + int height; +}; + +struct mfc_enc_hier_p_qp { + int t0_frame_qp; + int t2_frame_qp; + int t3_frame_qp; +}; + +enum BUF_STATUS { + BUF_ENQUEUED, + BUF_DEQUEUED +}; + +struct mfc_dec_v4l2 { + char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */ + char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */ + char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */ + + unsigned int mfc_src_bufs_len; /* needed for munmap */ + unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */ + + unsigned int mfc_num_src_bufs; /* the number of source buffers */ + unsigned int mfc_num_dst_bufs; /* the number of destination buffers */ + + char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS]; + int bBeingFinalized; + int allocIndex; + int beingUsedIndex; +}; + +struct mfc_enc_v4l2 { + char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; + char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; + char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS]; + + unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES]; + unsigned int mfc_dst_bufs_len; + + unsigned int mfc_num_src_bufs; + unsigned int mfc_num_dst_bufs; + + unsigned int mfc_dst_bufs_bytes_used_len; + char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS]; + int bRunning; + int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */ + int beingUsedIndex; +}; + +typedef struct { + int magic; + int hMFC; + int hVMEM; + int width; + int height; + int sizeStrmBuf; + struct mfc_frame_buf_arg sizeFrmBuf; + int displayStatus; + int inter_buff_status; + unsigned int virFreeStrmAddr; + unsigned int phyStrmBuf; + unsigned int virStrmBuf; + unsigned int virMvRefYC; + struct mfc_frame_buf_arg phyFrmBuf; + struct mfc_frame_buf_arg virFrmBuf; + unsigned int mapped_addr; + unsigned int mapped_size; + struct mfc_common_args MfcArg; + SSBSIP_MFC_CODEC_TYPE codecType; + SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; + unsigned int inframetag; + unsigned int outframetagtop; + unsigned int outframetagbottom; + unsigned int immediatelydisp; + unsigned int encodedHeaderSize; + int encodedDataSize; + unsigned int encodedframeType; + struct mfc_frame_buf_arg encodedphyFrmBuf; + + unsigned int dec_crc; + unsigned int dec_pixelcache; + unsigned int dec_slice; + unsigned int dec_numextradpb; + + int input_cookie; + int input_secure_id; + int input_size; + + /* to support non-blocking mode */ + unsigned int encode_cnt; + + struct mfc_dec_v4l2 v4l2_dec; + struct mfc_enc_v4l2 v4l2_enc; + + int enc_frameskip; + int cacheablebuffer; + struct mfc_dec_fimv1_info fimv1_res; + SSBSIP_MFC_LAST_FRAME_STATUS lastframe; + SSBSIP_MFC_INSTRM_MODE_TYPE framemap; +} _MFCLIB; + +#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) +#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) + +#define SSBSIP_MFC_FAIL (0) + +#endif /* __MFC_INTERFACE_H */ diff --git a/exynos/multimedia/codecs/video/exynos5/Android.mk b/exynos/multimedia/codecs/video/exynos5/Android.mk new file mode 100644 index 0000000..949c637 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_VIDEO_PATH :=$(LOCAL_PATH) + +include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/Android.mk b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/Android.mk new file mode 100644 index 0000000..f7ae2ec --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + include/mfc_errno.h \ + include/mfc_interface.h \ + include/SsbSipMfcApi.h + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + dec/src/SsbSipMfcDecAPI.c \ + enc/src/SsbSipMfcEncAPI.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + device/samsung/$(TARGET_BOARD_PLATFORM)/include + +LOCAL_MODULE := libsecmfcapi + +LOCAL_PRELINK_MODULE := false + +ifeq ($(BOARD_USES_MFC_FPS),true) +LOCAL_CFLAGS := -DCONFIG_MFC_FPS +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := liblog + +#ifeq ($(BOARD_USE_V4L2_ION),true) +#LOCAL_CFLAGS += -DUSE_ION +#LOCAL_SHARED_LIBRARIES += libion +#endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c new file mode 100644 index 0000000..cfb5dcc --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c @@ -0,0 +1,1669 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "videodev2.h" + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" +#ifdef USE_ION +#include "ion.h" +#endif + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "MFC_DEC_APP" +#include + +#ifdef CONFIG_MFC_FPS +#include +#endif + +/*#define CRC_ENABLE +#define SLICE_MODE_ENABLE */ +#define POLL_DEC_WAIT_TIMEOUT 25 + +#define USR_DATA_START_CODE (0x000001B2) +#define VOP_START_CODE (0x000001B6) +#define MP4_START_CODE (0x000001) + +#ifdef CONFIG_MFC_FPS +unsigned int framecount, over30ms; +struct timeval mTS1, mTS2, mDec1, mDec2; +#endif + +#define DEFAULT_NUMBER_OF_EXTRA_DPB 5 +#define CLEAR(x) memset (&(x), 0, sizeof(x)) + +enum { + NV12MT_FMT = 0, + NV12M_FMT, + NV21M_FMT, +}; + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; +static int mfc_dev_node = 6; + +int read_header_data(void *openHandle); +int init_mfc_output_stream(void *openHandle); +int isBreak_loop(void *openHandle); + +int v4l2_mfc_querycap(int fd) +{ + struct v4l2_capability cap; + int ret; + + CLEAR(cap); + + ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYCAP failed", __func__); + return ret; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("[%s] Device does not support capture", __func__); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOGE("[%s] Device does not support output", __func__); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("[%s] Device does not support streaming", __func__); + return -1; + } + + return 0; +} + +int v4l2_mfc_s_fmt(int fd, enum v4l2_buf_type type, + int pixelformat, unsigned int sizeimage, int width, int height) +{ + int ret; + struct v4l2_format fmt; + + CLEAR(fmt); + + fmt.type = type; + + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + switch (pixelformat) { + case H264_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + break; + case MPEG4_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case H263_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; + break; + case XVID_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_XVID; + break; + case MPEG2_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG12; + break; + case FIMV1_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV1; + fmt.fmt.pix_mp.width = width; + fmt.fmt.pix_mp.height = height; + break; + case FIMV2_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV2; + break; + case FIMV3_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV3; + break; + case FIMV4_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV4; + break; + case VC1_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1; + break; + case VC1RCV_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1_RCV; + break; + case VP8_DEC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VP8; + break; + default: + LOGE("[%s] Does NOT support the codec type (%d)", __func__, pixelformat); + return -1; + } + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage; + } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + switch (pixelformat) { + case NV12MT_FMT: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; + break; + case NV12M_FMT: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; + break; + case NV21M_FMT: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV21M; + break; + default: + LOGE("[%s] Does NOT support the pixel format (%d)", __func__, pixelformat); + return -1; + } + } else { + LOGE("[%s] Wrong buffer type", __func__); + return -1; + } + + ret = ioctl(fd, VIDIOC_S_FMT, &fmt); + + return ret; +} + +int v4l2_mfc_reqbufs(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_cnt) +{ + struct v4l2_requestbuffers reqbuf; + int ret; + + CLEAR(reqbuf); + + reqbuf.type = type; + reqbuf.memory = memory; + reqbuf.count = *buf_cnt; + + ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf); + *buf_cnt = reqbuf.count; + + return ret; +} + +int v4l2_mfc_querybuf(int fd, struct v4l2_buffer *buf, enum v4l2_buf_type type, + enum v4l2_memory memory, int index, struct v4l2_plane *planes) +{ + int length = -1, ret; + + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + length = 1; + else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + length = 2; + + CLEAR(*buf); + buf->type = type; + buf->memory = memory; + buf->index = index; + buf->m.planes = planes; + buf->length = length; + + ret = ioctl(fd, VIDIOC_QUERYBUF, buf); + + return ret; +} + +int v4l2_mfc_streamon(int fd, enum v4l2_buf_type type) +{ + int ret; + + ret = ioctl(fd, VIDIOC_STREAMON, &type); + + return ret; +} + +int v4l2_mfc_streamoff(int fd, enum v4l2_buf_type type) +{ + int ret; + + ret = ioctl(fd, VIDIOC_STREAMOFF, &type); + + return ret; +} + +int v4l2_mfc_s_ctrl(int fd, int id, int value) +{ + struct v4l2_control ctrl; + int ret; + + CLEAR(ctrl); + ctrl.id = id; + ctrl.value = value; + + ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); + + return ret; +} + +int v4l2_mfc_g_ctrl(int fd, int id, int *value) +{ + struct v4l2_control ctrl; + int ret; + + CLEAR(ctrl); + ctrl.id = id; + + ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); + *value = ctrl.value; + + return ret; +} + +int v4l2_mfc_qbuf(int fd, struct v4l2_buffer *qbuf, enum v4l2_buf_type type, + enum v4l2_memory memory, int index, + struct v4l2_plane *planes, int frame_length) +{ + int ret, length = 0; + + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + CLEAR(*qbuf); + length = 1; + } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + length = 2; + } + + qbuf->type = type; + qbuf->memory = memory; + qbuf->index = index; + qbuf->m.planes = planes; + qbuf->length = length; + qbuf->m.planes[0].bytesused = frame_length; + + ret = ioctl(fd, VIDIOC_QBUF, qbuf); + + return ret; +} + +int v4l2_mfc_dqbuf(int fd, struct v4l2_buffer *dqbuf, enum v4l2_buf_type type, + enum v4l2_memory memory) +{ + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + int ret, length = 0; + + CLEAR(*dqbuf); + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + length = 1; + else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + length = 2; + + dqbuf->type = type; + dqbuf->memory = memory; + dqbuf->m.planes = planes; + dqbuf->length = length; + + ret = ioctl(fd, VIDIOC_DQBUF, dqbuf); + + return ret; +} + +int v4l2_mfc_g_fmt(int fd, struct v4l2_format *fmt, enum v4l2_buf_type type) +{ + int ret; + + CLEAR(*fmt); + fmt->type = type; + ret = ioctl(fd, VIDIOC_G_FMT, fmt); + + return ret; +} + +int v4l2_mfc_g_crop(int fd, struct v4l2_crop *crop, enum v4l2_buf_type type) +{ + int ret; + + CLEAR(*crop); + crop->type = type; + ret = ioctl(fd, VIDIOC_G_CROP, crop); + + return ret; +} + +int v4l2_mfc_poll(int fd, int *revents, int timeout) +{ + struct pollfd poll_events; + int ret; + + poll_events.fd = fd; + poll_events.events = POLLOUT | POLLERR; + poll_events.revents = 0; + + ret = poll((struct pollfd*)&poll_events, 1, timeout); + *revents = poll_events.revents; + + return ret; +} + +static void getAByte(char *buff, int *code) +{ + int byte; + + *code = (*code << 8); + byte = (int)*buff; + byte &= 0xFF; + *code |= byte; +} + +static int isPBPacked(_MFCLIB *pCtx, int Frameleng) +{ + char *strmBuffer = NULL; + int startCode = 0xFFFFFFFF; + int leng_idx = 1; + + strmBuffer = (char*)pCtx->virStrmBuf; + + while (1) { + while (startCode != USR_DATA_START_CODE) { + if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { + LOGI("[%s] VOP START Found !!.....return",__func__); + LOGW("[%s] Non Packed PB",__func__); + return 0; + } + getAByte(strmBuffer, &startCode); + LOGV(">> StartCode = 0x%08x <<\n", startCode); + strmBuffer++; + leng_idx++; + } + LOGI("[%s] User Data Found !!",__func__); + + do { + if (*strmBuffer == 'p') { + LOGW("[%s] Packed PB",__func__); + return 1; + } + getAByte(strmBuffer, &startCode); + strmBuffer++; leng_idx++; + } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); + + if (leng_idx > Frameleng) + break; + } + + LOGW("[%s] Non Packed PB",__func__); + + return 0; +} + +static void getMFCName(char *devicename, int size) +{ + snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); +} + +void SsbSipMfcDecSetMFCNode(int devicenode) +{ + mfc_dev_node = devicenode; +} + +void SsbSipMfcDecSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcDecOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX; + char mfc_dev_name[64]; + + int ret; + int req_count; + unsigned int i, j; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); + +#ifdef CONFIG_MFC_FPS + framecount = 0; + over30ms = 0; + gettimeofday(&mTS1, NULL); +#endif + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("[%s] malloc failed.",__func__); + return NULL; + } + + memset(pCTX, 0, sizeof(_MFCLIB)); + + getMFCName(mfc_dev_name, 64); + LOGI("[%s] dev name is %s",__func__,mfc_dev_name); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("[%s] MFC device node not exists",__func__); + goto error_case1; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR|O_NONBLOCK, 0); + if (hMFCOpen < 0) { + LOGE("[%s] Failed to open MFC device",__func__); + goto error_case1; + } + + pCTX->hMFC = hMFCOpen; + + ret = v4l2_mfc_querycap(pCTX->hMFC); + if (ret != 0) { + LOGE("[%s] QUERYCAP failed", __func__); + goto error_case2; + } + + pCTX->inter_buff_status = MFC_USE_NONE; + ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + H264_DEC, MAX_DECODER_INPUT_BUFFER_SIZE, 0, 0); + if (ret != 0) { + LOGE("[%s] S_FMT failed",__func__); + goto error_case2; + } + + pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE; + + req_count = MFC_DEC_NUM_SRC_BUFS; + ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, &req_count); + if (ret != 0) { + LOGE("[%s] VIDIOC_REQBUFS failed",__func__); + goto error_case2; + } + + pCTX->v4l2_dec.mfc_num_src_bufs = req_count; + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; ++i) { + ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, i, planes); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYBUF failed",__func__); + goto error_case3; + } + + pCTX->v4l2_dec.mfc_src_bufs[i] = mmap(NULL, buf.m.planes[0].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_dec.mfc_src_bufs[i] == MAP_FAILED) { + LOGE("[%s] mmap failed (%d)",__func__,i); + goto error_case3; + } + } + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + /* set extra DPB size to 5 as default for optimal performce (heuristic method) */ + pCTX->dec_numextradpb = DEFAULT_NUMBER_OF_EXTRA_DPB; + + pCTX->v4l2_dec.bBeingFinalized = 0; + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED; + + pCTX->cacheablebuffer = NO_CACHE; + + for (i = 0; iv4l2_dec.mfc_src_buf_flags[i] = BUF_DEQUEUED; + + pCTX->v4l2_dec.beingUsedIndex = 0; + + return (void *) pCTX; + +error_case3: + for (j = 0; j < i; j++) + munmap(pCTX->v4l2_dec.mfc_src_bufs[j], pCTX->v4l2_dec.mfc_src_bufs_len); +error_case2: + close(pCTX->hMFC); +error_case1: + free(pCTX); + + return NULL; +} + +void *SsbSipMfcDecOpenExt(void *value) +{ + _MFCLIB *pCTX; + + pCTX = SsbSipMfcDecOpen(); + + if (pCTX == NULL) + return NULL; + + if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { + pCTX->cacheablebuffer = NO_CACHE; + LOGI("[%s] non cacheable buffer",__func__); + } else { + pCTX->cacheablebuffer = CACHE; + LOGI("[%s] cacheable buffer",__func__); + } + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) +{ + int ret, i; + _MFCLIB *pCTX; + +#ifdef CONFIG_MFC_FPS + LOGI(">>> MFC"); + gettimeofday(&mTS2, NULL); + LOGI(">>> time=%d", mTS2.tv_sec-mTS1.tv_sec); + LOGI(">>> framecount=%d", framecount); + LOGI(">>> 30ms over=%d", over30ms); +#endif + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { + ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + } + + if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { + ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); + } + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; i++) + munmap(pCTX->v4l2_dec.mfc_src_bufs[i], pCTX->v4l2_dec.mfc_src_bufs_len); + pCTX->inter_buff_status &= ~(MFC_USE_STRM_BUFF); + } + + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); + } + pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); + } + +#ifdef USE_ION + ion_client_destroy(pCTX->ion_fd); +#endif + close(pCTX->hMFC); + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) +{ + int packedPB = 0; + _MFCLIB *pCTX; + int ret; + + int width, height; + int ctrl_value; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + int poll_state, poll_revents; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + pCTX->codecType = codec_type; + + if ((pCTX->codecType == MPEG4_DEC) || (pCTX->codecType == XVID_DEC) || + (pCTX->codecType == FIMV1_DEC) || (pCTX->codecType == FIMV2_DEC) || + (pCTX->codecType == FIMV3_DEC) || (pCTX->codecType == FIMV4_DEC)) + packedPB = isPBPacked(pCTX, Frameleng); + + if (pCTX->codecType == FIMV1_DEC) { + width = pCTX->fimv1_res.width; + height = pCTX->fimv1_res.height; + } else { + width = 0; + height = 0; + } + ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, pCTX->codecType, + MAX_DECODER_INPUT_BUFFER_SIZE, width, height); + if (ret != 0) { + LOGE("[%s] S_FMT failed", __func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + /* Set default destination format as NV12MT */ + ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, NV12MT_FMT, + 0, width, height); + if (ret != 0) { + LOGE("[%s] S_FMT failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + /* PackedPB should be set after VIDIOC_S_FMT */ + if (packedPB) { + ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CODEC_PACKED_PB, 1); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed of PACKED_PB\n", __func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + } + + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, Frameleng); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + /* Processing the header requires running streamon + on OUTPUT queue */ + ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; + + ret = read_header_data(pCTX); + if (ret != 0) + goto error_case1; + + /* cacheable buffer */ + if (pCTX->cacheablebuffer == NO_CACHE) + ctrl_value = 0; + else + ctrl_value = 1; + + ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CACHEABLE, ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE", __func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + +#ifdef USE_ION + pCTX->ion_fd = ion_client_create(); + if (pCTX->ion_fd < 3) { + LOGE("[%s] Failed to get ion_fd : %d", __func__, pCTX->ion_fd); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } +#endif + + ret = init_mfc_output_stream(pCTX); + if (ret != 0) + goto error_case1; + + ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)", __func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + + do { + poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); + if (poll_state > 0) { + if (poll_revents & POLLOUT) { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); + if (ret == 0) + break; + } else if (poll_revents & POLLERR) { + LOGE("[%s] POLLERR\n", __func__); + return MFC_GETOUTBUF_STATUS_NULL; + } else { + LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); + return MFC_GETOUTBUF_STATUS_NULL; + } + } else if (poll_state < 0) { + return MFC_GETOUTBUF_STATUS_NULL; + } + } while (poll_state == 0); + + return MFC_RET_OK; + +error_case1: + SsbSipMfcDecClose(openHandle); + return ret; +} + +int read_header_data(void *openHandle) +{ + struct v4l2_format fmt; + struct v4l2_crop crop; + struct v4l2_pix_format_mplane pix_mp; + int ctrl_value; + int ret; + + _MFCLIB *pCTX; + pCTX = (_MFCLIB *) openHandle; + + ret = v4l2_mfc_g_fmt(pCTX->hMFC, &fmt, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_FMT failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case; + } + + pix_mp = fmt.fmt.pix_mp; + pCTX->decOutInfo.buf_width = pix_mp.plane_fmt[0].bytesperline; + pCTX->decOutInfo.buf_height = + pix_mp.plane_fmt[0].sizeimage / pix_mp.plane_fmt[0].bytesperline; + + pCTX->decOutInfo.img_width = pix_mp.width; + pCTX->decOutInfo.img_height = pix_mp.height; + + ret = v4l2_mfc_g_crop(pCTX->hMFC, &crop, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CROP failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case; + } + + pCTX->decOutInfo.crop_left_offset = crop.c.left; + pCTX->decOutInfo.crop_top_offset = crop.c.top; + pCTX->decOutInfo.crop_right_offset = + pix_mp.width - crop.c.width - crop.c.left; + pCTX->decOutInfo.crop_bottom_offset = + pix_mp.height - crop.c.height - crop.c.top; + + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_REQ_NUM_BUFS, &ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case; + } + + pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl_value + pCTX->dec_numextradpb; + + LOGV("[%s] Num of allocated buffers: %d\n",__func__, pCTX->v4l2_dec.mfc_num_dst_bufs); + + return 0; + +error_case: + return ret; + } + +/* Initialize output stream of MFC */ +int init_mfc_output_stream(void *openHandle) +{ + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + int ret; + int i, j; + _MFCLIB *pCTX; + pCTX = (_MFCLIB *) openHandle; + + ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_MEMORY_MMAP, (int *)&pCTX->v4l2_dec.mfc_num_dst_bufs); + if (ret != 0) { + LOGE("[%s] VIDIOC_REQBUFS failed (destination buffers)",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { + ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_MEMORY_MMAP, i, planes); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYBUF failed (destination buffers)",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case1; + } + + pCTX->v4l2_dec.mfc_dst_bufs_len[0] = buf.m.planes[0].length; + pCTX->v4l2_dec.mfc_dst_bufs_len[1] = buf.m.planes[1].length; + + pCTX->v4l2_dec.mfc_dst_phys[i][0] = buf.m.planes[0].cookie; + pCTX->v4l2_dec.mfc_dst_phys[i][1] = buf.m.planes[1].cookie; + +#ifdef USE_ION + pCTX->dst_ion_fd[i][0] = (int)buf.m.planes[0].share; + pCTX->dst_ion_fd[i][1] = (int)buf.m.planes[1].share; + + pCTX->v4l2_dec.mfc_dst_bufs[i][0] = + ion_map(pCTX->dst_ion_fd[i][0],pCTX->v4l2_dec.mfc_dst_bufs_len[0],0); + pCTX->v4l2_dec.mfc_dst_bufs[i][1] = + ion_map(pCTX->dst_ion_fd[i][1],pCTX->v4l2_dec.mfc_dst_bufs_len[1],0); + if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED || + pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) + goto error_case2; +#else + pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, buf.m.planes[0].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) { + LOGE("[%s] mmap failed (destination buffers (Y))",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_dec.mfc_dst_bufs[i][1] = mmap(NULL, buf.m.planes[1].length, + PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); + if (pCTX->v4l2_dec.mfc_dst_bufs[i][1] == MAP_FAILED) { + LOGE("[%s] mmap failed (destination buffers (UV))",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } +#endif + + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_MEMORY_MMAP, i, planes, 0); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_DEC_INIT_FAIL; + goto error_case2; + } + } + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + return 0; + +error_case2: + for (j = 0; j < i; j++) { + munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); + munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); + } +error_case1: + return ret; +} + +int resolution_change(void *openHandle) +{ + int i, ret; + int req_count; + _MFCLIB *pCTX; + pCTX = (_MFCLIB *) openHandle; + + ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (ret != 0) + goto error_case; + + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); + munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); + } + pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); + + req_count = 0; + ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_MEMORY_MMAP, &req_count); + if (ret != 0) + goto error_case; + + read_header_data(pCTX); + init_mfc_output_stream(pCTX); + + ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) + goto error_case; + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + + return 0; + +error_case: + return ret; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) +{ + _MFCLIB *pCTX; + int ret; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + int loop_count, ctrl_value; + + int poll_state; + int poll_revents; + +#ifdef CONFIG_MFC_FPS + framecount++; +#endif + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec1, NULL); +#endif + pCTX = (_MFCLIB *) openHandle; + + if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { + /* Queue the stream frame */ + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = 1; + + /* wait for decoding */ + do { + poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); + if (poll_state > 0) { + if (poll_revents & POLLOUT) { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); + if (ret == 0) { + if (buf.flags & V4L2_BUF_FLAG_ERROR) + return MFC_RET_DEC_EXE_ERR; + pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED; + break; + } + } else if (poll_revents & POLLERR) { + LOGE("[%s] POLLERR\n",__func__); + return MFC_RET_DEC_EXE_ERR; + } else { + LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); + return MFC_RET_DEC_EXE_ERR; + } + } else if (poll_state < 0) { + return MFC_RET_DEC_EXE_ERR; + } + + if (isBreak_loop(pCTX)) + break; + + } while(0 == poll_state); + + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return MFC_RET_OK; + } else { + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed", __func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + + switch (ctrl_value) { + case 0: + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + break; + case 1: + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; + break; + case 2: + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + break; + case 3: + pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL; + break; + } + } + + if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) { + resolution_change(pCTX); + } else { + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } + + if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + + } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ + + /* Queue the stream frame */ + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + + /* wait for decoding */ + loop_count = 0; + do { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) + usleep(1000); + loop_count++; + if (loop_count >= 1000) { + LOGE("[%s] Error in do-while loop",__func__); + break; + } + } while (ret != 0); + + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } else { + loop_count = 0; + do { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) + usleep(1000); + loop_count++; + if (loop_count >= 1000) { + LOGE("[%s] Error in do-while loop",__func__); + break; + } + } while (ret != 0); + + if (buf.m.planes[0].bytesused == 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return MFC_RET_OK; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } + + pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3)); + + switch (pCTX->decOutInfo.disp_pic_frame_type) { + case V4L2_BUF_FLAG_KEYFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 1; + break; + case V4L2_BUF_FLAG_PFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 2; + break; + case V4L2_BUF_FLAG_BFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 3; + break; + default: + pCTX->decOutInfo.disp_pic_frame_type = 0; + break; + } + + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, + buf.index, planes, 0); + +#ifdef CONFIG_MFC_FPS + gettimeofday(&mDec2, NULL); + if (mDec2.tv_usec-mDec1.tv_usec > 30000) over30ms++; +#endif + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill) +{ + _MFCLIB *pCTX; + int ret; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + +#ifdef CONFIG_MFC_FPS + framecount++; +#endif + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { + /* Queue the stream frame */ + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { + /* Queue the stream frame */ + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_DEC_EXE_ERR; + } + } + + if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0)) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; + + return MFC_RET_OK; +} + +int isBreak_loop(void *openHandle) +{ + _MFCLIB *pCTX; + pCTX = (_MFCLIB *) openHandle; + int ctrl_value; + int ret = 0; + + if (pCTX->displayStatus == MFC_GETOUTBUF_DISPLAY_ONLY) + return 1; + + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CHECK_STATE, &ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed", __func__); + return 0; + } + + if (ctrl_value == MFCSTATE_DEC_RES_DETECT) { + LOGV("[%s] Resolution Change detect",__func__); + return 1; + } else if (ctrl_value == MFCSTATE_DEC_TERMINATING) { + LOGV("[%s] Decoding Finish!!!",__func__); + return 1; + } + + return 0; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + int ret; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + int loop_count, ctrl_value; + + int poll_state; + int poll_revents; + + pCTX = (_MFCLIB *) openHandle; + + if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { + /* wait for decoding */ + do { + poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); + if (poll_state > 0) { + if (poll_revents & POLLOUT) { + buf.m.planes = planes; + buf.length = 1; + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); + if (ret == 0) { + if (buf.flags & V4L2_BUF_FLAG_ERROR) + return MFC_GETOUTBUF_STATUS_NULL; + pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED; + break; + } + } else if (poll_revents & POLLERR) { + LOGE("[%s] POLLERR\n",__func__); + return MFC_GETOUTBUF_STATUS_NULL; + } else { + LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); + return MFC_GETOUTBUF_STATUS_NULL; + } + } else if (poll_state < 0) { + return MFC_GETOUTBUF_STATUS_NULL; + } + + if (isBreak_loop(pCTX)) + break; + + } while (poll_state == 0); + + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return SsbSipMfcDecGetOutBuf(pCTX, output_info);; + } else { + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed", __func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + + switch (ctrl_value) { + case 0: + pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; + break; + case 1: + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; + break; + case 2: + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + break; + case 3: + pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL; + break; + } + } + + if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) { + resolution_change(pCTX); + } else { + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } + + if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; + pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ + + /* wait for decoding */ + loop_count = 0; + do { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) + usleep(1000); + loop_count++; + if (loop_count >= 1000) { + LOGE("[%s] Error in do-while loop",__func__); + break; + } + } while (ret != 0); + + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } else { + loop_count = 0; + do { + ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (ret != 0) + usleep(1000); + loop_count++; + if (loop_count >= 1000) { + LOGE("[%s] Error in do-while loop",__func__); + break; + } + } while (ret != 0); + + if (buf.m.planes[0].bytesused == 0) { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; + pCTX->decOutInfo.disp_pic_frame_type = -1; + return SsbSipMfcDecGetOutBuf(pCTX, output_info);; + } else { + pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; + } + + pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; + pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; + + pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; + pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; + } + + pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3)); + + switch (pCTX->decOutInfo.disp_pic_frame_type) { + case V4L2_BUF_FLAG_KEYFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 1; + break; + case V4L2_BUF_FLAG_PFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 2; + break; + case V4L2_BUF_FLAG_BFRAME: + pCTX->decOutInfo.disp_pic_frame_type = 3; + break; + default: + pCTX->decOutInfo.disp_pic_frame_type = 0; + break; + } + + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, + buf.index, planes, 0); + + return SsbSipMfcDecGetOutBuf(pCTX, output_info); +} + +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) +{ + _MFCLIB *pCTX; + int i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return NULL; + } + + if ((inputBufferSize < 0) || (inputBufferSize > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("[%s] inputBufferSize = %d is invalid",__func__, inputBufferSize); + return NULL; + } + + pCTX = (_MFCLIB *) openHandle; + + for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) + if (BUF_DEQUEUED == pCTX->v4l2_dec.mfc_src_buf_flags[i]) + break; + + if (i == MFC_DEC_NUM_SRC_BUFS) { + LOGV("[%s] No buffer is available.",__func__); + return NULL; + } else { + pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_dec.mfc_src_bufs[i]; + pCTX->v4l2_dec.beingUsedIndex = i; + /* Set the buffer flag as Enqueued for NB_mode_process*/ + /* FIXME: Check this assignment in case of using New API ExeNb() */ + pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + + return (void *)pCTX->virStrmBuf; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) +{ + _MFCLIB *pCTX; + int i; + + LOGV("[%s] Enter",__func__); + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) { + if (pCTX->v4l2_dec.mfc_src_bufs[i] == virInBuf) + break; + } + + if (i == MFC_DEC_NUM_SRC_BUFS) { + LOGE("[%s] Can not use the buffer",__func__); + return MFC_RET_INVALID_PARAM; + } else { + pCTX->virStrmBuf = (unsigned int)virInBuf; + pCTX->v4l2_dec.beingUsedIndex = i; + pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + LOGV("[%s] Exit idx %d",__func__,pCTX->v4l2_dec.beingUsedIndex); + return MFC_RET_OK; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_GETOUTBUF_DISPLAY_END; + } + + pCTX = (_MFCLIB *) openHandle; + + output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; + output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; + + output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; + output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; + + output_info->img_width = pCTX->decOutInfo.img_width; + output_info->img_height= pCTX->decOutInfo.img_height; + + output_info->buf_width = pCTX->decOutInfo.buf_width; + output_info->buf_height= pCTX->decOutInfo.buf_height; + + output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + + output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; + + switch (pCTX->displayStatus) { + case MFC_GETOUTBUF_DISPLAY_ONLY: + case MFC_GETOUTBUF_DISPLAY_DECODING: + case MFC_GETOUTBUF_DISPLAY_END: + case MFC_GETOUTBUF_DECODING_ONLY: + case MFC_GETOUTBUF_CHANGE_RESOL: + break; + default: + return MFC_GETOUTBUF_DISPLAY_END; + } + + return pCTX->displayStatus; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret, i; + + _MFCLIB *pCTX; + struct mfc_dec_fimv1_info *fimv1_res; + + struct v4l2_buffer buf; + struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; + + int id, ctrl_value; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if ((value == NULL) && (MFC_DEC_SETCONF_IS_LAST_FRAME !=conf_type)) { + LOGE("[%s] value is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + /* First, process non-ioctl calling settings */ + switch (conf_type) { + case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: + pCTX->dec_numextradpb = *((unsigned int *) value); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: /* be set before calling SsbSipMfcDecInit */ + fimv1_res = (struct mfc_dec_fimv1_info *)value; + LOGI("fimv1->width = %d\n", fimv1_res->width); + LOGI("fimv1->height = %d\n", fimv1_res->height); + pCTX->fimv1_res.width = (int)(fimv1_res->width); + pCTX->fimv1_res.height = (int)(fimv1_res->height); + return MFC_RET_OK; + + case MFC_DEC_SETCONF_IS_LAST_FRAME: + if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { + pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; + return MFC_RET_OK; + } else { + return MFC_RET_FAIL; + } + + case MFC_DEC_SETCONF_DPB_FLUSH: + ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + + for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { + ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_MEMORY_MMAP, i, planes, 0); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + } + + ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); + return MFC_RET_DEC_SET_CONF_FAIL; + } + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + return MFC_RET_OK; + default: + /* Others will be processed next */ + break; + } + + /* Process ioctl calling settings */ + switch (conf_type) { + case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */ + id = V4L2_CID_CODEC_DISPLAY_DELAY; + ctrl_value = *((unsigned int *) value); + break; + + case MFC_DEC_SETCONF_CRC_ENABLE: + id = V4L2_CID_CODEC_CRC_ENABLE; + ctrl_value = 1; + break; + + case MFC_DEC_SETCONF_SLICE_ENABLE: + id = V4L2_CID_CODEC_SLICE_INTERFACE; + ctrl_value = 1; + break; + + case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */ + id = V4L2_CID_CODEC_FRAME_TAG; + ctrl_value = *((unsigned int*)value); + break; + + case MFC_DEC_SETCONF_POST_ENABLE: + id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE; + ctrl_value = *((unsigned int*)value); + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + ret = v4l2_mfc_s_ctrl(pCTX->hMFC, id, ctrl_value); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); + return MFC_RET_DEC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + + SSBSIP_MFC_IMG_RESOLUTION *img_resolution; + int ret; + SSBSIP_MFC_CRC_DATA *crc_data; + SSBSIP_MFC_CROP_INFORMATION *crop_information; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + switch (conf_type) { + case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: + img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; + img_resolution->width = pCTX->decOutInfo.img_width; + img_resolution->height = pCTX->decOutInfo.img_height; + img_resolution->buf_width = pCTX->decOutInfo.buf_width; + img_resolution->buf_height = pCTX->decOutInfo.buf_height; + break; + + case MFC_DEC_GETCONF_FRAME_TAG: + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_FRAME_TAG, (int*)value); + if (ret != 0) + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG", __func__); + break; + + case MFC_DEC_GETCONF_CRC_DATA: + crc_data = (SSBSIP_MFC_CRC_DATA *) value; + + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_LUMA, &crc_data->luma0); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + + ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_CHROMA, &crc_data->chroma0); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__); + return MFC_RET_DEC_GET_CONF_FAIL; + } + LOGI("[%s] crc_data->luma0=0x%x\n", __func__, crc_data->luma0); + LOGI("[%s] crc_data->chroma0=0x%x\n", __func__, crc_data->chroma0); + break; + + case MFC_DEC_GETCONF_CROP_INFO: + crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; + crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; + crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c new file mode 100644 index 0000000..a4a841f --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c @@ -0,0 +1,1318 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "videodev2.h" + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "MFC_ENC_APP" +#include + +#define POLL_ENC_WAIT_TIMEOUT 25 + +#ifndef true +#define true (1) +#endif + +#ifndef false +#define false (0) +#endif + +#define MAX_STREAM_SIZE (2*1024*1024) + +static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; +static int mfc_dev_node = 7; + +static void getMFCName(char *devicename, int size) +{ + snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); +} + +void SsbSipMfcEncSetMFCName(char *devicename) +{ + mfc_dev_name = devicename; +} + +void *SsbSipMfcEncOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX; + + char mfc_dev_name[64]; + + int ret; + struct v4l2_capability cap; + + LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); + getMFCName(mfc_dev_name, 64); + LOGI("[%s] dev name is %s\n",__func__,mfc_dev_name); + + if (access(mfc_dev_name, F_OK) != 0) { + LOGE("[%s] MFC device node not exists",__func__); + return NULL; + } + + hMFCOpen = open(mfc_dev_name, O_RDWR | O_NONBLOCK, 0); + if (hMFCOpen < 0) { + LOGE("[%s] Failed to open MFC device",__func__); + return NULL; + } + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("[%s] malloc failed.",__func__); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + pCTX->hMFC = hMFCOpen; + + memset(&cap, 0, sizeof(cap)); + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); + if (ret != 0) { + LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("[%s] Device does not support capture",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOGE("[%s] Device does not support output",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("[%s] Device does not support streaming",__func__); + close(pCTX->hMFC); + free(pCTX); + return NULL; + } + + pCTX->v4l2_enc.bRunning = 0; + /* physical address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 1; + + pCTX->cacheablebuffer = NO_CACHE; + + return (void *)pCTX; +} + +void *SsbSipMfcEncOpenExt(void *value) +{ + _MFCLIB *pCTX; + + pCTX = SsbSipMfcEncOpen(); + if (pCTX == NULL) + return NULL; + + if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { + pCTX->cacheablebuffer = NO_CACHE; + /* physical address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 1; + LOGI("[%s] non cacheable buffer",__func__); + } + else { + pCTX->cacheablebuffer = CACHE; + /* vitual address is used for Input source */ + pCTX->v4l2_enc.bInputPhyVir = 0; + LOGI("[%s] cacheable buffer",__func__); + } + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) +{ + _MFCLIB *pCTX; + int ret, i; + + enum v4l2_buf_type type; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); + } + + if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); + return MFC_RET_CLOSE_FAIL; + } + pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); + } + + if (!pCTX->v4l2_enc.bInputPhyVir) { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); + } + } + + for (i = 0; i < pCTX->v4l2_enc.mfc_num_dst_bufs; i++) + munmap(pCTX->v4l2_enc.mfc_dst_bufs[i], pCTX->v4l2_enc.mfc_dst_bufs_len); + + pCTX->inter_buff_status = MFC_USE_NONE; + + close(pCTX->hMFC); + + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) +{ + int ret, i, j,index; + _MFCLIB *pCTX; + + enum v4l2_buf_type type; + struct v4l2_format fmt; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + + struct v4l2_buffer buf; + struct v4l2_requestbuffers reqbuf; + + struct v4l2_control ctrl; + + struct pollfd poll_events; + int poll_state; + + struct v4l2_ext_control ext_ctrl_mpeg4[28]; + struct v4l2_ext_control ext_ctrl_h263[20]; + struct v4l2_ext_control ext_ctrl[48]; + struct v4l2_ext_controls ext_ctrls; + + SSBSIP_MFC_ENC_H264_PARAM *h264_arg; + SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; + SSBSIP_MFC_ENC_H263_PARAM *h263_arg; + + if (openHandle == NULL) { + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; + if (mpeg4_arg->codecType == MPEG4_ENC) { + pCTX->codecType= MPEG4_ENC; + pCTX->width = mpeg4_arg->SourceWidth; + pCTX->height = mpeg4_arg->SourceHeight; + pCTX->framemap = mpeg4_arg->FrameMap; + } else { + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; + if (h263_arg->codecType == H263_ENC) { + pCTX->codecType = H263_ENC; + pCTX->width = h263_arg->SourceWidth; + pCTX->height = h263_arg->SourceHeight; + pCTX->framemap = h263_arg->FrameMap; + } else { + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; + if (h264_arg->codecType == H264_ENC) { + pCTX->codecType = H264_ENC; + pCTX->width = h264_arg->SourceWidth; + pCTX->height = h264_arg->SourceHeight; + pCTX->framemap = h264_arg->FrameMap; + } else { + LOGE("[%s] Undefined codec type \n",__func__); + ret = MFC_RET_INVALID_PARAM; + goto error_case1; + } + } + } + + switch (pCTX->codecType) { + case MPEG4_ENC: + ext_ctrl_mpeg4[0].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE; + ext_ctrl_mpeg4[0].value = mpeg4_arg->ProfileIDC; + ext_ctrl_mpeg4[1].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL; + ext_ctrl_mpeg4[1].value = mpeg4_arg->LevelIDC; + ext_ctrl_mpeg4[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl_mpeg4[2].value = mpeg4_arg->IDRPeriod; + ext_ctrl_mpeg4[3].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL; + ext_ctrl_mpeg4[3].value = mpeg4_arg->DisableQpelME; + + ext_ctrl_mpeg4[4].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl_mpeg4[4].value = mpeg4_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ + if (mpeg4_arg->SliceMode == 0) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = 1; /* default */ + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */ + } else if (mpeg4_arg->SliceMode == 1) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = mpeg4_arg->SliceArgument; + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */ + } else if (mpeg4_arg->SliceMode == 3) { + ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl_mpeg4[5].value = 1; /* default */ + ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl_mpeg4[6].value = mpeg4_arg->SliceArgument; + } + /* + It should be set using mpeg4_arg->NumberBFrames after being handled by appl. + */ + ext_ctrl_mpeg4[7].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES; + ext_ctrl_mpeg4[7].value = mpeg4_arg->NumberBFrames; + ext_ctrl_mpeg4[8].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl_mpeg4[8].value = mpeg4_arg->RandomIntraMBRefresh; + + ext_ctrl_mpeg4[9].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl_mpeg4[9].value = mpeg4_arg->PadControlOn; + ext_ctrl_mpeg4[10].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl_mpeg4[10].value = mpeg4_arg->LumaPadVal; + ext_ctrl_mpeg4[11].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl_mpeg4[11].value = mpeg4_arg->CbPadVal; + ext_ctrl_mpeg4[12].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl_mpeg4[12].value = mpeg4_arg->CrPadVal; + + ext_ctrl_mpeg4[13].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl_mpeg4[13].value = mpeg4_arg->EnableFRMRateControl; + ext_ctrl_mpeg4[14].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES; + ext_ctrl_mpeg4[14].value = mpeg4_arg->TimeIncreamentRes; + ext_ctrl_mpeg4[15].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA; + ext_ctrl_mpeg4[15].value = mpeg4_arg->VopTimeIncreament; + ext_ctrl_mpeg4[16].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + ext_ctrl_mpeg4[16].value = mpeg4_arg->Bitrate; + + ext_ctrl_mpeg4[17].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP; + ext_ctrl_mpeg4[17].value = mpeg4_arg->FrameQp; + ext_ctrl_mpeg4[18].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP; + ext_ctrl_mpeg4[18].value = mpeg4_arg->FrameQp_P; + ext_ctrl_mpeg4[19].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP; + ext_ctrl_mpeg4[19].value = mpeg4_arg->FrameQp_B; + + ext_ctrl_mpeg4[20].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP; + ext_ctrl_mpeg4[20].value = mpeg4_arg->QSCodeMax; + ext_ctrl_mpeg4[21].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP; + ext_ctrl_mpeg4[21].value = mpeg4_arg->QSCodeMin; + ext_ctrl_mpeg4[22].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl_mpeg4[22].value = mpeg4_arg->CBRPeriodRf; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl_mpeg4[24].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl_mpeg4[24].value = 0; + + ext_ctrl_mpeg4[25].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl_mpeg4[25].value = 0; + + ext_ctrl_mpeg4[26].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; + ext_ctrl_mpeg4[26].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + + ext_ctrl_mpeg4[27].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MB_ENABLE; /* MFC 6.x Only */ + ext_ctrl_mpeg4[27].value = mpeg4_arg->EnableMBRateControl; + break; + + case H263_ENC: + ext_ctrl_h263[0].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl_h263[0].value = h263_arg->IDRPeriod; + + ext_ctrl_h263[1].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl_h263[1].value = h263_arg->SliceMode; /* 0: one, Check is needed if h264 support multi-slice */ + + ext_ctrl_h263[2].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl_h263[2].value = h263_arg->RandomIntraMBRefresh; + + ext_ctrl_h263[3].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl_h263[3].value = h263_arg->PadControlOn; + ext_ctrl_h263[4].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl_h263[4].value = h263_arg->LumaPadVal; + ext_ctrl_h263[5].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl_h263[5].value = h263_arg->CbPadVal; + ext_ctrl_h263[6].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl_h263[6].value = h263_arg->CrPadVal; + + ext_ctrl_h263[7].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl_h263[7].value = h263_arg->EnableFRMRateControl; + + ext_ctrl_h263[8].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE; + ext_ctrl_h263[8].value = h263_arg->FrameRate; + + ext_ctrl_h263[9].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + ext_ctrl_h263[9].value = h263_arg->Bitrate; + + ext_ctrl_h263[10].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP; + ext_ctrl_h263[10].value = h263_arg->FrameQp; + ext_ctrl_h263[11].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP; + ext_ctrl_h263[11].value = h263_arg->FrameQp_P; + + ext_ctrl_h263[12].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP; + ext_ctrl_h263[12].value = h263_arg->QSCodeMax; + ext_ctrl_h263[13].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP; + ext_ctrl_h263[13].value = h263_arg->QSCodeMin; + ext_ctrl_h263[14].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl_h263[14].value = h263_arg->CBRPeriodRf; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl_h263[16].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl_h263[16].value = 0; + + ext_ctrl_h263[17].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl_h263[17].value = 0; + + ext_ctrl_h263[18].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; + ext_ctrl_h263[18].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + + ext_ctrl_h263[19].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MB_ENABLE; /* MFC 6.x Only */ + ext_ctrl_h263[19].value = h263_arg->EnableMBRateControl; + break; + + case H264_ENC: + ext_ctrl[0].id = V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE; + ext_ctrl[0].value = h264_arg->ProfileIDC; + ext_ctrl[1].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL; + ext_ctrl[1].value = h264_arg->LevelIDC; + ext_ctrl[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; + ext_ctrl[2].value = h264_arg->IDRPeriod; + ext_ctrl[3].id = V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC; + ext_ctrl[3].value = h264_arg->NumberReferenceFrames; + ext_ctrl[4].id = V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P; + ext_ctrl[4].value = h264_arg->NumberRefForPframes; + ext_ctrl[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; + ext_ctrl[5].value = h264_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ + if (h264_arg->SliceMode == 0) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = 1; /* default */ + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = 2800; /* based on MFC6.x */ + } else if (h264_arg->SliceMode == 1) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = h264_arg->SliceArgument; + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = 2800; /* based on MFC6.x */ + } else if (h264_arg->SliceMode == 3) { + ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; + ext_ctrl[6].value = 1; /* default */ + ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; + ext_ctrl[7].value = h264_arg->SliceArgument; + } + /* + It should be set using h264_arg->NumberBFrames after being handled by appl. + */ + ext_ctrl[8].id = V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES; + ext_ctrl[8].value = h264_arg->NumberBFrames; + ext_ctrl[9].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE; + ext_ctrl[9].value = h264_arg->LoopFilterDisable; + ext_ctrl[10].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA; + ext_ctrl[10].value = h264_arg->LoopFilterAlphaC0Offset; + ext_ctrl[11].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA; + ext_ctrl[11].value = h264_arg->LoopFilterBetaOffset; + ext_ctrl[12].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE; + ext_ctrl[12].value = h264_arg->SymbolMode; + ext_ctrl[13].id = V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE; + ext_ctrl[13].value = h264_arg->PictureInterlace; + ext_ctrl[14].id = V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM; + ext_ctrl[14].value = h264_arg->Transform8x8Mode; + ext_ctrl[15].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; + ext_ctrl[15].value = h264_arg->RandomIntraMBRefresh; + ext_ctrl[16].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; + ext_ctrl[16].value = h264_arg->PadControlOn; + ext_ctrl[17].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; + ext_ctrl[17].value = h264_arg->LumaPadVal; + ext_ctrl[18].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; + ext_ctrl[18].value = h264_arg->CbPadVal; + ext_ctrl[19].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; + ext_ctrl[19].value = h264_arg->CrPadVal; + ext_ctrl[20].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; + ext_ctrl[20].value = h264_arg->EnableFRMRateControl; + ext_ctrl[21].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE; + ext_ctrl[21].value = h264_arg->EnableMBRateControl; + ext_ctrl[22].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE; + ext_ctrl[22].value = h264_arg->FrameRate; + ext_ctrl[23].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; + /* FIXME temporary fix */ + if (h264_arg->Bitrate) + ext_ctrl[23].value = h264_arg->Bitrate; + else + ext_ctrl[23].value = 1; /* just for testing Movi studio */ + ext_ctrl[24].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP; + ext_ctrl[24].value = h264_arg->FrameQp; + ext_ctrl[25].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP; + ext_ctrl[25].value = h264_arg->FrameQp_P; + ext_ctrl[26].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP; + ext_ctrl[26].value = h264_arg->FrameQp_B; + ext_ctrl[27].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP; + ext_ctrl[27].value = h264_arg->QSCodeMax; + ext_ctrl[28].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP; + ext_ctrl[28].value = h264_arg->QSCodeMin; + ext_ctrl[29].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; + ext_ctrl[29].value = h264_arg->CBRPeriodRf; + ext_ctrl[30].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK; + ext_ctrl[30].value = h264_arg->DarkDisable; + ext_ctrl[31].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH; + ext_ctrl[31].value = h264_arg->SmoothDisable; + ext_ctrl[32].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC; + ext_ctrl[32].value = h264_arg->StaticDisable; + ext_ctrl[33].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY; + ext_ctrl[33].value = h264_arg->ActivityDisable; + + /* doesn't have to be set */ + ext_ctrl[34].id = V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP; + ext_ctrl[34].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; + ext_ctrl[35].id = V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD; + ext_ctrl[35].value = 10; + + if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; + } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; + } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; + ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; + } + + ext_ctrl[37].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; + ext_ctrl[37].value = 0; + + ext_ctrl[38].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; + ext_ctrl[38].value = 0; /* 0: seperated header + 1: header + first frame */ + + ext_ctrl[39].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; /* MFC5.x Only */ + ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + + ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE; + ext_ctrl[40].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; + ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC; + ext_ctrl[41].value = 0; + ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH; + ext_ctrl[42].value = 0; + ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT; + ext_ctrl[43].value = 0; + + if (pCTX->hier_p_enable) { + ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE; + ext_ctrl[44].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; + ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP; + ext_ctrl[45].value = pCTX->hier_qp_value.t0_frame_qp; + ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP; + ext_ctrl[46].value = pCTX->hier_qp_value.t2_frame_qp; + ext_ctrl[47].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP; + ext_ctrl[47].value = pCTX->hier_qp_value.t3_frame_qp; + } else { + ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE; + ext_ctrl[44].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; + ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP; + ext_ctrl[45].value = 0; + ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP; + ext_ctrl[46].value = 0; + ext_ctrl[47].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP; + ext_ctrl[47].value = 0; + } + break; + + default: + LOGE("[%s] Undefined codec type",__func__); + ret = MFC_RET_INVALID_PARAM; + goto error_case1; + } + + ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC; + if (pCTX->codecType == MPEG4_ENC) { + ext_ctrls.count = 28; + ext_ctrls.controls = ext_ctrl_mpeg4; + } else if (pCTX->codecType == H264_ENC) { + ext_ctrls.count = 48; + ext_ctrls.controls = ext_ctrl; + } else if (pCTX->codecType == H263_ENC) { + ext_ctrls.count = 20; + ext_ctrls.controls = ext_ctrl_h263; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_S_EXT_CTRLS, &ext_ctrls); + if (ret != 0) { + LOGE("[%s] Failed to set extended controls",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + fmt.fmt.pix_mp.width = pCTX->width; + fmt.fmt.pix_mp.height = pCTX->height; + fmt.fmt.pix_mp.num_planes = 2; +#if 0 + fmt.fmt.pix_mp.plane_fmt[0].bytesperline = Align(fmt.fmt.pix_mp.width, 128); + fmt.fmt.pix_mp.plane_fmt[1].bytesperline = Align(fmt.fmt.pix_mp.width, 128); + + if (NV12_TILE == pCTX->framemap) { + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 64x32 Tiles */ + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = + Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height, 32), 8192); /* tiled mode */ + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = + Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height >> 1, 32), 8192); /* tiled mode */ + } else { /* NV12_LINEAR (default) */ + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = + Align((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height), 2048); /* linear mode, 2K align */ + fmt.fmt.pix_mp.plane_fmt[1].sizeimage = + Align((fmt.fmt.pix_mp.width * (fmt.fmt.pix_mp.height >> 1)), 2048); /* linear mode, 2K align */ + } +#else /* FIXME: */ + if (NV12_TILE == pCTX->framemap) { + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 16x16 Tiles */ + } else { /* NV12_LINEAR (default) */ + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ + } +#endif + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed on MFC output stream",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* capture (dst) */ + memset(&fmt, 0, sizeof(fmt)); + + switch (pCTX->codecType) { + case H264_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + break; + case MPEG4_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case H263_ENC: + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; + break; + default: + LOGE("[%s] Codec has not been recognised",__func__); + return MFC_RET_ENC_INIT_FAIL; + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); + if (ret != 0) { + LOGE("[%s] S_FMT failed on MFC output stream",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* cacheable buffer */ + ctrl.id = V4L2_CID_CACHEABLE; + if (pCTX->cacheablebuffer == NO_CACHE) + ctrl.value = 0; + else + ctrl.value = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + + /* Initialize streams for input */ + memset(&reqbuf, 0, sizeof(reqbuf)); + reqbuf.count = MFC_ENC_NUM_SRC_BUFS; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (pCTX->v4l2_enc.bInputPhyVir) + reqbuf.memory = V4L2_MEMORY_USERPTR; + else + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] Reqbufs src ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case1; + } + pCTX->v4l2_enc.mfc_num_src_bufs = reqbuf.count; + + if (!pCTX->v4l2_enc.bInputPhyVir) { + /* Then the buffers have to be queried and mmaped */ + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; ++i) { + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + buf.m.planes = planes; + buf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); + if (ret != 0) { + LOGE("[%s] Querybuf src ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_src_bufs_len[0] = buf.m.planes[0].length; + pCTX->v4l2_enc.mfc_src_bufs_len[1] = buf.m.planes[1].length; + + pCTX->v4l2_enc.mfc_src_phys[i][0] = buf.m.planes[0].cookie; + pCTX->v4l2_enc.mfc_src_phys[i][1] = buf.m.planes[1].cookie; + + pCTX->v4l2_enc.mfc_src_bufs[i][0] = + mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == MAP_FAILED) { + LOGE("[%s] Mmap on src buffer (0) failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_src_bufs[i][1] = + mmap(NULL, buf.m.planes[1].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); + if (pCTX->v4l2_enc.mfc_src_bufs[i][1] == MAP_FAILED) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + LOGE("[%s] Mmap on src buffer (1) failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + } + } else + LOGV("[%s] Camera Phys src buf %d",__func__,reqbuf.count); + + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) + pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_DEQUEUED; + + pCTX->v4l2_enc.beingUsedIndex = 0; + + pCTX->sizeFrmBuf.luma = (unsigned int)(pCTX->width * pCTX->height); + pCTX->sizeFrmBuf.chroma = (unsigned int)((pCTX->width * pCTX->height) >> 1); + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + /* Initialize stream for output */ + memset(&reqbuf, 0, sizeof(reqbuf)); + reqbuf.count = MFC_ENC_MAX_DST_BUFS; + reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + reqbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); + if (ret != 0) { + LOGE("[%s] Reqbufs dst ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case2; + } + + pCTX->v4l2_enc.mfc_num_dst_bufs = reqbuf.count; + + for (i = 0; i < MFC_ENC_MAX_DST_BUFS; ++i) { + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + buf.m.planes = planes; + buf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); + if (ret != 0) { + LOGE("[%s] Querybuf dst ioctl failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + pCTX->v4l2_enc.mfc_dst_bufs_len = buf.m.planes[0].length; + pCTX->v4l2_enc.mfc_dst_bufs[i] = + mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); + if (pCTX->v4l2_enc.mfc_dst_bufs[i] == MAP_FAILED) { + LOGE("[%s] Mmap on dst buffer failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } + + pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, VIDIOC_STREAMON failed",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + + pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = 1; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLIN | POLLERR; + poll_events.revents = 0; + + /* wait for header encoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLIN) { /* POLLIN */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &buf); + if (ret == 0) + break; + } else if (poll_events.revents & POLLERR) { /*POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } else if (0 > poll_state) { + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + } while (1 == poll_state); + + pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused; + pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[buf.index]; + + /* stream dequeued index */ + index = buf.index; + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = index; + buf.m.planes = planes; + buf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + ret = MFC_RET_ENC_INIT_FAIL; + goto error_case3; + } + LOGV("[%s] Strm out idx %d",__func__,index); + + return MFC_RET_OK; +error_case3: + for (j = 0; j < i; j++) + munmap(pCTX->v4l2_enc.mfc_dst_bufs[j], pCTX->v4l2_enc.mfc_dst_bufs_len); + + i = pCTX->v4l2_enc.mfc_num_src_bufs; +error_case2: + if (!pCTX->v4l2_enc.bInputPhyVir) { + for (j = 0; j < i; j++) { + munmap(pCTX->v4l2_enc.mfc_src_bufs[j][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); + munmap(pCTX->v4l2_enc.mfc_src_bufs[j][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); + } + } +error_case1: + return ret; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + int i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + /* FIXME check this if GetInBuf() is not called for UserPtr */ + if (pCTX->v4l2_enc.bInputPhyVir) { + input_info->YPhyAddr = (void*)0; + input_info->CPhyAddr = (void*)0; + input_info->YVirAddr = (void*)0; + input_info->CVirAddr = (void*)0; + + /* FIXME check whether Y & C sizes should be set or not*/ + if (NV12_TILE == pCTX->framemap) { + /* 4:2:0, 2 Planes, 64x32 Tiles */ + input_info->YSize = Align(Align(pCTX->width, 128) * Align(pCTX->height, 32), 8192); /* tiled mode */ + input_info->CSize = Align(Align(pCTX->width, 128) * Align(pCTX->height >> 1, 32), 8192); /* tiled mode */ + } else { /* NV12_LINEAR (default) */ + /* 4:2:0, 2 Planes, linear */ + input_info->YSize = Align((pCTX->width * pCTX->height), 2048); /* linear mode, 2K align */ + input_info->CSize = Align((pCTX->width * (pCTX->height >> 1)), 2048); /* linear mode, 2K align */ + } + } else { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) + if (BUF_DEQUEUED == pCTX->v4l2_enc.mfc_src_buf_flags[i]) + break; + + if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { + LOGV("[%s] No buffer is available.",__func__); + return MFC_RET_ENC_GET_INBUF_FAIL; + } else { + input_info->YPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][0]; + input_info->CPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][1]; + input_info->YVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][0]; + input_info->CVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][1]; + input_info->YSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[0]; + input_info->CSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[1]; + + pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + } + LOGV("[%s] Input Buffer idx %d",__func__,i); + return MFC_RET_OK; +} + + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + int ret,i; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + memset(&qbuf, 0, sizeof(qbuf)); + if (pCTX->v4l2_enc.bInputPhyVir) { + qbuf.memory = V4L2_MEMORY_USERPTR; + qbuf.index = pCTX->v4l2_enc.beingUsedIndex; + planes[0].m.userptr = (unsigned long)input_info->YPhyAddr; + planes[0].length = input_info->YSize; + planes[0].bytesused = input_info->YSize; + planes[1].m.userptr = (unsigned long)input_info->CPhyAddr; + planes[1].length = input_info->CSize; + planes[1].bytesused = input_info->CSize; + + /* FIXME, this is only for case of not using B frame, + Camera side should know which buffer is queued() refering to index of + MFC dqbuf() */ + pCTX->v4l2_enc.beingUsedIndex++; + pCTX->v4l2_enc.beingUsedIndex %= MFC_ENC_NUM_SRC_BUFS; + LOGV("[%s] Phy Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); + } else { + for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) + if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == input_info->YVirAddr) + break; + + if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { + LOGE("[%s] Can not use the buffer",__func__); + return MFC_RET_INVALID_PARAM; + } else { + pCTX->v4l2_enc.beingUsedIndex = i; + //pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; + } + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = pCTX->v4l2_enc.beingUsedIndex; + planes[0].bytesused = pCTX->width * pCTX->height; + planes[1].bytesused = (pCTX->width * pCTX->height) >> 1; + LOGV("[%s] Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); + } + + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + qbuf.m.planes = planes; + qbuf.length = 2; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_SET_INBUF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + struct v4l2_control ctrl; + unsigned int encoded_y_addr, encoded_c_addr; + int ret; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + if (pCTX->v4l2_enc.bRunning == 0) { + pCTX->encodedHeaderSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; + output_info->dataSize = 0; + } else { + output_info->dataSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; + } + + ctrl.id = V4L2_CID_CODEC_ENCODED_LUMA_ADDR; + ctrl.value = 0; + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) + LOGE("[%s] Error to do g_ctrl",__func__); + encoded_y_addr = (unsigned int)ctrl.value; + + ctrl.id = V4L2_CID_CODEC_ENCODED_CHROMA_ADDR; + ctrl.value = 0; + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) + LOGE("[%s] Error to do g_ctrl",__func__); + encoded_c_addr = (unsigned int)ctrl.value; + + output_info->headerSize = pCTX->encodedHeaderSize; + output_info->frameType = pCTX->encodedframeType; + output_info->StrmPhyAddr = (void *)0; + output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; + output_info->encodedYPhyAddr = (void*)encoded_y_addr; + output_info->encodedCPhyAddr = (void*)encoded_c_addr; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) +{ + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_ENC_SET_OUTBUF_FAIL; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) +{ + int ret; + int dequeued_index; + int loopcnt = 0; + _MFCLIB *pCTX; + + struct v4l2_buffer qbuf; + struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; + enum v4l2_buf_type type; + + struct v4l2_control ctrl; + + struct pollfd poll_events; + int poll_state; + + LOGV("[%s] Enter \n",__func__); + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = pCTX->inframetag; + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + if (pCTX->v4l2_enc.bRunning == 0) { + type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); + if (ret != 0) { + LOGE("[%s] VIDIOC_STREAMON failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->v4l2_enc.bRunning = 1; + } + + pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.m.planes = planes; + qbuf.length = 1; + + /* note: #define POLLOUT 0x0004 */ + poll_events.fd = pCTX->hMFC; + poll_events.events = POLLIN | POLLERR; + poll_events.revents = 0; + + /* wait for encoding */ + do { + poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); + if (0 < poll_state) { + if (poll_events.revents & POLLIN) { /* POLLIN */ + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret == 0) + break; + } else if (poll_events.revents & POLLERR) { /* POLLERR */ + LOGE("[%s] POLLERR\n",__func__); + return MFC_RET_ENC_EXE_ERR; + } else { + LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); + return MFC_RET_ENC_EXE_ERR; + } + } else if (0 > poll_state) { + LOGE("[%s] poll() Encoder POLL Timeout 0x%x\n",__func__, poll_events.revents); + return MFC_RET_ENC_EXE_ERR; + } else { /* in the case of B frame encoding */ + ctrl.id = V4L2_CID_CODEC_CHECK_STATE; + ctrl.value = 0; + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + LOGV("[%s] ctx state = %d\n",__func__, ctrl.value); + if (ctrl.value == MFCSTATE_ENC_NO_OUTPUT) + return MFC_RET_OK; + } + loopcnt++; + } while ((0 == poll_state) && (loopcnt < 5)); + + if (pCTX->v4l2_enc.bRunning != 0) { + pCTX->encodedframeType = (qbuf.flags & 0x38) >> 3; /* encoded frame type */ + LOGV("[%s] encoded frame type = %d\n", __func__, pCTX->encodedframeType); + + switch (pCTX->encodedframeType) { + case 1: + pCTX->encodedframeType = MFC_FRAME_TYPE_I_FRAME; + break; + case 2: + pCTX->encodedframeType = MFC_FRAME_TYPE_P_FRAME; + break; + case 4: + pCTX->encodedframeType = MFC_FRAME_TYPE_B_FRAME; + break; + default: + LOGE("[%s] VIDIOC_DQBUF failed, encoded frame type is wrong",__func__); + } + } + + dequeued_index = qbuf.index; + + if (qbuf.m.planes[0].bytesused > 0) { /* FIXME later */ + pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = qbuf.m.planes[0].bytesused; + } + + ctrl.id = V4L2_CID_CODEC_FRAME_TAG; + ctrl.value = 0; + + ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->outframetagtop = ctrl.value; + + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + qbuf.memory = V4L2_MEMORY_MMAP; + qbuf.index = dequeued_index; + qbuf.m.planes = planes; + qbuf.length = 1; + + ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + + if (pCTX->v4l2_enc.bRunning != 0) { + memset(&qbuf, 0, sizeof(qbuf)); + qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (pCTX->v4l2_enc.bInputPhyVir) + qbuf.memory = V4L2_MEMORY_USERPTR; + else + qbuf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); + if (ret != 0) { + LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); + return MFC_RET_ENC_EXE_ERR; + } + } + pCTX->v4l2_enc.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; + + /* Update context stream buffer address */ + pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[dequeued_index]; + LOGV("[%s] Strm out idx %d",__func__,dequeued_index); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + struct v4l2_control ctrl; + struct mfc_enc_hier_p_qp hier_p_qp; + int ret; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *) openHandle; + + switch (conf_type) { + case MFC_ENC_SETCONF_FRAME_TAG: + pCTX->inframetag = *((unsigned int *)value); + return MFC_RET_OK; + + case MFC_ENC_SETCONF_FRAME_TYPE: + ctrl.id = V4L2_CID_CODEC_FRAME_INSERTION; + ctrl.value = *((unsigned int*)value); + break; + + case MFC_ENC_SETCONF_I_PERIOD: + ctrl.id = V4L2_CID_CODEC_ENCODED_I_PERIOD_CH; + ctrl.value = *((unsigned int*)value); + break; + + case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: + ctrl.id = V4L2_CID_CODEC_ENCODED_FRAME_RATE_CH; + ctrl.value = *((unsigned int*)value); + break; + + case MFC_ENC_SETCONF_CHANGE_BIT_RATE: + ctrl.id = V4L2_CID_CODEC_ENCODED_BIT_RATE_CH; + ctrl.value = *((unsigned int*)value); + break; + + case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: + pCTX->enc_frameskip = *((int *)value); + return MFC_RET_OK; +#if 0 + case MFC_ENC_SETCONF_VUI_INFO: + vui_info = *((struct mfc_enc_vui_info *) value); + EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); + EncArg.args.set_config.in_config_value[1] = 0; + break; +#endif + case MFC_ENC_SETCONF_HIER_P: + hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); + pCTX->hier_p_enable = 1; + pCTX->hier_qp_value.t0_frame_qp = (int)(hier_p_qp.t0_frame_qp); + pCTX->hier_qp_value.t2_frame_qp = (int)(hier_p_qp.t2_frame_qp); + pCTX->hier_qp_value.t3_frame_qp = (int)(hier_p_qp.t3_frame_qp); + return MFC_RET_OK; + + default: + LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); + if (ret != 0) { + LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); + return MFC_RET_ENC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + _MFCLIB *pCTX; + + pCTX = (_MFCLIB *) openHandle; + + if (openHandle == NULL) { + LOGE("[%s] openHandle is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("[%s] value is NULL\n",__func__); + return MFC_RET_INVALID_PARAM; + } + + switch (conf_type) { + case MFC_ENC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->outframetagtop; + break; + + default: + LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} + diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h new file mode 100644 index 0000000..28b2d8a --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SSBSIP_MFC_API_H_ +#define _SSBSIP_MFC_API_H_ + +/*--------------------------------------------------------------------------------*/ +/* Definition */ +/*--------------------------------------------------------------------------------*/ +#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) +#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) + +#define SUPPORT_1080P 1 + +#if SUPPORT_1080P +#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ +#else +#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) +#endif + +#define SAMSUNG_MFC_DEV_NAME "/dev/video" + +#define SSBSIP_MFC_OK (1) +#define SSBSIP_MFC_FAIL (0) + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + H264_DEC, + VC1_DEC, /* VC1 advaced Profile decoding */ + MPEG4_DEC, + XVID_DEC, + MPEG1_DEC, + MPEG2_DEC, + H263_DEC, + VC1RCV_DEC, /* VC1 simple/main profile decoding */ + FIMV1_DEC, + FIMV2_DEC, + FIMV3_DEC, + FIMV4_DEC, + VP8_DEC, + H264_ENC, + MPEG4_ENC, + H263_ENC, + UNKNOWN_TYPE +} SSBSIP_MFC_CODEC_TYPE; + +typedef enum { + DONT_CARE = 0, + I_FRAME = 1, + NOT_CODED = 2 +} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; + +typedef enum { + NV12_LINEAR = 0, + NV12_TILE +} SSBSIP_MFC_INSTRM_MODE_TYPE; + +typedef enum { + NO_CACHE = 0, + CACHE = 1 +} SSBIP_MFC_BUFFER_TYPE; + +typedef enum { + MFC_DEC_SETCONF_POST_ENABLE = 1, + MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, + MFC_DEC_SETCONF_DISPLAY_DELAY, + MFC_DEC_SETCONF_IS_LAST_FRAME, + MFC_DEC_SETCONF_SLICE_ENABLE, + MFC_DEC_SETCONF_CRC_ENABLE, + MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, + MFC_DEC_SETCONF_FRAME_TAG, + MFC_DEC_GETCONF_CRC_DATA, + MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, + MFC_DEC_GETCONF_CROP_INFO, + MFC_DEC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, + MFC_DEC_SETCONF_DPB_FLUSH, + MFC_DEC_SETCONF_PIXEL_CACHE, + MFC_DEC_GETCONF_WIDTH_HEIGHT +} SSBSIP_MFC_DEC_CONF; + +typedef enum { + MFC_ENC_SETCONF_FRAME_TYPE = 100, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + MFC_ENC_SETCONF_FRAME_TAG, + MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, + MFC_ENC_GETCONF_FRAME_TAG, + + /* C210 specific feature */ + MFC_ENC_SETCONF_VUI_INFO, + MFC_ENC_SETCONF_I_PERIOD, + MFC_ENC_SETCONF_HIER_P +} SSBSIP_MFC_ENC_CONF; + +typedef enum { + MFC_GETOUTBUF_STATUS_NULL = 0, + MFC_GETOUTBUF_DECODING_ONLY = 1, + MFC_GETOUTBUF_DISPLAY_DECODING, + MFC_GETOUTBUF_DISPLAY_ONLY, + MFC_GETOUTBUF_DISPLAY_END, + MFC_GETOUTBUF_CHANGE_RESOL +} SSBSIP_MFC_DEC_OUTBUF_STATUS; + +typedef enum { + MFC_FRAME_TYPE_NOT_CODED, + MFC_FRAME_TYPE_I_FRAME, + MFC_FRAME_TYPE_P_FRAME, + MFC_FRAME_TYPE_B_FRAME, + MFC_FRAME_TYPE_OTHERS +} SSBSIP_MFC_FRAME_TYPE; + +typedef enum { + MFC_RET_OK = 1, + MFC_RET_FAIL = -1000, + MFC_RET_OPEN_FAIL = -1001, + MFC_RET_CLOSE_FAIL = -1002, + + MFC_RET_DEC_INIT_FAIL = -2000, + MFC_RET_DEC_EXE_TIME_OUT = -2001, + MFC_RET_DEC_EXE_ERR = -2002, + MFC_RET_DEC_GET_INBUF_FAIL = -2003, + MFC_RET_DEC_SET_INBUF_FAIL = -2004, + MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, + MFC_RET_DEC_GET_CONF_FAIL = -2006, + MFC_RET_DEC_SET_CONF_FAIL = -2007, + + MFC_RET_ENC_INIT_FAIL = -3000, + MFC_RET_ENC_EXE_TIME_OUT = -3001, + MFC_RET_ENC_EXE_ERR = -3002, + MFC_RET_ENC_GET_INBUF_FAIL = -3003, + MFC_RET_ENC_SET_INBUF_FAIL = -3004, + MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, + MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, + MFC_RET_ENC_GET_CONF_FAIL = -3007, + MFC_RET_ENC_SET_CONF_FAIL = -3008, + + MFC_RET_INVALID_PARAM = -4000 +} SSBSIP_MFC_ERROR_CODE; + +typedef struct { + void *YPhyAddr; /* [OUT] physical address of Y */ + void *CPhyAddr; /* [OUT] physical address of CbCr */ + void *YVirAddr; /* [OUT] virtual address of Y */ + void *CVirAddr; /* [OUT] virtual address of CbCr */ + + int img_width; /* [OUT] width of real image */ + int img_height; /* [OUT] height of real image */ + int buf_width; /* [OUT] width aligned to 16 */ + int buf_height; /* [OUT] height alighed to 16 */ + + int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ + int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ + int consumedByte; /* [OUT] the number of byte consumed during decoding */ + int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ + int crop_top_offset; /* [OUT] crop information, top_offset */ + int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ + int crop_left_offset; /* [OUT] crop information, left_offset */ + int crop_right_offset; /* [OUT] crop information, right_offset */ + int disp_pic_frame_type; /* [OUT] display picture frame type information */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_DEC_OUTPUT_INFO; + +typedef struct { + void *YPhyAddr; /* [IN/OUT] physical address of Y */ + void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ + void *YVirAddr; /* [IN/OUT] virtual address of Y */ + void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ + int YSize; /* [IN/OUT] input size of Y data */ + int CSize; /* [IN/OUT] input size of CbCr data */ + + /* C210 UMP feature */ + unsigned int y_cookie; /* [OUT] cookie for Y address */ + unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_INPUT_INFO; + +typedef struct { + unsigned int dataSize; /* [OUT] encoded data size(without header) */ + unsigned int headerSize; /* [OUT] encoded header size */ + unsigned int frameType; /* [OUT] frame type of encoded stream */ + void *StrmPhyAddr; /* [OUT] physical address of Y */ + void *StrmVirAddr; /* [OUT] virtual address of Y */ + void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ + void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ + + /* C210 UMP feature */ + unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ + unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ + unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ +} SSBSIP_MFC_ENC_OUTPUT_INFO; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + + /* H.264 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int NumberReferenceFrames; /* [IN] The number of reference pictures used */ + int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ + int LoopFilterDisable; /* [IN] disable the loop filter */ + int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ + int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ + int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ + int PictureInterlace; /* [IN] Enables the interlace mode */ + int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ + int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ + int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ + int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ + int StaticDisable; /* [IN] Disable adaptive rate control on static region */ + int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ +} SSBSIP_MFC_ENC_H264_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */ + + /* MPEG4 specific parameters */ + int ProfileIDC; /* [IN] profile */ + int LevelIDC; /* [IN] level */ + int FrameQp_B; /* [IN] The quantization parameter of the B frame */ + int TimeIncreamentRes; /* [IN] frame rate */ + int VopTimeIncreament; /* [IN] frame rate */ + int SliceArgument; /* [IN] MB number or byte number */ + int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ + int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ +} SSBSIP_MFC_ENC_MPEG4_PARAM; + +typedef struct { + /* common parameters */ + SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ + int SourceWidth; /* [IN] width of video to be encoded */ + int SourceHeight; /* [IN] height of video to be encoded */ + int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ + int SliceMode; /* [IN] Multi slice mode */ + int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ + int EnableFRMRateControl; /* [IN] frame based rate control enable */ + int Bitrate; /* [IN] rate control parameter(bit rate) */ + int FrameQp; /* [IN] The quantization parameter of the frame */ + int FrameQp_P; /* [IN] The quantization parameter of the P frame */ + int QSCodeMax; /* [IN] Maximum Quantization value */ + int QSCodeMin; /* [IN] Minimum Quantization value */ + int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ + int PadControlOn; /* [IN] Enable padding control */ + int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ + int CbPadVal; /* [IN] CB pel value used to fill padding area */ + int CrPadVal; /* [IN] CR pel value used to fill padding area */ + int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ + int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */ + + /* H.263 specific parameters */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ +} SSBSIP_MFC_ENC_H263_PARAM; + +typedef struct { + int width; + int height; + int buf_width; + int buf_height; +} SSBSIP_MFC_IMG_RESOLUTION; + +typedef struct { + int crop_top_offset; + int crop_bottom_offset; + int crop_left_offset; + int crop_right_offset; +} SSBSIP_MFC_CROP_INFORMATION; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------------*/ +/* Decoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcDecOpen(void); +void *SsbSipMfcDecOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); +//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); +//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); +#else +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); +#endif + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); + +/*--------------------------------------------------------------------------------*/ +/* Encoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcEncOpen(void); +void *SsbSipMfcEncOpenExt(void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h new file mode 100644 index 0000000..b8e96ab --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_ERRNO_H +#define __MFC_ERRNO_H __FILE__ + +enum mfc_ret_code { + MFC_OK = 1, + MFC_FAIL = -1000, + MFC_OPEN_FAIL = -1001, + MFC_CLOSE_FAIL = -1002, + + MFC_DEC_INIT_FAIL = -2000, + MFC_DEC_EXE_TIME_OUT = -2001, + MFC_DEC_EXE_ERR = -2002, + MFC_DEC_GET_INBUF_FAIL = 2003, + MFC_DEC_SET_INBUF_FAIL = 2004, + MFC_DEC_GET_OUTBUF_FAIL = -2005, + MFC_DEC_GET_CONF_FAIL = -2006, + MFC_DEC_SET_CONF_FAIL = -2007, + + MFC_ENC_INIT_FAIL = -3000, + MFC_ENC_EXE_TIME_OUT = -3001, + MFC_ENC_EXE_ERR = -3002, + MFC_ENC_GET_INBUF_FAIL = -3003, + MFC_ENC_SET_INBUF_FAIL = -3004, + MFC_ENC_GET_OUTBUF_FAIL = -3005, + MFC_ENC_SET_OUTBUF_FAIL = -3006, + MFC_ENC_GET_CONF_FAIL = -3007, + MFC_ENC_SET_CONF_FAIL = -3008, + + MFC_STATE_INVALID = -4000, + MFC_DEC_HEADER_FAIL = -4001, + MFC_DEC_INIT_BUF_FAIL = -4002, + MFC_ENC_HEADER_FAIL = -5000, + MFC_ENC_PARAM_FAIL = -5001, + MFC_FRM_BUF_SIZE_FAIL = -6000, + MFC_FW_LOAD_FAIL = -6001, + MFC_FW_INIT_FAIL = -6002, + MFC_INST_NUM_EXCEEDED_FAIL = -6003, + MFC_MEM_ALLOC_FAIL = -6004, + MFC_MEM_INVALID_ADDR_FAIL = -6005, + MFC_MEM_MAPPING_FAIL = -6006, + MFC_GET_CONF_FAIL = -6007, + MFC_SET_CONF_FAIL = -6008, + MFC_INVALID_PARAM_FAIL = -6009, + MFC_API_FAIL = -9000, + + MFC_CMD_FAIL = -1003, + MFC_SLEEP_FAIL = -1010, + MFC_WAKEUP_FAIL = -1020, + + MFC_CLK_ON_FAIL = -1030, + MFC_CLK_OFF_FAIL = -1030, + MFC_PWR_ON_FAIL = -1040, + MFC_PWR_OFF_FAIL = -1041, +}; + +#endif /* __MFC_ERRNO_H */ diff --git a/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h new file mode 100644 index 0000000..2200e10 --- /dev/null +++ b/exynos/multimedia/codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Global header for Samsung MFC (Multi Function Codec - FIMV) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MFC_INTERFACE_H +#define __MFC_INTERFACE_H + +#include "mfc_errno.h" +#include "SsbSipMfcApi.h" + +#define IOCTL_MFC_DEC_INIT (0x00800001) +#define IOCTL_MFC_ENC_INIT (0x00800002) +#define IOCTL_MFC_DEC_EXE (0x00800003) +#define IOCTL_MFC_ENC_EXE (0x00800004) + +#define IOCTL_MFC_GET_IN_BUF (0x00800010) +#define IOCTL_MFC_FREE_BUF (0x00800011) +#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) +#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) +#define IOCTL_MFC_SET_IN_BUF (0x00800018) + +#define IOCTL_MFC_SET_CONFIG (0x00800101) +#define IOCTL_MFC_GET_CONFIG (0x00800102) + +#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) + +/* MFC H/W support maximum 32 extra DPB. */ +#define MFC_MAX_EXTRA_DPB 5 +#define MFC_MAX_DISP_DELAY 0xF + +#define MFC_LIB_VER_MAJOR 1 +#define MFC_LIB_VER_MINOR 00 + +#define BUF_L_UNIT (1024) +#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) + +#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ +#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */ +#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */ + +#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ +#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */ +#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */ + +enum inst_type { + DECODER = 0x1, + ENCODER = 0x2, +}; + +enum mfc_check_state { + MFCSTATE_PROCESSING = 0, + MFCSTATE_DEC_RES_DETECT, + MFCSTATE_DEC_TERMINATING, + MFCSTATE_ENC_NO_OUTPUT, +}; + +typedef enum { + MFC_UNPACKED_PB = 0, + MFC_PACKED_PB = 1 +} mfc_packed_mode; + +typedef enum { + SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0, + SSBSIP_MFC_LAST_FRAME_RECEIVED = 1, + SSBSIP_MFC_LAST_FRAME_PROCESSED = 2 +} SSBSIP_MFC_LAST_FRAME_STATUS; + +typedef enum { + MFC_USE_NONE = 0x0000, + MFC_USE_YUV_BUFF = 0x0001, + MFC_USE_STRM_BUFF = 0x0010, + MFC_USE_SRC_STREAMON = 0x0100, + MFC_USE_DST_STREAMON = 0x1000, +} s3c_mfc_interbuff_status; + +typedef struct { + int luma0; /* per frame (or top field) */ + int chroma0; /* per frame (or top field) */ + int luma1; /* per frame (or bottom field) */ + int chroma1; /* per frame (or bottom field) */ +} SSBSIP_MFC_CRC_DATA; + +struct mfc_strm_ref_buf_arg { + unsigned int strm_ref_y; + unsigned int mv_ref_yc; +}; + +struct mfc_frame_buf_arg { + unsigned int luma; + unsigned int chroma; +}; + +struct mfc_enc_init_common_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + + int in_width; /* [IN] width of YUV420 frame to be encoded */ + int in_height; /* [IN] height of YUV420 frame to be encoded */ + + int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ + int in_vop_quant; /* [IN] VOP quant */ + int in_vop_quant_p; /* [IN] VOP quant for P frame */ + + /* [IN] RC enable */ + /* [IN] RC enable (0:disable, 1:frame level RC) */ + int in_rc_fr_en; + int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ + + int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ + int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ + int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ + + /* [IN] Multi-slice mode (0:single, 1:multiple) */ + int in_ms_mode; + /* [IN] Multi-slice size (in num. of mb or byte) */ + int in_ms_arg; + + int in_mb_refresh; /* [IN] Macroblock refresh */ + + /* [IN] Enable (1) / Disable (0) padding with the specified values */ + int in_pad_ctrl_on; + + /* [IN] pad value if pad_ctrl_on is Enable */ + int in_y_pad_val; + int in_cb_pad_val; + int in_cr_pad_val; + + /* linear or tiled */ + int in_frame_map; + + unsigned int in_pixelcache; + + unsigned int in_mapped_addr; + struct mfc_strm_ref_buf_arg out_u_addr; + struct mfc_strm_ref_buf_arg out_p_addr; + struct mfc_strm_ref_buf_arg out_buf_size; + unsigned int out_header_size; +}; + +struct mfc_enc_init_h263_arg { + int in_rc_framerate; /* [IN] RC parameter (framerate) */ +}; + +struct mfc_enc_init_mpeg4_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ + int in_quart_pixel; + + int in_TimeIncreamentRes; /* [IN] VOP time resolution */ + int in_VopTimeIncreament; /* [IN] Frame delta */ +}; + +struct mfc_enc_init_h264_arg { + int in_profile; /* [IN] profile */ + int in_level; /* [IN] level */ + + int in_vop_quant_b; /* [IN] VOP quant for B frame */ + + /* [IN] B frame number */ + int in_bframenum; + + /* [IN] interlace mode(0:progressive, 1:interlace) */ + int in_interlace_mode; + + /* [IN] reference number */ + int in_reference_num; + /* [IN] reference number of P frame */ + int in_ref_num_p; + + int in_rc_framerate; /* [IN] RC parameter (framerate) */ + int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ + /* [IN] MB level rate control dark region adaptive feature */ + int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control smooth region adaptive feature */ + int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control static region adaptive feature */ + int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ + /* [IN] MB level rate control activity region adaptive feature */ + int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ + + /* [IN] disable deblocking filter idc */ + int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ + /* [IN] slice alpha c0 offset of deblocking filter */ + int in_deblock_alpha_c0; + /* [IN] slice beta offset of deblocking filter */ + int in_deblock_beta; + + /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ + int in_symbolmode; + /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ + int in_transform8x8_mode; + + /* [IN] Inter weighted parameter for mode decision */ + int in_md_interweight_pps; + /* [IN] Intra weighted parameter for mode decision */ + int in_md_intraweight_pps; +}; + +struct mfc_enc_init_arg { + struct mfc_enc_init_common_arg cmn; + union { + struct mfc_enc_init_h264_arg h264; + struct mfc_enc_init_mpeg4_arg mpeg4; + struct mfc_enc_init_h263_arg h263; + } codec; +}; + +struct mfc_enc_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ + unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ + unsigned int in_frametag; /* [IN] unique frame ID */ + + unsigned int out_frame_type; /* [OUT] frame type */ + int out_encoded_size; /* [OUT] Length of Encoded video stream */ + unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */ + unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */ + unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */ + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif +}; + +struct mfc_dec_init_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] address of stream buffer */ + int in_strm_size; /* [IN] filled size in stream buffer */ + int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ + + unsigned int in_crc; /* [IN] */ + unsigned int in_pixelcache; /* [IN] */ + unsigned int in_slice; /* [IN] */ + unsigned int in_numextradpb; /* [IN] */ + + unsigned int in_mapped_addr; + + int out_frm_width; /* [OUT] width of YUV420 frame */ + int out_frm_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ + + int out_crop_right_offset; /* [OUT] crop information for h264 */ + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; +}; + +struct mfc_dec_exe_arg { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_strm_buf; /* [IN] the physical address of STRM_BUF */ + /* [IN] Size of video stream filled in STRM_BUF */ + int in_strm_size; + /* [IN] the address of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_buf; + /* [IN] size of dpb FRAME_BUF */ + struct mfc_frame_buf_arg in_frm_size; + /* [IN] Unique frame ID eg. application specific timestamp */ + unsigned int in_frametag; + /* [IN] immdiate Display for seek,thumbnail and one frame */ + int in_immediately_disp; + /* [OUT] the physical address of display buf */ + int out_display_Y_addr; + /* [OUT] the physical address of display buf */ + int out_display_C_addr; + int out_display_status; + /* [OUT] unique frame ID of an output frame or top field */ + unsigned int out_frametag_top; + /* [OUT] unique frame ID of bottom field */ + unsigned int out_frametag_bottom; + int out_pic_time_top; + int out_pic_time_bottom; + int out_consumed_byte; + + int out_crop_right_offset; + int out_crop_left_offset; + int out_crop_bottom_offset; + int out_crop_top_offset; + + /* in new driver, each buffer offset must be return to the user */ + int out_y_offset; + int out_c_offset; + +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int out_y_secure_id; + unsigned int out_c_secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int out_y_cookie; + unsigned int out_c_cookie; +#endif + int out_img_width; /* [OUT] width of YUV420 frame */ + int out_img_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + + int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ +}; + +struct mfc_get_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to get for the configurable parameter. */ + /* Maximum four integer values can be obtained; */ + int out_config_value[4]; +}; + +struct mfc_set_config_arg { + /* [IN] Configurable parameter type */ + int in_config_param; + + /* [IN] Values to be set for the configurable parameter. */ + /* Maximum four integer values can be set. */ + int in_config_value[4]; +}; + +struct mfc_get_real_addr_arg { + unsigned int key; + unsigned int addr; +}; + +struct mfc_buf_alloc_arg { + enum inst_type type; + int size; + /* + unsigned int mapped; + */ + unsigned int align; + + unsigned int addr; + /* + unsigned int phys; + */ +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + /* FIMXE: invalid secure id == -1 */ + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_buf_free_arg { + unsigned int addr; +}; + +/* RMVME */ +struct mfc_mem_alloc_arg { + enum inst_type type; + int buff_size; + SSBIP_MFC_BUFFER_TYPE buf_cache_type; + unsigned int mapped_addr; +#if defined(CONFIG_VIDEO_MFC_VCM_UMP) + unsigned int secure_id; +#elif defined(CONFIG_S5P_VMEM) + unsigned int cookie; +#else + unsigned int offset; +#endif +}; + +struct mfc_mem_free_arg { + unsigned int key; +}; +/* RMVME */ + +union mfc_args { + /* + struct mfc_enc_init_arg enc_init; + + struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; + struct mfc_enc_init_mpeg4_arg enc_init_h263; + struct mfc_enc_init_h264_arg enc_init_h264; + */ + struct mfc_enc_init_arg enc_init; + struct mfc_enc_exe_arg enc_exe; + + struct mfc_dec_init_arg dec_init; + struct mfc_dec_exe_arg dec_exe; + + struct mfc_get_config_arg get_config; + struct mfc_set_config_arg set_config; + + struct mfc_buf_alloc_arg buf_alloc; + struct mfc_buf_free_arg buf_free; + struct mfc_get_real_addr_arg real_addr; + + /* RMVME */ + struct mfc_mem_alloc_arg mem_alloc; + struct mfc_mem_free_arg mem_free; + /* RMVME */ +}; + +struct mfc_common_args { + enum mfc_ret_code ret_code; /* [OUT] error code */ + union mfc_args args; +}; + +struct mfc_enc_vui_info { + int aspect_ratio_idc; +}; + +struct mfc_dec_fimv1_info { + int width; + int height; +}; + +struct mfc_enc_hier_p_qp { + int t0_frame_qp; + int t2_frame_qp; + int t3_frame_qp; +}; + +enum BUF_STATUS { + BUF_ENQUEUED, + BUF_DEQUEUED +}; + +struct mfc_dec_v4l2 { + char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */ + char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */ + char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */ + + unsigned int mfc_src_bufs_len; /* needed for munmap */ + unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */ + + unsigned int mfc_num_src_bufs; /* the number of source buffers */ + unsigned int mfc_num_dst_bufs; /* the number of destination buffers */ + + char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS]; + int bBeingFinalized; + int allocIndex; + int beingUsedIndex; +}; + +struct mfc_enc_v4l2 { + char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; + char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; + char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS]; + + unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES]; + unsigned int mfc_dst_bufs_len; + + unsigned int mfc_num_src_bufs; + unsigned int mfc_num_dst_bufs; + + unsigned int mfc_dst_bufs_bytes_used_len; + char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS]; + int bRunning; + int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */ + int beingUsedIndex; +}; + +typedef struct { + int magic; + int hMFC; + int hVMEM; + int width; + int height; + int sizeStrmBuf; + struct mfc_frame_buf_arg sizeFrmBuf; + int displayStatus; + int inter_buff_status; + unsigned int virFreeStrmAddr; + unsigned int phyStrmBuf; + unsigned int virStrmBuf; + unsigned int virMvRefYC; + struct mfc_frame_buf_arg phyFrmBuf; + struct mfc_frame_buf_arg virFrmBuf; + unsigned int mapped_addr; + unsigned int mapped_size; + struct mfc_common_args MfcArg; + SSBSIP_MFC_CODEC_TYPE codecType; + SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; + unsigned int inframetag; + unsigned int outframetagtop; + unsigned int outframetagbottom; + unsigned int immediatelydisp; + unsigned int encodedHeaderSize; + int encodedDataSize; + unsigned int encodedframeType; + struct mfc_frame_buf_arg encodedphyFrmBuf; + + unsigned int dec_crc; + unsigned int dec_pixelcache; + unsigned int dec_slice; + unsigned int dec_numextradpb; + + int input_cookie; + int input_secure_id; + int input_size; + + /* to support non-blocking mode */ + unsigned int encode_cnt; + + struct mfc_dec_v4l2 v4l2_dec; + struct mfc_enc_v4l2 v4l2_enc; + + int enc_frameskip; + int cacheablebuffer; + struct mfc_dec_fimv1_info fimv1_res; + SSBSIP_MFC_LAST_FRAME_STATUS lastframe; + SSBSIP_MFC_INSTRM_MODE_TYPE framemap; + + int hier_p_enable; + struct mfc_enc_hier_p_qp hier_qp_value; + + /*ION related*/ + int ion_fd; + int dst_ion_fd[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; +} _MFCLIB; + +#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) +#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) + +#define SSBSIP_MFC_FAIL (0) + +#endif /* __MFC_INTERFACE_H */ diff --git a/exynos/multimedia/libstagefrighthw/Android.mk b/exynos/multimedia/libstagefrighthw/Android.mk new file mode 100644 index 0000000..ce7a5e7 --- /dev/null +++ b/exynos/multimedia/libstagefrighthw/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Plugin.cpp + +LOCAL_CFLAGS += $(PV_CFLAGS_MINUS_VISIBILITY) + +LOCAL_C_INCLUDES:= \ + $(TOP)/frameworks/base/include/media/stagefright/openmax \ + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libcutils \ + libui \ + libdl \ + libsurfaceflinger_client + +LOCAL_MODULE := libstagefrighthw + +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp b/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp new file mode 100644 index 0000000..efc8691 --- /dev/null +++ b/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SEC_OMX_Plugin.h" + +#include + +#include +#include + +namespace android { + +OMXPluginBase *createOMXPlugin() { + return new SECOMXPlugin; +} + +SECOMXPlugin::SECOMXPlugin() + : mLibHandle(dlopen("libSEC_OMX_Core.so", RTLD_NOW)), + mInit(NULL), + mDeinit(NULL), + mComponentNameEnum(NULL), + mGetHandle(NULL), + mFreeHandle(NULL), + mGetRolesOfComponentHandle(NULL) { + if (mLibHandle != NULL) { + mInit = (InitFunc)dlsym(mLibHandle, "SEC_OMX_Init"); + mDeinit = (DeinitFunc)dlsym(mLibHandle, "SEC_OMX_Deinit"); + + mComponentNameEnum = + (ComponentNameEnumFunc)dlsym(mLibHandle, "SEC_OMX_ComponentNameEnum"); + + mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "SEC_OMX_GetHandle"); + mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "SEC_OMX_FreeHandle"); + + mGetRolesOfComponentHandle = + (GetRolesOfComponentFunc)dlsym( + mLibHandle, "SEC_OMX_GetRolesOfComponent"); + + (*mInit)(); + + } +} + +SECOMXPlugin::~SECOMXPlugin() { + if (mLibHandle != NULL) { + (*mDeinit)(); + + dlclose(mLibHandle); + mLibHandle = NULL; + } +} + +OMX_ERRORTYPE SECOMXPlugin::makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mGetHandle)( + reinterpret_cast(component), + const_cast(name), + appData, const_cast(callbacks)); +} + +OMX_ERRORTYPE SECOMXPlugin::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mFreeHandle)(reinterpret_cast(component)); +} + +OMX_ERRORTYPE SECOMXPlugin::enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mComponentNameEnum)(name, size, index); +} + +OMX_ERRORTYPE SECOMXPlugin::getRolesOfComponent( + const char *name, + Vector *roles) { + roles->clear(); + + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + OMX_U32 numRoles; + OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)( + const_cast(name), &numRoles, NULL); + + if (err != OMX_ErrorNone) { + return err; + } + + if (numRoles > 0) { + OMX_U8 **array = new OMX_U8 *[numRoles]; + for (OMX_U32 i = 0; i < numRoles; ++i) { + array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE]; + } + + OMX_U32 numRoles2; + err = (*mGetRolesOfComponentHandle)( + const_cast(name), &numRoles2, array); + + CHECK_EQ(err, OMX_ErrorNone); + CHECK_EQ(numRoles, numRoles2); + + for (OMX_U32 i = 0; i < numRoles; ++i) { + String8 s((const char *)array[i]); + roles->push(s); + + delete[] array[i]; + array[i] = NULL; + } + + delete[] array; + array = NULL; + } + + return OMX_ErrorNone; +} + +} // namespace android + diff --git a/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.h b/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.h new file mode 100644 index 0000000..6df2d31 --- /dev/null +++ b/exynos/multimedia/libstagefrighthw/SEC_OMX_Plugin.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SEC_OMX_PLUGIN + +#define SEC_OMX_PLUGIN + +#include + +namespace android { + +struct SECOMXPlugin : public OMXPluginBase { + SECOMXPlugin(); + virtual ~SECOMXPlugin(); + + virtual OMX_ERRORTYPE makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component); + + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component); + + virtual OMX_ERRORTYPE enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index); + + virtual OMX_ERRORTYPE getRolesOfComponent( + const char *name, + Vector *roles); + +private: + void *mLibHandle; + + typedef OMX_ERRORTYPE (*InitFunc)(); + typedef OMX_ERRORTYPE (*DeinitFunc)(); + typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)( + OMX_STRING, OMX_U32, OMX_U32); + + typedef OMX_ERRORTYPE (*GetHandleFunc)( + OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *); + + typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *); + + typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)( + OMX_STRING, OMX_U32 *, OMX_U8 **); + + InitFunc mInit; + DeinitFunc mDeinit; + ComponentNameEnumFunc mComponentNameEnum; + GetHandleFunc mGetHandle; + FreeHandleFunc mFreeHandle; + GetRolesOfComponentFunc mGetRolesOfComponentHandle; + + SECOMXPlugin(const SECOMXPlugin &); + SECOMXPlugin &operator=(const SECOMXPlugin &); +}; + +} // namespace android + +#endif // SEC_OMX_PLUGIN diff --git a/exynos/multimedia/openmax/Android.mk b/exynos/multimedia/openmax/Android.mk new file mode 100644 index 0000000..61bdff7 --- /dev/null +++ b/exynos/multimedia/openmax/Android.mk @@ -0,0 +1,38 @@ +WITH_SEC_OMX := true + +ifeq ($(WITH_SEC_OMX), true) + +LOCAL_PATH := $(call my-dir) +BOARD_USE_ANB := true + +include $(CLEAR_VARS) + +SEC_OMX_TOP := $(LOCAL_PATH) + +SEC_COPY_HEADERS_TO := libsecmm + +SEC_OMX_INC := $(SEC_OMX_TOP)/include/ +SEC_OMX_COMPONENT := $(SEC_OMX_TOP)/component + +include $(SEC_OMX_TOP)/osal/Android.mk +include $(SEC_OMX_TOP)/core/Android.mk + +include $(SEC_OMX_COMPONENT)/common/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/h264/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/mpeg4/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/vc1/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/h264/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/mpeg4/Android.mk + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(SEC_OMX_COMPONENT)/video/dec/vp8/Android.mk +endif + +ifeq ($(BOARD_USE_ALP_AUDIO), true) +include $(SEC_OMX_COMPONENT)/audio/dec/Android.mk +include $(SEC_OMX_COMPONENT)/audio/dec/mp3/Android.mk +endif + +endif diff --git a/exynos/multimedia/openmax/component/audio/dec/Android.mk b/exynos/multimedia/openmax/component/audio/dec/Android.mk new file mode 100644 index 0000000..303737b --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Adec.c + +LOCAL_MODULE := libSEC_OMX_Adec +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/audio/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.c b/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.c new file mode 100644 index 0000000..dab7247 --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.c @@ -0,0 +1,1376 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Adec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#include +#include +#include +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OMX_Adec.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_ETC.h" +#include "srp_api.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_AUDIO_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pSECPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + SEC_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = temp_buffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + SEC_OSAL_Free(temp_buffer); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { + (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, + pSECComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { + if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { + if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); + pSECPort->bufferHeader[i]->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pSECPort->assignedBufferNum--; + if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]); + pSECPort->bufferHeader[i] = NULL; + pBufferHdr = NULL; + } + pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECPort->assignedBufferNum == 0) { + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT* pSECPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + if ((pSECComponent->currentState == OMX_StateExecuting) && + (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; + secOMXInputPort->markType.hMarkTargetComponent = NULL; + secOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + if (CHECK_PORT_TUNNELED(secOMXInputPort)) { + OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); + } else { + bufferHeader->nFilledLen = 0; + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE* message = NULL; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; + dataBuffer->dataValid = OMX_TRUE; + dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; + dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; + + SEC_OSAL_Free(message); + + if (dataBuffer->allocSize <= dataBuffer->dataLen) + SEC_OSAL_Log(SEC_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; + pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; + pSECComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { + OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); + } else { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + /* reset dataBuffer */ + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE *message = NULL; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid =OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ + pSECComponent->processData[OUTPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; + pSECComponent->processData[OUTPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; + + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + + return ret; +} + +static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; + + processData->dataLen = 0; + processData->remainDataLen = 0; + processData->usedDataLen = 0; + processData->nFlags = 0; + processData->timeStamp = 0; + + return ret; +} + +OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_U32 checkedSize = 0; + OMX_BOOL flagEOF = OMX_FALSE; + OMX_BOOL previousFrameEOF = OMX_FALSE; + + FunctionIn(); + + if (inputUseBuffer->dataValid == OMX_TRUE) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + if (inputData->dataLen == 0) { + previousFrameEOF = OMX_TRUE; + } else { + previousFrameEOF = OMX_FALSE; + } + + /* Audio extractor should parse into frame units. */ + flagEOF = OMX_TRUE; + checkedSize = checkInputStreamLen; + copySize = checkedSize; + + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) + pSECComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + if (copySize > 0) + SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); + + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + inputData->dataLen += copySize; + inputData->remainDataLen += copySize; + + if (previousFrameEOF == OMX_TRUE) { + inputData->timeStamp = inputUseBuffer->timeStamp; + inputData->nFlags = inputUseBuffer->nFlags; + } + + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } else { + if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || + (inputData->dataLen == 0))) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) && + (inputData->dataLen != 0)) { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_TRUE; + } + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); + flagEOF = OMX_FALSE; + } + + if ((inputUseBuffer->remainDataLen == 0) || + (CHECK_PORT_BEING_FLUSHED(secInputPort))) + SEC_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; + } + + if (flagEOF == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + /* Flush SRP buffers */ + SRP_Flush(); + + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + SEC_OSAL_Log(SEC_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", + inputData->timeStamp, inputData->timeStamp / 1E6); + } + + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + + FunctionOut(); + + return ret; +} + +OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + FunctionIn(); + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) { + pSECComponent->checkTimeStamp.startTimeStamp = -19761123; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + ret = OMX_TRUE; + goto EXIT; + } + } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + ret = OMX_TRUE; + goto EXIT; + } + + if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = outputData->remainDataLen; + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = outputData->nFlags; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_TRUE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) || + (CHECK_PORT_BEING_FLUSHED(secOutputPort))) + SEC_OutputBufferReturn(pOMXComponent); + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); + + ret = OMX_FALSE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_AUDIODEC_COMPONENT *pVideoDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + if (((pSECComponent->currentState == OMX_StatePause) || + (pSECComponent->currentState == OMX_StateIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + while ((SEC_Check_BufferProcess_State(pSECComponent)) && (!pSECComponent->bExitBufferProcessThread)) { + SEC_OSAL_SleepMillisec(0); + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = SEC_OutputBufferGetQueue(pSECComponent); + if ((ret == OMX_ErrorUndefined) || + (secInputPort->portState != OMX_StateIdle) || + (secOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pSECComponent->remainOutputData == OMX_FALSE) { + if (pSECComponent->reInputData == OMX_FALSE) { + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = SEC_InputBufferGetQueue(pSECComponent); + break; + } + + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataDecodeYet) + pSECComponent->reInputData = OMX_TRUE; + else + pSECComponent->reInputData = OMX_FALSE; + } + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + + if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) + pSECComponent->remainOutputData = OMX_TRUE; + else + pSECComponent->remainOutputData = OMX_FALSE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pSECComponent->portParam.nPorts; + portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamAudioPortFormat: + { + OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + + if (portIndex == INPUT_PORT_INDEX) { + supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eEncoding = portDefinition->format.audio.eEncoding; + } else if (portIndex == OUTPUT_PORT_INDEX) { + supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eEncoding = portDefinition->format.audio.eEncoding; + } + ret = OMX_ErrorNone; + } + break; + default: + { + ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE SEC_OMX_AudioDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamAudioPortFormat: + { + OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + portDefinition->format.audio.eEncoding = portFormat->eEncoding; + ret = OMX_ErrorNone; + } + break; + default: + { + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigAudioMute: + { + SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_IndexConfigAudioMute"); + ret = OMX_ErrorUnsupportedIndex; + } + break; + case OMX_IndexConfigAudioVolume: + { + SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_IndexConfigAudioVolume"); + ret = OMX_ErrorUnsupportedIndex; + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pAudioDec = SEC_OSAL_Malloc(sizeof(SEC_OMX_AUDIODEC_COMPONENT)); + if (pAudioDec == NULL) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OSAL_Memset(pAudioDec, 0, sizeof(SEC_OMX_AUDIODEC_COMPONENT)); + pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pAudioDec; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_AUDIO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_AUDIO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_AUDIO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainAudio; + + pSECPort->portDefinition.format.audio.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pSECPort->portDefinition.format.audio.pNativeRender = 0; + pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_AUDIO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_AUDIO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainAudio; + + pSECPort->portDefinition.format.audio.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pSECPort->portDefinition.format.audio.pNativeRender = 0; + pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; + + + pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; + + pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; + pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; + pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; + pSECComponent->sec_BufferReset = &SEC_BufferReset; + pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; + pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OSAL_Free(pAudioDec); + pSECComponent->hComponentHandle = pAudioDec = NULL; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + SEC_OSAL_Free(pSECPort->portDefinition.format.audio.cMIMEType); + pSECPort->portDefinition.format.audio.cMIMEType = NULL; + } + + ret = SEC_OMX_Port_Destructor(pOMXComponent); + + ret = SEC_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.h b/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.h new file mode 100644 index 0000000..8ff20ab --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/SEC_OMX_Adec.h @@ -0,0 +1,132 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Adec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#ifndef SEC_OMX_AUDIO_DECODE +#define SEC_OMX_AUDIO_DECODE + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" + +#define MAX_AUDIO_INPUTBUFFER_NUM 2 +#define MAX_AUDIO_OUTPUTBUFFER_NUM 2 + +#define DEFAULT_AUDIO_INPUT_BUFFER_SIZE (16 * 1024) +#define DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE (32 * 1024) + +#define DEFAULT_AUDIO_SAMPLING_FREQ 44100 +#define DEFAULT_AUDIO_CHANNELS_NUM 2 +#define DEFAULT_AUDIO_BIT_PER_SAMPLE 16 + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 + +typedef struct _SRP_DEC_INPUT_BUFFER +{ + void *PhyAddr; // physical address + void *VirAddr; // virtual address + int bufferSize; // input buffer alloc size + int dataSize; // Data length +} SRP_DEC_INPUT_BUFFER; + +typedef struct _SEC_OMX_AUDIODEC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + + OMX_BOOL bFirstFrame; + OMX_PTR pInputBuffer; + SRP_DEC_INPUT_BUFFER SRPDecInputBuffer[MAX_AUDIO_INPUTBUFFER_NUM]; + OMX_U32 indexInputBuffer; +} SEC_OMX_AUDIODEC_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer); +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_AudioDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_AudioDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_AudioDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +} +#endif + +#endif /* SEC_OMX_AUDIO_DECODE */ diff --git a/exynos/multimedia/openmax/component/audio/dec/mp3/Android.mk b/exynos/multimedia/openmax/component/audio/dec/mp3/Android.mk new file mode 100644 index 0000000..43af655 --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/mp3/Android.mk @@ -0,0 +1,31 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Mp3dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.MP3.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Adec libsecosal libsecbasecomponent \ + libsrpapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/audio/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.c b/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.c new file mode 100644 index 0000000..a8c77f6 --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.c @@ -0,0 +1,918 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mp3dec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Adec.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "library_register.h" +#include "SEC_OMX_Mp3dec.h" +#include "srp_api.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MP3_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +//#define SRP_DUMP_TO_FILE +#ifdef SRP_DUMP_TO_FILE +#include "stdio.h" + +FILE *inFile; +FILE *outFile; +#endif + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamAudioMp3: + { + OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure; + OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL; + SEC_MP3_HANDLE *pMp3Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcMp3Param = &pMp3Dec->mp3Param; + + SEC_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); + } + break; + case OMX_IndexParamAudioPcm: + { + OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure; + OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL; + SEC_MP3_HANDLE *pMp3Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcPcmParam = &pMp3Dec->pcmParam; + + SEC_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE); + } + break; + default: + ret = SEC_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamAudioMp3: + { + OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL; + OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure; + SEC_MP3_HANDLE *pMp3Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstMp3Param = &pMp3Dec->mp3Param; + + SEC_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); + } + break; + case OMX_IndexParamAudioPcm: + { + OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL; + OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure; + SEC_MP3_HANDLE *pMp3Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstPcmParam = &pMp3Dec->pcmParam; + + SEC_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + default: + ret = SEC_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = SEC_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_MP3_HANDLE *pMp3Dec = (SEC_MP3_HANDLE *)pAudioDec->hCodecHandle; + + FunctionIn(); + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */ + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_FALSE; + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +#ifdef SRP_DUMP_TO_FILE + inFile = fopen("/data/InFile.mp3", "w+"); + outFile = fopen("/data/OutFile.pcm", "w+"); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + FunctionIn(); + +#ifdef SRP_DUMP_TO_FILE + fclose(inFile); + fclose(outFile); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_MP3_HANDLE *pMp3Dec = (SEC_MP3_HANDLE *)pAudioDec->hCodecHandle; + struct srp_dec_info codecDecInfo; + OMX_S32 returnCodec = 0; + unsigned long isSRPStopped = 0; + OMX_PTR dataBuffer = NULL; + unsigned int dataLen = 0; + OMX_BOOL isSRPIbufOverflow = OMX_FALSE; + + FunctionIn(); + +#ifdef SRP_DUMP_TO_FILE + if (pSECComponent->reInputData == OMX_FALSE) { + fwrite(pInputData->dataBuffer, pInputData->dataLen, 1, inFile); + } +#endif + + /* Save timestamp and flags of input data */ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS); + + /* Decoding mp3 frames by SRP */ + if (pSECComponent->getAllDelayBuffer == OMX_FALSE) { + returnCodec = SRP_Decode(pInputData->dataBuffer, pInputData->dataLen); + + if (returnCodec >= 0) { + if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) { + SRP_Send_EOS(); + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE; + } + } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) { + isSRPIbufOverflow = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } + } + + if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_FALSE) { + returnCodec = SRP_Get_Dec_Info(&codecDecInfo); + if (returnCodec < 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Dec_Info failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT; + } + + if (!codecDecInfo.sample_rate || !codecDecInfo.channels) { + if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { + pOutputData->dataLen = 0; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + if (isSRPIbufOverflow) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + } + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "numChannels(%d), samplingRate(%d)", + codecDecInfo.channels, codecDecInfo.sample_rate); + + if (pMp3Dec->pcmParam.nChannels != codecDecInfo.channels || + pMp3Dec->pcmParam.nSamplingRate != codecDecInfo.sample_rate) { + /* Change channel count and sampling rate information */ + pMp3Dec->pcmParam.nChannels = codecDecInfo.channels; + pMp3Dec->pcmParam.nSamplingRate = codecDecInfo.sample_rate; + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + + pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE; + + if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { + pOutputData->dataLen = 0; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + if (isSRPIbufOverflow) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + } + goto EXIT; + } + + /* Get decoded data from SRP */ + returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen); + if (dataLen > 0) { + pOutputData->dataLen = dataLen; + SEC_OSAL_Memcpy(pOutputData->dataBuffer, dataBuffer, dataLen); + } else { + pOutputData->dataLen = 0; + } + +#ifdef SRP_DUMP_TO_FILE + if (pOutputData->dataLen > 0) + fwrite(pOutputData->dataBuffer, pOutputData->dataLen, 1, outFile); +#endif + + /* Delay EOS signal until all the PCM is returned from the SRP driver. */ + if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { + if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) { + returnCodec = SRP_GetParams(SRP_STOP_EOS_STATE, &isSRPStopped); + if (returnCodec != 0) + SEC_OSAL_Log(SEC_LOG_ERROR, "Fail SRP_STOP_EOS_STATE"); + if (isSRPStopped == 1) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */ + ret = OMX_ErrorNone; + } else { + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } + } else { /* Flush after EOS */ + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; + } + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { + if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + + goto EXIT; + } + + ret = SEC_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData); + + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + SEC_MP3_HANDLE *pMp3Dec = NULL; + OMX_PTR pInputBuffer = NULL; + OMX_PTR pOutputBuffer = NULL; + unsigned int inputBufferSize = 0; + unsigned int inputBufferNum = 0; + unsigned int outputBufferSize = 0; + unsigned int outputBufferNum = 0; + OMX_S32 returnCodec; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MP3_DEC, componentName) != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_AudioDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_AUDIO_DEC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorInsufficientResources; + goto EXIT_ERROR_1; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MP3_DEC); + + pMp3Dec = SEC_OSAL_Malloc(sizeof(SEC_MP3_HANDLE)); + if (pMp3Dec == NULL) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorInsufficientResources; + goto EXIT_ERROR_2; + } + SEC_OSAL_Memset(pMp3Dec, 0, sizeof(SEC_MP3_HANDLE)); + pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; + pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec; + + /* Create and Init SRP */ + pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_FALSE; + returnCodec = SRP_Create(SRP_INIT_BLOCK_MODE); + if (returnCodec < 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Create failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_3; + } + pMp3Dec->hSRPMp3Handle.hSRPHandle = (OMX_HANDLETYPE)returnCodec; /* SRP's fd */ + returnCodec = SRP_Init(); + if (returnCodec < 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Init failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_4; + } + pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE; + + /* Get input buffer info from SRP */ + returnCodec = SRP_Get_Ibuf_Info(&pInputBuffer, &inputBufferSize, &inputBufferNum); + if (returnCodec < 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_5; + } + + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = inputBufferSize; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = SEC_OSAL_Malloc(inputBufferSize); + if (pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer == NULL) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Input data buffer alloc failed"); + ret = OMX_ErrorInsufficientResources; + goto EXIT_ERROR_5; + } + + /* Get output buffer info from SRP */ + returnCodec = SRP_Get_Obuf_Info(&pOutputBuffer, &outputBufferSize, &outputBufferNum); + if (returnCodec < 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_6; + } + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = inputBufferNum; + pSECPort->portDefinition.nBufferCountMin = inputBufferNum; + pSECPort->portDefinition.nBufferSize = inputBufferSize; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + SEC_OSAL_Memset(pSECPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/mpeg"); + pSECPort->portDefinition.format.audio.pNativeRender = 0; + pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = outputBufferNum; + pSECPort->portDefinition.nBufferCountMin = outputBufferNum; + pSECPort->portDefinition.nBufferSize = outputBufferSize; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + SEC_OSAL_Memset(pSECPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pSECPort->portDefinition.format.audio.pNativeRender = 0; + pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM; + + /* Default values for Mp3 audio param */ + INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE); + pMp3Dec->mp3Param.nPortIndex = INPUT_PORT_INDEX; + pMp3Dec->mp3Param.nChannels = DEFAULT_AUDIO_CHANNELS_NUM; + pMp3Dec->mp3Param.nBitRate = 0; + pMp3Dec->mp3Param.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ; + pMp3Dec->mp3Param.nAudioBandWidth = 0; + pMp3Dec->mp3Param.eChannelMode = OMX_AUDIO_ChannelModeStereo; + pMp3Dec->mp3Param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3; + + /* Default values for PCM audio param */ + INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE); + pMp3Dec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX; + pMp3Dec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM; + pMp3Dec->pcmParam.eNumData = OMX_NumericalDataSigned; + pMp3Dec->pcmParam.eEndian = OMX_EndianLittle; + pMp3Dec->pcmParam.bInterleaved = OMX_TRUE; + pMp3Dec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE; + pMp3Dec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ; + pMp3Dec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear; + pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF; + pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF; + + pOMXComponent->GetParameter = &SEC_SRP_Mp3Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_SRP_Mp3Dec_SetParameter; + pOMXComponent->GetConfig = &SEC_SRP_Mp3Dec_GetConfig; + pOMXComponent->SetConfig = &SEC_SRP_Mp3Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_SRP_Mp3Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_SRP_Mp3Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + /* ToDo: Change the function name associated with a specific codec */ + pSECComponent->sec_mfc_componentInit = &SEC_SRP_Mp3Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_SRP_Mp3Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_SRP_Mp3Dec_bufferProcess; + pSECComponent->sec_checkInputFrame = NULL; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + goto EXIT; /* This function is performed successfully. */ + +EXIT_ERROR_6: + SEC_OSAL_Free(pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer); + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; +EXIT_ERROR_5: + SRP_Deinit(); +EXIT_ERROR_4: + SRP_Terminate(); +EXIT_ERROR_3: + SEC_OSAL_Free(pMp3Dec); + pAudioDec->hCodecHandle = NULL; +EXIT_ERROR_2: + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; +EXIT_ERROR_1: + SEC_OMX_AudioDecodeComponentDeinit(pOMXComponent); +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MP3_HANDLE *pMp3Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + if (pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer) { + SEC_OSAL_Free(pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer); + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + } + + pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pMp3Dec != NULL) { + if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) { + SRP_Deinit(); + SRP_Terminate(); + } + SEC_OSAL_Free(pMp3Dec); + ((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_AudioDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.h b/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.h new file mode 100644 index 0000000..a8b80f5 --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/mp3/SEC_OMX_Mp3dec.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mp3dec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#ifndef SEC_OMX_MP3_DEC_COMPONENT +#define SEC_OMX_MP3_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + +typedef struct _SEC_SRP_MP3_HANDLE +{ + OMX_HANDLETYPE hSRPHandle; + OMX_BOOL bConfiguredSRP; + OMX_BOOL bSRPLoaded; + OMX_BOOL bSRPSendEOS; + OMX_S32 returnCodec; +} SEC_SRP_MP3_HANDLE; + +typedef struct _SEC_MP3_HANDLE +{ + /* OMX Codec specific */ + OMX_AUDIO_PARAM_MP3TYPE mp3Param; + OMX_AUDIO_PARAM_PCMMODETYPE pcmParam; + + /* SEC SRP Codec specific */ + SEC_SRP_MP3_HANDLE hSRPMp3Handle; +} SEC_MP3_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif /* SEC_OMX_MP3_DEC_COMPONENT */ diff --git a/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.c b/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.c new file mode 100644 index 0000000..c94377a --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.c @@ -0,0 +1,58 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MP3_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - audio decoder MP3 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MP3_DEC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MP3_DEC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.h b/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.h new file mode 100644 index 0000000..90ae8c2 --- /dev/null +++ b/exynos/multimedia/openmax/component/audio/dec/mp3/library_register.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2011.10.18 : Create + */ + +#ifndef SEC_OMX_MP3_DEC_REG +#define SEC_OMX_MP3_DEC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MP3 */ +#define SEC_OMX_COMPONENT_MP3_DEC "OMX.SEC.MP3.Decoder" +#define SEC_OMX_COMPONENT_MP3_DEC_ROLE "audio_decoder.mp3" + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif /* SEC_OMX_MP3_DEC_REG */ + diff --git a/exynos/multimedia/openmax/component/common/Android.mk b/exynos/multimedia/openmax/component/common/Android.mk new file mode 100644 index 0000000..a6f84bf --- /dev/null +++ b/exynos/multimedia/openmax/component/common/Android.mk @@ -0,0 +1,43 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Basecomponent.c \ + SEC_OMX_Baseport.c + +LOCAL_MODULE := libsecbasecomponent + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := libsecosal +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal + +include $(BUILD_STATIC_LIBRARY) + + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Resourcemanager.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libSEC_OMX_Resourcemanager + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := libsecosal +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.c b/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.c new file mode 100644 index 0000000..e615d18 --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.c @@ -0,0 +1,1535 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Basecomponent.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Event.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Resourcemanager.h" +#include "SEC_OMX_Macros.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_BASE_COMP" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* Change CHECK_SIZE_VERSION Macro */ +OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + OMX_VERSIONTYPE* version = NULL; + if (header == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32)); + if (*((OMX_U32*)header) != size) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || + version->s.nVersionMinor != VERSIONMINOR_NUMBER) { + ret = OMX_ErrorVersionMismatch; + goto EXIT; + } + ret = OMX_ErrorNone; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetComponentVersion( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE *pComponentVersion, + OMX_OUT OMX_VERSIONTYPE *pSpecVersion, + OMX_OUT OMX_UUIDTYPE *pComponentUUID) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_U32 compUUID[3]; + + FunctionIn(); + + /* check parameters */ + if (hComponent == NULL || + pComponentName == NULL || pComponentVersion == NULL || + pSpecVersion == NULL || pComponentUUID == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + SEC_OSAL_Strcpy(pComponentName, pSECComponent->componentName); + SEC_OSAL_Memcpy(pComponentVersion, &(pSECComponent->componentVersion), sizeof(OMX_VERSIONTYPE)); + SEC_OSAL_Memcpy(pSpecVersion, &(pSECComponent->specVersion), sizeof(OMX_VERSIONTYPE)); + + /* Fill UUID with handle address, PID and UID. + * This should guarantee uiniqness */ + compUUID[0] = (OMX_U32)pOMXComponent; + compUUID[1] = getpid(); + compUUID[2] = getuid(); + SEC_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID)); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetState ( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE *pState) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pState == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + *pState = pSECComponent->currentState; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_BufferProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->sec_BufferProcess(pOMXComponent); + + SEC_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_MESSAGE *message; + OMX_STATETYPE destState = messageParam; + OMX_STATETYPE currentState = pSECComponent->currentState; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 countValue = 0; + unsigned int i = 0, j = 0; + int k = 0; + + FunctionIn(); + + /* check parameters */ + if (currentState == destState) { + ret = OMX_ErrorSameState; + goto EXIT; + } + if (currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { + ret = SEC_OMX_Get_Resource(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + } + if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded)) || + ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid)) || + ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) || + ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) { + SEC_OMX_Release_Resource(pOMXComponent); + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "destState: %d", destState); + + switch (destState) { + case OMX_StateInvalid: + switch (currentState) { + case OMX_StateWaitForResources: + SEC_OMX_Out_WaitForResource(pOMXComponent); + case OMX_StateIdle: + case OMX_StateExecuting: + case OMX_StatePause: + case OMX_StateLoaded: + pSECComponent->currentState = OMX_StateInvalid; + if (pSECComponent->hBufferProcess) { + pSECComponent->bExitBufferProcessThread = OMX_TRUE; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); + if (countValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); + pSECComponent->hBufferProcess = NULL; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + } + if (pSECComponent->sec_mfc_componentTerminate != NULL) + pSECComponent->sec_mfc_componentTerminate(pOMXComponent); + + ret = OMX_ErrorInvalidState; + break; + default: + ret = OMX_ErrorInvalidState; + break; + } + break; + case OMX_StateLoaded: + switch (currentState) { + case OMX_StateIdle: + pSECComponent->bExitBufferProcessThread = OMX_TRUE; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); + if (countValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); + pSECComponent->hBufferProcess = NULL; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + + pSECComponent->sec_mfc_componentTerminate(pOMXComponent); + + for (i = 0; i < (pSECComponent->portParam.nPorts); i++) { + pSECPort = (pSECComponent->pSECPort + i); + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message != NULL) + SEC_OSAL_Free(message); + } + ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, i); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pSECPort)) { + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + } + pSECComponent->currentState = OMX_StateLoaded; + break; + case OMX_StateWaitForResources: + ret = SEC_OMX_Out_WaitForResource(pOMXComponent); + pSECComponent->currentState = OMX_StateLoaded; + break; + case OMX_StateExecuting: + case OMX_StatePause: + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StateIdle: + switch (currentState) { + case OMX_StateLoaded: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = (pSECComponent->pSECPort + i); + if (pSECPort == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, i); + if (ret!=OMX_ErrorNone) + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pSECPort)) { + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[i].loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } + } + ret = pSECComponent->sec_mfc_componentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + goto EXIT; + } + pSECComponent->bExitBufferProcessThread = OMX_FALSE; + SEC_OSAL_SignalCreate(&pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + ret = SEC_OSAL_SemaphoreCreate(&pSECComponent->pSECPort[i].bufferSemID); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + ret = SEC_OSAL_MutexCreate(&pSECComponent->secDataBuffer[i].bufferMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + } + ret = SEC_OSAL_ThreadCreate(&pSECComponent->hBufferProcess, + SEC_OMX_BufferProcessThread, + pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pSECComponent->currentState = OMX_StateIdle; + break; + case OMX_StateExecuting: + case OMX_StatePause: + SEC_OMX_BufferFlushProcessNoEvent(pOMXComponent, ALL_PORT_INDEX); + pSECComponent->currentState = OMX_StateIdle; + break; + case OMX_StateWaitForResources: + pSECComponent->currentState = OMX_StateIdle; + break; + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StateExecuting: + switch (currentState) { + case OMX_StateLoaded: + ret = OMX_ErrorIncorrectStateTransition; + break; + case OMX_StateIdle: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { + for (j = 0; j < pSECPort->tunnelBufferNum; j++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + } + } + + pSECComponent->transientState = SEC_OMX_TransStateMax; + pSECComponent->currentState = OMX_StateExecuting; + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + break; + case OMX_StatePause: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { + OMX_S32 semaValue = 0, cnt = 0; + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &semaValue); + if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > semaValue) { + cnt = SEC_OSAL_GetElemNum(&pSECPort->bufferQ) - semaValue; + for (k = 0; k < cnt; k++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + } + } + } + + pSECComponent->currentState = OMX_StateExecuting; + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + break; + case OMX_StateWaitForResources: + ret = OMX_ErrorIncorrectStateTransition; + break; + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StatePause: + switch (currentState) { + case OMX_StateLoaded: + ret = OMX_ErrorIncorrectStateTransition; + break; + case OMX_StateIdle: + pSECComponent->currentState = OMX_StatePause; + break; + case OMX_StateExecuting: + pSECComponent->currentState = OMX_StatePause; + break; + case OMX_StateWaitForResources: + ret = OMX_ErrorIncorrectStateTransition; + break; + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StateWaitForResources: + switch (currentState) { + case OMX_StateLoaded: + ret = SEC_OMX_In_WaitForResource(pOMXComponent); + pSECComponent->currentState = OMX_StateWaitForResources; + break; + case OMX_StateIdle: + case OMX_StateExecuting: + case OMX_StatePause: + ret = OMX_ErrorIncorrectStateTransition; + break; + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECComponent->pCallbacks != NULL) { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, OMX_CommandStateSet, + destState, NULL); + } + } else { + if (pSECComponent->pCallbacks != NULL) { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_MessageHandlerThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + OMX_U32 messageType = 0, portIndex = 0; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + while (pSECComponent->bExitMessageHandlerThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pSECComponent->msgSemaphoreHandle); + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECComponent->messageQ); + if (message != NULL) { + messageType = message->messageType; + switch (messageType) { + case OMX_CommandStateSet: + ret = SEC_OMX_ComponentStateSet(pOMXComponent, message->messageParam); + break; + case OMX_CommandFlush: + ret = SEC_OMX_BufferFlushProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandPortDisable: + ret = SEC_OMX_PortDisableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandPortEnable: + ret = SEC_OMX_PortEnableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandMarkBuffer: + portIndex = message->messageParam; + pSECComponent->pSECPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent; + pSECComponent->pSECPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData; + break; + case (OMX_COMMANDTYPE)SEC_OMX_CommandComponentDeInit: + pSECComponent->bExitMessageHandlerThread = OMX_TRUE; + break; + default: + break; + } + SEC_OSAL_Free(message); + message = NULL; + } + } + + SEC_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_StateSet(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_U32 destState = nParam; + OMX_U32 i = 0; + + if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateLoaded)) { + pSECComponent->transientState = SEC_OMX_TransStateLoadedToIdle; + for(i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateIdle; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateLoaded) && (pSECComponent->currentState == OMX_StateIdle)) { + pSECComponent->transientState = SEC_OMX_TransStateIdleToLoaded; + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateLoaded; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateLoaded"); + } else if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateExecuting)) { + pSECComponent->transientState = SEC_OMX_TransStateExecutingToIdle; + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateExecuting) && (pSECComponent->currentState == OMX_StateIdle)) { + pSECComponent->transientState = SEC_OMX_TransStateIdleToExecuting; + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateExecuting"); + } else if (destState == OMX_StateInvalid) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateInvalid; + } + } + + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE SEC_SetPortFlush(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0, index = 0; + + + if ((pSECComponent->currentState == OMX_StateExecuting) || + (pSECComponent->currentState == OMX_StatePause)) { + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + /********************* + * need flush event set ????? + **********************/ + cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + for (i = 0; i < cnt; i++) { + if (portIndex == ALL_PORT_INDEX) + index = i; + else + index = portIndex; + pSECComponent->pSECPort[index].bIsPortFlushed = OMX_TRUE; + } + } else { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE SEC_SetPortEnable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pSECPort->portState = OMX_StateIdle; + } + } + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pSECPort->portState = OMX_StateIdle; + } + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_SetPortDisable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (!CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + pSECPort->portState = OMX_StateLoaded; + pSECPort->bIsPortDisabled = OMX_TRUE; + } + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portState = OMX_StateLoaded; + pSECPort->bIsPortDisabled = OMX_TRUE; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_SetMarkBuffer(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + + if (nParam >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECComponent->currentState == OMX_StateExecuting) || + (pSECComponent->currentState == OMX_StatePause)) { + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorIncorrectStateOperation; + } + +EXIT: + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_CommandQueue( + SEC_OMX_BASECOMPONENT *pSECComponent, + OMX_COMMANDTYPE Cmd, + OMX_U32 nParam, + OMX_PTR pCmdData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_MESSAGE *command = (SEC_OMX_MESSAGE *)SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + + if (command == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + command->messageType = (OMX_U32)Cmd; + command->messageParam = nParam; + command->pCmdData = pCmdData; + + ret = SEC_OSAL_Queue(&pSECComponent->messageQ, (void *)command); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + ret = SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SendCommand( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam, + OMX_IN OMX_PTR pCmdData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (Cmd) { + case OMX_CommandStateSet : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandStateSet"); + SEC_StateSet(pSECComponent, nParam); + break; + case OMX_CommandFlush : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandFlush"); + ret = SEC_SetPortFlush(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortDisable : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortDisable"); + ret = SEC_SetPortDisable(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortEnable : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortEnable"); + ret = SEC_SetPortEnable(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandMarkBuffer : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandMarkBuffer"); + ret = SEC_SetMarkBuffer(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; +/* + case SEC_CommandFillBuffer : + case SEC_CommandEmptyBuffer : + case SEC_CommandDeInit : +*/ + default: + break; + } + + ret = SEC_OMX_CommandQueue(pSECComponent, Cmd, nParam, pCmdData); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case (OMX_INDEXTYPE)OMX_COMPONENT_CAPABILITY_TYPE_INDEX: + { + /* For Android PV OpenCORE */ + OMXComponentCapabilityFlagsType *capabilityFlags = (OMXComponentCapabilityFlagsType *)ComponentParameterStructure; + SEC_OSAL_Memcpy(capabilityFlags, &pSECComponent->capabilityFlags, sizeof(OMXComponentCapabilityFlagsType)); + } + break; + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + portParam->nPorts = 0; + portParam->nStartPortNumber = 0; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + compPriority->nGroupID = pSECComponent->compPriority.nGroupID; + compPriority->nGroupPriority = pSECComponent->compPriority.nGroupPriority; + } + break; + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if ((pSECComponent->currentState == OMX_StateLoaded) || + (pSECComponent->currentState == OMX_StateWaitForResources)) { + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + + if (pSECPort->portDefinition.eDir == OMX_DirInput) { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; + } else if (CHECK_PORT_TUNNELED(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + } else { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else if (CHECK_PORT_TUNNELED(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; + } else { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + } + } + else + { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + break; + default: + { + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + + ret = OMX_ErrorNone; + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && + (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorUndefined; + /* SEC_OSAL_Memcpy(&pSECComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */ + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (portDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, portDefinition, portDefinition->nSize); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + if ((pSECComponent->currentState != OMX_StateLoaded) && + (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECComponent->compPriority.nGroupID = compPriority->nGroupID; + pSECComponent->compPriority.nGroupPriority = compPriority->nGroupPriority; + } + break; + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pSECPort) == 0) { + ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/ + goto EXIT; + } + + if (pSECPort->portDefinition.eDir == OMX_DirInput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorNone; + } + */ + pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pSECPort->tunneledPort; + ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pSECPort->tunneledPort; + ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + } + goto EXIT; + } + } else if (pSECPort->portDefinition.eDir == OMX_DirOutput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; + ret = OMX_ErrorNone; + } + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorNone; + } + */ + pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + break; + default: + { + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + + ret = OMX_ErrorNone; + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = OMX_ErrorUnsupportedIndex; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = OMX_ErrorUnsupportedIndex; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = OMX_ErrorBadParameter; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetCallbacks ( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pCallbacks == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (pSECComponent->currentState != OMX_StateLoaded) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECComponent->pCallbacks = pCallbacks; + pSECComponent->callbackData = pAppData; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_UseEGLImage( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void *eglImage) +{ + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE SEC_OMX_BaseComponent_Constructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASECOMPONENT)); + if (pSECComponent == NULL) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent, 0, sizeof(SEC_OMX_BASECOMPONENT)); + pOMXComponent->pComponentPrivate = (OMX_PTR)pSECComponent; + + ret = SEC_OSAL_SemaphoreCreate(&pSECComponent->msgSemaphoreHandle); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + ret = SEC_OSAL_MutexCreate(&pSECComponent->compMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent->bExitMessageHandlerThread = OMX_FALSE; + SEC_OSAL_QueueCreate(&pSECComponent->messageQ); + ret = SEC_OSAL_ThreadCreate(&pSECComponent->hMessageHandler, SEC_OMX_MessageHandlerThread, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pOMXComponent->GetComponentVersion = &SEC_OMX_GetComponentVersion; + pOMXComponent->SendCommand = &SEC_OMX_SendCommand; + pOMXComponent->GetState = &SEC_OMX_GetState; + pOMXComponent->SetCallbacks = &SEC_OMX_SetCallbacks; + pOMXComponent->UseEGLImage = &SEC_OMX_UseEGLImage; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BaseComponent_Destructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 semaValue = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OMX_CommandQueue(pSECComponent, SEC_OMX_CommandComponentDeInit, 0, NULL); + SEC_OSAL_SleepMillisec(0); + SEC_OSAL_Get_SemaphoreCount(pSECComponent->msgSemaphoreHandle, &semaValue); + if (semaValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + + SEC_OSAL_ThreadTerminate(pSECComponent->hMessageHandler); + pSECComponent->hMessageHandler = NULL; + + SEC_OSAL_MutexTerminate(pSECComponent->compMutex); + pSECComponent->compMutex = NULL; + SEC_OSAL_SemaphoreTerminate(pSECComponent->msgSemaphoreHandle); + pSECComponent->msgSemaphoreHandle = NULL; + SEC_OSAL_QueueTerminate(&pSECComponent->messageQ); + + SEC_OSAL_Free(pSECComponent); + pSECComponent = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + + diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.h b/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.h new file mode 100644 index 0000000..5cedc4d --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Basecomponent.h @@ -0,0 +1,191 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Basecomponent.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_BASECOMP +#define SEC_OMX_BASECOMP + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" + + +typedef struct _SEC_OMX_MESSAGE +{ + OMX_U32 messageType; + OMX_U32 messageParam; + OMX_PTR pCmdData; +} SEC_OMX_MESSAGE; + +typedef struct _SEC_OMX_DATABUFFER +{ + OMX_HANDLETYPE bufferMutex; + OMX_BUFFERHEADERTYPE* bufferHeader; + OMX_BOOL dataValid; + OMX_U32 allocSize; + OMX_U32 dataLen; + OMX_U32 usedDataLen; + OMX_U32 remainDataLen; + OMX_U32 nFlags; + OMX_TICKS timeStamp; +} SEC_OMX_DATABUFFER; + +typedef struct _SEC_OMX_DATA +{ + OMX_BYTE dataBuffer; + OMX_U32 allocSize; + OMX_U32 dataLen; + OMX_U32 usedDataLen; + OMX_U32 remainDataLen; + OMX_U32 previousDataLen; + OMX_U32 nFlags; + OMX_TICKS timeStamp; +} SEC_OMX_DATA; + +/* for Check TimeStamp after Seek */ +typedef struct _SEC_OMX_TIMESTAPM +{ + OMX_BOOL needSetStartTimeStamp; + OMX_BOOL needCheckStartTimeStamp; + OMX_TICKS startTimeStamp; + OMX_U32 nStartFlags; +} SEC_OMX_TIMESTAMP; + +typedef struct _SEC_OMX_BASECOMPONENT +{ + OMX_STRING componentName; + OMX_VERSIONTYPE componentVersion; + OMX_VERSIONTYPE specVersion; + + OMX_STATETYPE currentState; + SEC_OMX_TRANS_STATETYPE transientState; + + SEC_CODEC_TYPE codecType; + SEC_OMX_PRIORITYMGMTTYPE compPriority; + OMX_MARKTYPE propagateMarkType; + OMX_HANDLETYPE compMutex; + + OMX_HANDLETYPE hComponentHandle; + + /* Message Handler */ + OMX_BOOL bExitMessageHandlerThread; + OMX_HANDLETYPE hMessageHandler; + OMX_HANDLETYPE msgSemaphoreHandle; + SEC_QUEUE messageQ; + + /* Buffer Process */ + OMX_BOOL bExitBufferProcessThread; + OMX_HANDLETYPE hBufferProcess; + + /* Buffer */ + SEC_OMX_DATABUFFER secDataBuffer[2]; + + /* Data */ + SEC_OMX_DATA processData[2]; + + /* Port */ + OMX_PORT_PARAM_TYPE portParam; + SEC_OMX_BASEPORT *pSECPort; + + OMX_HANDLETYPE pauseEvent; + + /* Callback function */ + OMX_CALLBACKTYPE *pCallbacks; + OMX_PTR callbackData; + + /* Save Timestamp */ + OMX_TICKS timeStamp[MAX_TIMESTAMP]; + SEC_OMX_TIMESTAMP checkTimeStamp; + + /* Save Flags */ + OMX_U32 nFlags[MAX_FLAGS]; + + OMX_BOOL getAllDelayBuffer; + OMX_BOOL remainOutputData; + OMX_BOOL reInputData; + + /* Android CapabilityFlags */ + OMXComponentCapabilityFlagsType capabilityFlags; + + OMX_BOOL bUseFlagEOF; + OMX_BOOL bSaveFlagEOS; + + OMX_ERRORTYPE (*sec_mfc_componentInit)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_mfc_componentTerminate)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_mfc_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData); + + OMX_ERRORTYPE (*sec_AllocateTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_FreeTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_BufferProcess)(OMX_HANDLETYPE hComponent); + OMX_ERRORTYPE (*sec_BufferReset)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_InputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_OutputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); + + int (*sec_checkInputFrame)(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); + +} SEC_OMX_BASECOMPONENT; + +OMX_ERRORTYPE SEC_OMX_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE SEC_OMX_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE SEC_OMX_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + +OMX_ERRORTYPE SEC_OMX_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + +OMX_ERRORTYPE SEC_OMX_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); + +OMX_ERRORTYPE SEC_OMX_BaseComponent_Constructor(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_BaseComponent_Destructor(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +extern "C" { +#endif + + OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size); + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.c b/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.c new file mode 100644 index 0000000..3bd37f5 --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.c @@ -0,0 +1,1014 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Baseport.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Mutex.h" + +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_BASE_PORT" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + SEC_OMX_MESSAGE *message = NULL; + OMX_U32 flushNum = 0; + OMX_S32 semValue = 0; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &semValue); + if (semValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message != NULL) { + bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; + bufferHeader->nFilledLen = 0; + + if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if (portIndex) { + OMX_EmptyThisBuffer(pSECPort->tunneledComponent, bufferHeader); + } else { + OMX_FillThisBuffer(pSECPort->tunneledComponent, bufferHeader); + } + SEC_OSAL_Free(message); + message = NULL; + } else if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Tunneled mode is not working, Line:%d", __LINE__); + ret = OMX_ErrorNotImplemented; + SEC_OSAL_Queue(&pSECPort->bufferQ, pSECPort); + goto EXIT; + } else { + if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } else { + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + + SEC_OSAL_Free(message); + message = NULL; + } + } + } + + if (pSECComponent->secDataBuffer[portIndex].dataValid == OMX_TRUE) { + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + message->pCmdData = pSECComponent->secDataBuffer[portIndex].bufferHeader; + message->messageType = 0; + message->messageParam = -1; + SEC_OSAL_Queue(&pSECPort->bufferQ, message); + pSECComponent->sec_BufferReset(pOMXComponent, portIndex); + } else { + if (portIndex == INPUT_PORT_INDEX) + pSECComponent->sec_InputBufferReturn(pOMXComponent); + else if (portIndex == OUTPUT_PORT_INDEX) + pSECComponent->sec_OutputBufferReturn(pOMXComponent); + } + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) < (int)pSECPort->assignedBufferNum) { + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + } + if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) != (int)pSECPort->assignedBufferNum) + SEC_OSAL_SetElemNum(&pSECPort->bufferQ, pSECPort->assignedBufferNum); + } else { + while(1) { + OMX_S32 cnt = 0; + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &cnt); + if (cnt <= 0) + break; + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + } + SEC_OSAL_SetElemNum(&pSECPort->bufferQ, 0); + } + + pSECComponent->processData[portIndex].dataLen = 0; + pSECComponent->processData[portIndex].nFlags = 0; + pSECComponent->processData[portIndex].remainDataLen = 0; + pSECComponent->processData[portIndex].timeStamp = 0; + pSECComponent->processData[portIndex].usedDataLen = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (ret == OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_TRACE,"OMX_CommandFlush EventCmdComplete"); + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandFlush, portIndex, NULL); + } + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } else if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->remainOutputData = OMX_FALSE; + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } else if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->remainOutputData = OMX_FALSE; + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE SEC_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, portIndex); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + pSECPort->portDefinition.bPopulated = OMX_TRUE; + if (pSECComponent->currentState == OMX_StateExecuting) { + for (i=0; itunnelBufferNum; i++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); + } + } + } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } else { + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = SEC_OMX_EnablePort(pOMXComponent, portIndex); + if (ret == OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortEnable, portIndex, NULL); + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 i = 0, elemNum = 0; + SEC_OMX_MESSAGE *message; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if (!CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pSECComponent->currentState!=OMX_StateLoaded) { + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + SEC_OSAL_Free(message); + } + ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, portIndex); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->portDefinition.bPopulated = OMX_FALSE; + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + } else { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + SEC_OSAL_Free(message); + } + } + pSECPort->portDefinition.bPopulated = OMX_FALSE; + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + } + } + pSECPort->portDefinition.bEnabled = OMX_FALSE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + /* port flush*/ + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } else if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->remainOutputData = OMX_FALSE; + } + } + + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = SEC_OMX_DisablePort(pOMXComponent, portIndex); + pSECComponent->pSECPort[portIndex].bIsPortDisabled = OMX_FALSE; + if (ret == OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortDisable, portIndex, NULL); + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_EmptyThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + SEC_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateIdle) && + (pSECComponent->currentState != OMX_StateExecuting) && + (pSECComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pSECPort)) || + ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && + (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || + ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pSECPort->bufferHeader[i]) { + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } else { + ret = OMX_ErrorNone; + } + + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + message->messageType = SEC_OMX_CommandEmptyBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + ret = SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + ret = SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FillThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + SEC_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateIdle) && + (pSECComponent->currentState != OMX_StateExecuting) && + (pSECComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pSECPort)) || + ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && + (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || + ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pSECPort->bufferHeader[i]) { + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } else { + ret = OMX_ErrorNone; + } + + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + message->messageType = SEC_OMX_CommandFillBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + ret = SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + INIT_SET_SIZE_VERSION(&pSECComponent->portParam, OMX_PORT_PARAM_TYPE); + pSECComponent->portParam.nPorts = ALL_PORT_NUM; + pSECComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; + + pSECPort = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); + if (pSECPort == NULL) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECPort, 0, sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); + pSECComponent->pSECPort = pSECPort; + + /* Input Port */ + pSECInputPort = &pSECPort[INPUT_PORT_INDEX]; + + SEC_OSAL_QueueCreate(&pSECInputPort->bufferQ); + + pSECInputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + if (pSECInputPort->bufferHeader == NULL) { + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECInputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + + pSECInputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pSECInputPort->bufferStateAllocate == NULL) { + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pSECInputPort->bufferSemID = NULL; + pSECInputPort->assignedBufferNum = 0; + pSECInputPort->portState = OMX_StateMax; + pSECInputPort->bIsPortFlushed = OMX_FALSE; + pSECInputPort->bIsPortDisabled = OMX_FALSE; + pSECInputPort->tunneledComponent = NULL; + pSECInputPort->tunneledPort = 0; + pSECInputPort->tunnelBufferNum = 0; + pSECInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pSECInputPort->tunnelFlags = 0; + ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->loadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pSECInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pSECInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; + pSECInputPort->portDefinition.eDir = OMX_DirInput; + pSECInputPort->portDefinition.nBufferCountActual = 0; + pSECInputPort->portDefinition.nBufferCountMin = 0; + pSECInputPort->portDefinition.nBufferSize = 0; + pSECInputPort->portDefinition.bEnabled = OMX_FALSE; + pSECInputPort->portDefinition.bPopulated = OMX_FALSE; + pSECInputPort->portDefinition.eDomain = OMX_PortDomainMax; + pSECInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pSECInputPort->portDefinition.nBufferAlignment = 0; + pSECInputPort->markType.hMarkTargetComponent = NULL; + pSECInputPort->markType.pMarkData = NULL; + + /* Output Port */ + pSECOutputPort = &pSECPort[OUTPUT_PORT_INDEX]; + + SEC_OSAL_QueueCreate(&pSECOutputPort->bufferQ); + + pSECOutputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + if (pSECOutputPort->bufferHeader == NULL) { + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(pSECOutputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + + pSECOutputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pSECOutputPort->bufferStateAllocate == NULL) { + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(pSECOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pSECOutputPort->bufferSemID = NULL; + pSECOutputPort->assignedBufferNum = 0; + pSECOutputPort->portState = OMX_StateMax; + pSECOutputPort->bIsPortFlushed = OMX_FALSE; + pSECOutputPort->bIsPortDisabled = OMX_FALSE; + pSECOutputPort->tunneledComponent = NULL; + pSECOutputPort->tunneledPort = 0; + pSECOutputPort->tunnelBufferNum = 0; + pSECOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pSECOutputPort->tunnelFlags = 0; + ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->loadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); + pSECOutputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_SemaphoreTerminate(pSECOutputPort->loadedResource); + pSECOutputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); + pSECOutputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pSECOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pSECOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; + pSECOutputPort->portDefinition.eDir = OMX_DirOutput; + pSECOutputPort->portDefinition.nBufferCountActual = 0; + pSECOutputPort->portDefinition.nBufferCountMin = 0; + pSECOutputPort->portDefinition.nBufferSize = 0; + pSECOutputPort->portDefinition.bEnabled = OMX_FALSE; + pSECOutputPort->portDefinition.bPopulated = OMX_FALSE; + pSECOutputPort->portDefinition.eDomain = OMX_PortDomainMax; + pSECOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pSECOutputPort->portDefinition.nBufferAlignment = 0; + pSECOutputPort->markType.hMarkTargetComponent = NULL; + pSECOutputPort->markType.pMarkData = NULL; + + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.startTimeStamp = 0; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + + pOMXComponent->EmptyThisBuffer = &SEC_OMX_EmptyThisBuffer; + pOMXComponent->FillThisBuffer = &SEC_OMX_FillThisBuffer; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + int i = 0; + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + for (i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + + SEC_OSAL_SemaphoreTerminate(pSECPort->loadedResource); + pSECPort->loadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECPort->unloadedResource); + pSECPort->unloadedResource = NULL; + SEC_OSAL_Free(pSECPort->bufferStateAllocate); + pSECPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECPort->bufferHeader); + pSECPort->bufferHeader = NULL; + + SEC_OSAL_QueueTerminate(&pSECPort->bufferQ); + } + SEC_OSAL_Free(pSECComponent->pSECPort); + pSECComponent->pSECPort = NULL; + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.h b/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.h new file mode 100644 index 0000000..a69a443 --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Baseport.h @@ -0,0 +1,95 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Baseport.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_BASE_PORT +#define SEC_OMX_BASE_PORT + + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" + + +#define BUFFER_STATE_ALLOCATED (1 << 0) +#define BUFFER_STATE_ASSIGNED (1 << 1) +#define HEADER_STATE_ALLOCATED (1 << 2) +#define BUFFER_STATE_FREE 0 + +#define MAX_BUFFER_NUM 20 + +#define INPUT_PORT_INDEX 0 +#define OUTPUT_PORT_INDEX 1 +#define ALL_PORT_INDEX -1 +#define ALL_PORT_NUM 2 + +typedef struct _SEC_OMX_BASEPORT +{ + OMX_BUFFERHEADERTYPE **bufferHeader; + OMX_U32 *bufferStateAllocate; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + OMX_HANDLETYPE bufferSemID; + SEC_QUEUE bufferQ; + OMX_U32 assignedBufferNum; + OMX_STATETYPE portState; + OMX_HANDLETYPE loadedResource; + OMX_HANDLETYPE unloadedResource; + + OMX_BOOL bIsPortFlushed; + OMX_BOOL bIsPortDisabled; + OMX_MARKTYPE markType; + + OMX_CONFIG_RECTTYPE cropRectangle; + + /* Tunnel Info */ + OMX_HANDLETYPE tunneledComponent; + OMX_U32 tunneledPort; + OMX_U32 tunnelBufferNum; + OMX_BUFFERSUPPLIERTYPE bufferSupplier; + OMX_U32 tunnelFlags; + + OMX_BOOL bIsANBEnabled; + OMX_BOOL bStoreMetaData; +} SEC_OMX_BASEPORT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + + +#endif diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c new file mode 100644 index 0000000..6a2c979 --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c @@ -0,0 +1,478 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Resourcemanager.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Resourcemanager.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_RM" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +#define MAX_RESOURCE_VIDEO_DEC 3 /* for Android */ +#define MAX_RESOURCE_VIDEO_ENC 1 /* for Android */ + +/* Max allowable video scheduler component instance */ +static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL; +static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL; +static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL; +static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL; +static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; + + +OMX_ERRORTYPE addElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (*ppList != NULL) { + pTempComp = *ppList; + while (pTempComp->pNext != NULL) { + pTempComp = pTempComp->pNext; + } + pTempComp->pNext = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); + if (pTempComp->pNext == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL; + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent; + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pSECComponent->compPriority.nGroupPriority; + goto EXIT; + } else { + *ppList = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); + if (*ppList == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pTempComp = *ppList; + pTempComp->pNext = NULL; + pTempComp->pOMXStandComp = pOMXComponent; + pTempComp->groupPriority = pSECComponent->compPriority.nGroupPriority; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE removeElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pPrevComp = NULL; + OMX_BOOL bDetectComp = OMX_FALSE; + + if (*ppList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pCurrComp = *ppList; + while (pCurrComp != NULL) { + if (pCurrComp->pOMXStandComp == pOMXComponent) { + if (*ppList == pCurrComp) { + *ppList = pCurrComp->pNext; + SEC_OSAL_Free(pCurrComp); + } else { + if (pPrevComp != NULL) + pPrevComp->pNext = pCurrComp->pNext; + + SEC_OSAL_Free(pCurrComp); + } + bDetectComp = OMX_TRUE; + break; + } else { + pPrevComp = pCurrComp; + pCurrComp = pCurrComp->pNext; + } + } + + if (bDetectComp == OMX_FALSE) + ret = OMX_ErrorComponentNotFound; + else + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +int searchLowPriority(SEC_OMX_RM_COMPONENT_LIST *RMComp_list, OMX_U32 inComp_priority, SEC_OMX_RM_COMPONENT_LIST **outLowComp) +{ + int ret = 0; + SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL; + + if (RMComp_list == NULL) + ret = -1; + + pTempComp = RMComp_list; + *outLowComp = 0; + + while (pTempComp != NULL) { + if (pTempComp->groupPriority > inComp_priority) { + if (pCandidateComp != NULL) { + if (pCandidateComp->groupPriority < pTempComp->groupPriority) + pCandidateComp = pTempComp; + } else { + pCandidateComp = pTempComp; + } + } + + pTempComp = pTempComp->pNext; + } + + *outLowComp = pCandidateComp; + if (pCandidateComp == NULL) + ret = 0; + else + ret = 1; + +EXIT: + return ret; +} + +OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateIdle) { + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, pSECComponent->callbackData, + OMX_EventError, OMX_ErrorResourcesLost, 0, NULL); + ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else if ((pSECComponent->currentState == OMX_StateExecuting) || (pSECComponent->currentState == OMX_StatePause)) { + /* Todo */ + } + + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Init() +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + ret = SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex); + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit() +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pCurrComponent; + SEC_OMX_RM_COMPONENT_LIST *pNextComponent; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + if (gpVideoDecRMComponentList) { + pCurrComponent = gpVideoDecRMComponentList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoDecRMComponentList = NULL; + } + if (gpVideoDecRMWaitingList) { + pCurrComponent = gpVideoDecRMWaitingList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoDecRMWaitingList = NULL; + } + + if (gpVideoEncRMComponentList) { + pCurrComponent = gpVideoEncRMComponentList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoEncRMComponentList = NULL; + } + if (gpVideoEncRMWaitingList) { + pCurrComponent = gpVideoEncRMWaitingList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoEncRMWaitingList = NULL; + } + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + SEC_OSAL_MutexTerminate(ghVideoRMComponentListMutex); + ghVideoRMComponentListMutex = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; + int numElem = 0; + int lowCompDetect = 0; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) { + pComponentTemp = gpVideoDecRMComponentList; + if (pComponentTemp != NULL) { + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + } else { + numElem = 0; + } + if (numElem >= MAX_RESOURCE_VIDEO_DEC) { + lowCompDetect = searchLowPriority(gpVideoDecRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate); + if (lowCompDetect <= 0) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeComponent(pComponentCandidate->pOMXStandComp); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeElementList(&gpVideoDecRMComponentList, pComponentCandidate->pOMXStandComp); + ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + } else { + ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) { + pComponentTemp = gpVideoEncRMComponentList; + if (pComponentTemp != NULL) { + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + } else { + numElem = 0; + } + if (numElem >= MAX_RESOURCE_VIDEO_ENC) { + lowCompDetect = searchLowPriority(gpVideoEncRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate); + if (lowCompDetect <= 0) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeComponent(pComponentCandidate->pOMXStandComp); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeElementList(&gpVideoEncRMComponentList, pComponentCandidate->pOMXStandComp); + ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + } else { + ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + ret = OMX_ErrorNone; + +EXIT: + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; + int numElem = 0; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) { + pComponentTemp = gpVideoDecRMWaitingList; + if (gpVideoDecRMComponentList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = removeElementList(&gpVideoDecRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + if (numElem > 0) { + pOMXWaitComponent = gpVideoDecRMWaitingList->pOMXStandComp; + removeElementList(&gpVideoDecRMWaitingList, pOMXWaitComponent); + ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + } + } else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) { + pComponentTemp = gpVideoEncRMWaitingList; + if (gpVideoEncRMComponentList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = removeElementList(&gpVideoEncRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + if (numElem > 0) { + pOMXWaitComponent = gpVideoEncRMWaitingList->pOMXStandComp; + removeElementList(&gpVideoEncRMWaitingList, pOMXWaitComponent); + ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + } + } + +EXIT: + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) + ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent); + else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) + ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent); + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) + ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent); + else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) + ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent); + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.h b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.h new file mode 100644 index 0000000..e78b378 --- /dev/null +++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Resourcemanager.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_RESOURCEMANAGER +#define SEC_OMX_RESOURCEMANAGER + + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + + +struct SEC_OMX_RM_COMPONENT_LIST; +typedef struct _SEC_OMX_RM_COMPONENT_LIST +{ + OMX_COMPONENTTYPE *pOMXStandComp; + OMX_U32 groupPriority; + struct _SEC_OMX_RM_COMPONENT_LIST *pNext; +} SEC_OMX_RM_COMPONENT_LIST; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Init(); +OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit(); +OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/Android.mk b/exynos/multimedia/openmax/component/video/dec/Android.mk new file mode 100644 index 0000000..349be6f --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Vdec.c + +LOCAL_MODULE := libSEC_OMX_Vdec +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_STATIC_LIBRARIES := libsecosal +LOCAL_CFLAGS += -DUSE_ANB +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.c b/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.c new file mode 100644 index 0000000..80d2a50 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.c @@ -0,0 +1,1505 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vdec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_ETC.h" + +#ifdef USE_ANB +#include "SEC_OSAL_Android.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VIDEO_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((secOutputPort->portDefinition.format.video.nFrameWidth != + secInputPort->portDefinition.format.video.nFrameWidth) || + (secOutputPort->portDefinition.format.video.nFrameHeight != + secInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + secOutputPort->portDefinition.format.video.nFrameWidth = + secInputPort->portDefinition.format.video.nFrameWidth; + secOutputPort->portDefinition.format.video.nFrameHeight = + secInputPort->portDefinition.format.video.nFrameHeight; + width = secOutputPort->portDefinition.format.video.nStride = + secInputPort->portDefinition.format.video.nStride; + height = secOutputPort->portDefinition.format.video.nSliceHeight = + secInputPort->portDefinition.format.video.nSliceHeight; + + switch(secOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + if (width && height) + secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + width = secOutputPort->portDefinition.format.video.nFrameWidth; + height = secOutputPort->portDefinition.format.video.nFrameHeight; + if (width && height) { + secOutputPort->portDefinition.nBufferSize = + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height/2)); + } + break; + default: + if (width && height) + secOutputPort->portDefinition.nBufferSize = width * height * 2; + break; + } + } + + return ; +} + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pSECPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + SEC_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = temp_buffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + SEC_OSAL_Free(temp_buffer); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { + (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, + pSECComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { + if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { + if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); + pSECPort->bufferHeader[i]->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pSECPort->assignedBufferNum--; + if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]); + pSECPort->bufferHeader[i] = NULL; + pBufferHdr = NULL; + } + pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECPort->assignedBufferNum == 0) { + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT* pSECPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + if ((pSECComponent->currentState == OMX_StateExecuting) && + (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; + secOMXInputPort->markType.hMarkTargetComponent = NULL; + secOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + if (CHECK_PORT_TUNNELED(secOMXInputPort)) { + OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); + } else { + bufferHeader->nFilledLen = 0; + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE* message = NULL; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; + dataBuffer->dataValid = OMX_TRUE; + dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; + dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; + + SEC_OSAL_Free(message); + + if (dataBuffer->allocSize <= dataBuffer->dataLen) + SEC_OSAL_Log(SEC_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; + pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; + pSECComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { + OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); + } else { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + /* reset dataBuffer */ + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE *message = NULL; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid =OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ + pSECComponent->processData[OUTPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; + pSECComponent->processData[OUTPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; + + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + + return ret; +} + +static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; + + processData->dataLen = 0; + processData->remainDataLen = 0; + processData->usedDataLen = 0; + processData->nFlags = 0; + processData->timeStamp = 0; + + return ret; +} + +OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_U32 checkedSize = 0; + OMX_BOOL flagEOF = OMX_FALSE; + OMX_BOOL previousFrameEOF = OMX_FALSE; + + FunctionIn(); + + if (inputUseBuffer->dataValid == OMX_TRUE) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + if (inputData->dataLen == 0) { + previousFrameEOF = OMX_TRUE; + } else { + previousFrameEOF = OMX_FALSE; + } + if ((pSECComponent->bUseFlagEOF == OMX_TRUE) && + !(inputUseBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { + flagEOF = OMX_TRUE; + checkedSize = checkInputStreamLen; + } else { + pSECComponent->bUseFlagEOF = OMX_FALSE; + checkedSize = pSECComponent->sec_checkInputFrame(checkInputStream, checkInputStreamLen, inputUseBuffer->nFlags, previousFrameEOF, &flagEOF); + } + + if (flagEOF == OMX_TRUE) { + copySize = checkedSize; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); + } else { + copySize = checkInputStreamLen; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); + } + + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) + pSECComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + if (copySize > 0) + SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); + + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + inputData->dataLen += copySize; + inputData->remainDataLen += copySize; + + if (previousFrameEOF == OMX_TRUE) { + inputData->timeStamp = inputUseBuffer->timeStamp; + inputData->nFlags = inputUseBuffer->nFlags; + } + + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } else { + if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || + (inputData->dataLen == 0))) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) && + (inputData->dataLen != 0)) { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_TRUE; + } + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + + if(((inputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (inputData->dataLen <= 0) && (flagEOF == OMX_TRUE)) { + inputData->dataLen = inputData->previousDataLen; + inputData->remainDataLen = inputData->previousDataLen; + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); + flagEOF = OMX_FALSE; + } + + if (inputUseBuffer->remainDataLen == 0) + SEC_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; + } + + if (flagEOF == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + SEC_OSAL_Log(SEC_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", + inputData->timeStamp, inputData->timeStamp / 1E6); + } + + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + + FunctionOut(); + + return ret; +} + +OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + FunctionIn(); + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if ((pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) && + (pSECComponent->checkTimeStamp.nStartFlags == outputData->nFlags)){ + pSECComponent->checkTimeStamp.startTimeStamp = -19761123; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + ret = OMX_TRUE; + goto EXIT; + } + } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + ret = OMX_TRUE; + goto EXIT; + } + + if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = outputData->remainDataLen; + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = outputData->nFlags; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_TRUE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + SEC_OutputBufferReturn(pOMXComponent); + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); + + ret = OMX_FALSE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + if (((pSECComponent->currentState == OMX_StatePause) || + (pSECComponent->currentState == OMX_StateIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + while ((SEC_Check_BufferProcess_State(pSECComponent)) && (!pSECComponent->bExitBufferProcessThread)) { + SEC_OSAL_SleepMillisec(0); + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = SEC_OutputBufferGetQueue(pSECComponent); + if ((ret == OMX_ErrorUndefined) || + (secInputPort->portState != OMX_StateIdle) || + (secOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pSECComponent->remainOutputData == OMX_FALSE) { + if (pSECComponent->reInputData == OMX_FALSE) { + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = SEC_InputBufferGetQueue(pSECComponent); + break; + } + + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataDecodeYet) + pSECComponent->reInputData = OMX_TRUE; + else + pSECComponent->reInputData = OMX_FALSE; + } + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + + if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) + pSECComponent->remainOutputData = OMX_TRUE; + else + pSECComponent->remainOutputData = OMX_FALSE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pSECComponent->portParam.nPorts; + portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + + if (portIndex == INPUT_PORT_INDEX) { + supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; + portFormat->eColorFormat = portDefinition->format.video.eColorFormat; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + } else if (portIndex == OUTPUT_PORT_INDEX) { + supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + switch (index) { + case supportFormat_0: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_1: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_2: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + } + } + ret = OMX_ErrorNone; + } + break; +#ifdef USE_ANB + case OMX_IndexParamGetAndroidNativeBuffer: + { + ret = SEC_OSAL_GetANBParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; +#endif + default: + { + ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + portDefinition->format.video.eColorFormat = portFormat->eColorFormat; + portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; + portDefinition->format.video.xFramerate = portFormat->xFramerate; + } + } + break; +#ifdef USE_ANB + case OMX_IndexParamEnableAndroidBuffers: + case OMX_IndexParamUseAndroidNativeBuffer: + { + ret = SEC_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; +#endif + default: + { + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexVendorThumbnailMode: + { + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoDec->bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure); + + ret = OMX_ErrorNone; + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + +#ifdef USE_ANB + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableAndroidBuffers; + else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_GET_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer; + else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_USE_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer; + else + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); +#else + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoDec = SEC_OSAL_Malloc(sizeof(SEC_OMX_VIDEODEC_COMPONENT)); + if (pVideoDec == NULL) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OSAL_Memset(pVideoDec, 0, sizeof(SEC_OMX_VIDEODEC_COMPONENT)); + pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec; + + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = 0; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; + + pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; + pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; + pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; + pSECComponent->sec_BufferReset = &SEC_BufferReset; + pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; + pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OSAL_Free(pVideoDec); + pSECComponent->hComponentHandle = pVideoDec = NULL; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); + pSECPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = SEC_OMX_Port_Destructor(pOMXComponent); + + ret = SEC_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.h b/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.h new file mode 100644 index 0000000..806ad44 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/SEC_OMX_Vdec.h @@ -0,0 +1,153 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vdec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_VIDEO_DECODE +#define SEC_OMX_VIDEO_DECODE + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" + +#define MAX_VIDEO_INPUTBUFFER_NUM 5 +#define MAX_VIDEO_OUTPUTBUFFER_NUM 2 + +#define DEFAULT_FRAME_WIDTH 176 +#define DEFAULT_FRAME_HEIGHT 144 + +#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2 +#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 + +#define MFC_INPUT_BUFFER_NUM_MAX 2 +#define DEFAULT_MFC_INPUT_BUFFER_SIZE 1024 * 1024 * MFC_INPUT_BUFFER_NUM_MAX /*DEFAULT_VIDEO_INPUT_BUFFER_SIZE*/ + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 4 + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} MFC_DEC_ADDR_INFO; + +typedef struct _SEC_MFC_NBDEC_THREAD +{ + OMX_HANDLETYPE hNBDecodeThread; + OMX_HANDLETYPE hDecFrameStart; + OMX_HANDLETYPE hDecFrameEnd; + OMX_BOOL bExitDecodeThread; + OMX_BOOL bDecoderRun; + + OMX_U32 oneFrameSize; +} SEC_MFC_NBDEC_THREAD; + +typedef struct _MFC_DEC_INPUT_BUFFER +{ + void *PhyAddr; // physical address + void *VirAddr; // virtual address + int bufferSize; // input buffer alloc size + int dataSize; // Data length +} MFC_DEC_INPUT_BUFFER; + +typedef struct _SEC_OMX_VIDEODEC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + SEC_MFC_NBDEC_THREAD NBDecThread; + + OMX_BOOL bThumbnailMode; + OMX_BOOL bFirstFrame; + MFC_DEC_INPUT_BUFFER MFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; +} SEC_OMX_VIDEODEC_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer); +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/h264/Android.mk b/exynos/multimedia/openmax/component/video/dec/h264/Android.mk new file mode 100644 index 0000000..5ac0170 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/h264/Android.mk @@ -0,0 +1,58 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_H264dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.AVC.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +ifeq ($(BOARD_USE_CSC_FIMC), true) +ifeq ($(BOARD_USE_V4L2_ION), false) +LOCAL_CFLAGS += -DUSE_CSC_FIMC +endif +endif +endif + +ifeq ($(BOARD_USE_V4L2), false) +ifeq ($(BOARD_USE_S3D_SUPPORT), true) +LOCAL_CFLAGS += -DS3D_SUPPORT +endif +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +LOCAL_SHARED_LIBRARIES += libhwconverter +endif + +#ifeq ($(BOARD_USE_V4L2_ION),true) +#LOCAL_SHARED_LIBRARIES += libion +#endif + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.c b/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.c new file mode 100644 index 0000000..5efa041 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.c @@ -0,0 +1,2067 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264dec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "library_register.h" +#include "SEC_OMX_H264dec.h" +#include "SsbSipMfcApi.h" +#include "color_space_convertor.h" + +#ifdef USE_ANB +#include "SEC_OSAL_Android.h" +#endif + +/* To use CSC FIMC in SEC OMX, gralloc should allocate physical memory using FIMC */ +/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ +#ifdef USE_CSC_FIMC +#include "csc_fimc.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_H264_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define H264_DEC_NUM_OF_EXTRA_BUFFERS 7 + +#ifdef S3D_SUPPORT +#define ADD_SPS_PPS_I_FRAME +#else +//#define ADD_SPS_PPS_I_FRAME +#endif +//#define FULL_FRAME_SEARCH + +/* H.264 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; + + +static int Check_H264_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + OMX_U32 preFourByte = (OMX_U32)-1; + int accessUnitSize = 0; + int frameTypeBoundary = 0; + int nextNaluSize = 0; + int naluStart = 0; + + if (bPreviousFrameEOF == OMX_TRUE) + naluStart = 0; + else + naluStart = 1; + + while (1) { + int inputOneByte = 0; + + if (accessUnitSize == (int)buffSize) + goto EXIT; + + inputOneByte = *(pInputStream++); + accessUnitSize += 1; + + if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) { + int naluType = inputOneByte & 0x1F; + + SEC_OSAL_Log(SEC_LOG_TRACE, "NaluType : %d", naluType); + if (naluStart == 0) { +#ifdef ADD_SPS_PPS_I_FRAME + if (naluType == 1 || naluType == 5) +#else + if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8) +#endif + naluStart = 1; + } else { +#ifdef OLD_DETECT + frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9) +#else + if (naluType == 9) + frameTypeBoundary = -2; +#endif + if (naluType == 1 || naluType == 5) { + if (accessUnitSize == (int)buffSize) { + accessUnitSize--; + goto EXIT; + } + inputOneByte = *pInputStream++; + accessUnitSize += 1; + + if (inputOneByte >= 0x80) + frameTypeBoundary = -1; + } + if (frameTypeBoundary < 0) { + break; + } + } + + } + preFourByte = (preFourByte << 8) + inputOneByte; + } + + *pbEndOfFrame = OMX_TRUE; + nextNaluSize = -5; + if (frameTypeBoundary == -1) + nextNaluSize = -6; + if (preFourByte != 0x00000001) + nextNaluSize++; + return (accessUnitSize + nextNaluSize); + +EXIT: + *pbEndOfFrame = OMX_FALSE; + + return accessUnitSize; +} + +OMX_BOOL Check_H264_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize) +{ + if (streamSize < 4) { + return OMX_FALSE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x00) && + (pInputStream[3] != 0x00) && + ((pInputStream[3] >> 3) == 0x00)) { + return OMX_TRUE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] != 0x00) && + ((pInputStream[2] >> 3) == 0x00)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pProfileLevel = supportedAVCProfileLevels; + maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; + pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + realWidth = pSECPort->portDefinition.format.video.nFrameWidth; + realHeight = pSECPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.nBufferSize = + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex]; + pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; + pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigCommonOutputCrop: + { + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_CONFIG_RECTTYPE *pSrcRectType = NULL; + OMX_CONFIG_RECTTYPE *pDstRectType = NULL; + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + ret = OMX_ErrorNotReady; + break; + } + + pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure; + + if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) && + (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[pDstRectType->nPortIndex]; + + pSrcRectType = &(pSECPort->cropRectangle); + + pDstRectType->nTop = pSrcRectType->nTop; + pDstRectType->nLeft = pSrcRectType->nLeft; + pDstRectType->nHeight = pSrcRectType->nHeight; + pDstRectType->nWidth = pSrcRectType->nWidth; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); + + if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_PTR hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; +#ifdef S3D_SUPPORT + OMX_S32 setConfVal = 0; +#endif + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + } else { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Dec->hMFCH264Handle.hMFCHandle = hMFCHandle; + +#ifdef S3D_SUPPORT + /*Enable SEI parsing for checking frame_packing S3D*/ + setConfVal = 1; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_SEI_PARSE, &setConfVal); +#endif + + /* Allocate decoder's input buffer */ + /* Get first input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[0].dataSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + /* Get second input buffer */ + pStreamBuffer = NULL; + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[1].dataSize = 0; + pVideoDec->indexInputBuffer = 0; + + pVideoDec->bFirstFrame = OMX_TRUE; + + pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + pVideoDec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; + } +#endif + + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Dec->hMFCH264Handle.indexTimestamp = 0; + pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0; + + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +#ifdef USE_CSC_FIMC + pH264Dec->hFIMCHandle = csc_fimc_open(); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_PTR hMFCHandle = NULL; + + FunctionIn(); + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = NULL; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { + pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); + pVideoDec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.hDecFrameStart = NULL; + } +#endif + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle = NULL; + } + +#ifdef USE_CSC_FIMC + if (pH264Dec->hFIMCHandle != NULL) { + csc_fimc_close(pH264Dec->hFIMCHandle); + pH264Dec->hFIMCHandle = NULL; + } +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 setConfVal = 0; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize = 0; + OMX_U32 FrameBufferUVSize = 0; + OMX_BOOL outputDataValid = OMX_FALSE; +#ifdef S3D_SUPPORT + SSBSIP_MFC_FRAME_PACKING frame_packing; +#endif + + FunctionIn(); + + if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Default number in the driver is optimized */ + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + setConfVal = 0; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } else { + setConfVal = H264_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); + + setConfVal = 8; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } + + SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer, + pH264Dec->hMFCH264Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); + if (pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + SSBSIP_MFC_CROP_INFORMATION cropInfo; + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); + SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", + pSECInputPort->portDefinition.format.video.nFrameWidth, + pSECInputPort->portDefinition.format.video.nFrameHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", + imgResol.width, imgResol.height); + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", + cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , + cropInfo.crop_left_offset , cropInfo.crop_right_offset); + + pSECOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; + pSECOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; + pSECOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; + pSECOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; + + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; + + /** Update Frame Size **/ + if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || + (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send crop info call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + OMX_IndexConfigCommonOutputCrop, + NULL); + } + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); + + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send Port Settings changed call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + +#ifdef ADD_SPS_PPS_I_FRAME + ret = OMX_ErrorInputDataDecodeYet; +#else + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; +#endif + goto EXIT; + } else { + ret = OMX_ErrorMFCInit; + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + + if ((pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) && + (pVideoDec->bFirstFrame == OMX_FALSE)) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + /* wait for mfc decode done */ + if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + +#ifdef S3D_SUPPORT + /* Check Whether frame packing information is available */ + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_PACKING, &frame_packing); + + if (pVideoDec->bThumbnailMode == OMX_FALSE && + frame_packing.available && + pH264Dec->hMFCH264Handle.bS3DMode == OMX_FALSE) { + + SEC_OSAL_Log(SEC_LOG_TRACE, "arrangement ID: 0x%08x", frame_packing.arrangement_id); + SEC_OSAL_Log(SEC_LOG_TRACE, "arrangement_type: %d", frame_packing.arrangement_type); + SEC_OSAL_Log(SEC_LOG_TRACE, "content_interpretation_type: %d", frame_packing.content_interpretation_type); + SEC_OSAL_Log(SEC_LOG_TRACE, "current_frame_is_frame0_flag: %d", frame_packing.current_frame_is_frame0_flag); + SEC_OSAL_Log(SEC_LOG_TRACE, "spatial_flipping_flag: %d", frame_packing.spatial_flipping_flag); + SEC_OSAL_Log(SEC_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", frame_packing.frame0_grid_pos_x, + frame_packing.frame0_grid_pos_y, frame_packing.frame1_grid_pos_x, frame_packing.frame1_grid_pos_y); + + /* Change Outport eColorFormat based on Framepacking information*/ + if (frame_packing.arrangement_type == 3) { + if (frame_packing.content_interpretation_type == 1) { + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR; + break; + } + } else if (frame_packing.content_interpretation_type == 2) { + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL; + break; + } + } + } else if (frame_packing.arrangement_type == 4) { + if (frame_packing.content_interpretation_type == 1) { + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_TB_LR; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_TB_LR; + break; + } + } else if (frame_packing.content_interpretation_type == 2) { + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_TB_RL; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_TB_RL; + break; + } + } + } + + /** Send Port Settings changed call back - output color format change */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + + if ((pSECOutputPort->cropRectangle.nTop != 0) || (pSECOutputPort->cropRectangle.nLeft != 0)) { + /** Send crop info call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + OMX_IndexConfigCommonOutputCrop, + NULL); + } + pH264Dec->hMFCH264Handle.bS3DMode = OMX_TRUE; + SEC_OSAL_SleepMillisec(0); + ret = OMX_ErrorInputDataDecodeYet; + goto EXIT; + } +#endif + + if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if ((outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) || + (pH264Dec->hMFCH264Handle.bFlashPlayerMode == OMX_TRUE)) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + outputDataValid = OMX_TRUE; + pH264Dec->hMFCH264Handle.outputIndexTimestamp++; + pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + outputDataValid = OMX_FALSE; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + outputDataValid = OMX_FALSE; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { + pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + + outputDataValid = OMX_FALSE; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + } + + if (ret == OMX_ErrorInputDataDecodeYet) { + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } + + if ((Check_H264_StartCode(pInputData->dataBuffer, oneFrameSize) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); + pH264Dec->hMFCH264Handle.indexTimestamp++; + pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer, + pH264Dec->hMFCH264Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; + + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; + pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; + + SEC_OSAL_SleepMillisec(0); + + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE) && + (outputDataValid == OMX_FALSE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + pVideoDec->bFirstFrame = OMX_FALSE; + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + } + + /** Fill Output Buffer **/ + if (outputDataValid == OMX_TRUE) { + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int actualWidth = outputInfo.img_width; + int actualHeight = outputInfo.img_height; + int actualImageSize = actualWidth * actualHeight; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + actualImageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + actualImageSize + actualImageSize / 4; + pOutputData->dataLen = (actualImageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, actualWidth, actualHeight, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + actualWidth = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (actualWidth * actualHeight * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420p out for ThumbnailMode/Flash player mode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: +#ifdef S3D_SUPPORT + case OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR: + case OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL: + case OMX_SEC_COLOR_FormatNV12Tiled_TB_LR: + case OMX_SEC_COLOR_FormatNV12Tiled_TB_RL: +#endif + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: +#ifdef S3D_SUPPORT + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL: +#endif + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pH264Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pH264Dec->hFIMCHandle, pPhys, + pYUVBuf, actualWidth, actualHeight, + OMX_COLOR_FormatYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + actualWidth, + actualHeight); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + actualWidth, + actualHeight / 2); + break; + case OMX_COLOR_FormatYUV420Planar: +#ifdef S3D_SUPPORT + case OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR: + case OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL: + case OMX_SEC_COLOR_FormatYUV420Planar_TB_LR: + case OMX_SEC_COLOR_FormatYUV420Planar_TB_RL: +#endif + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pH264Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pH264Dec->hFIMCHandle, pPhys, + pYUVBuf, actualWidth, actualHeight, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + actualWidth, + actualHeight); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + actualWidth, + actualHeight / 2); + break; + } + } +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + } else { + pOutputData->dataLen = 0; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 setConfVal = 0; + OMX_S32 returnCodec = 0; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize; + OMX_U32 FrameBufferUVSize; + + FunctionIn(); + + if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Default number in the driver is optimized */ + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + setConfVal = 0; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } else { + setConfVal = H264_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); + + setConfVal = 8; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } + + returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + SSBSIP_MFC_CROP_INFORMATION cropInfo; + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); + SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", + pSECInputPort->portDefinition.format.video.nFrameWidth, + pSECInputPort->portDefinition.format.video.nFrameHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", + imgResol.width, imgResol.height); + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", + cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , + cropInfo.crop_left_offset , cropInfo.crop_right_offset); + + pSECOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; + pSECOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; + pSECOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; + pSECOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; + + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; + + /** Update Frame Size **/ + if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || + (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send crop info call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + OMX_IndexConfigCommonOutputCrop, + NULL); + } + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send Port Settings changed call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + +#ifdef ADD_SPS_PPS_I_FRAME + ret = OMX_ErrorInputDataDecodeYet; +#else + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; +#endif + goto EXIT; + } else { + ret = OMX_ErrorMFCInit; + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + if (Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { + pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); + + returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, oneFrameSize); + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { + pH264Dec->hMFCH264Handle.indexTimestamp++; + pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if ((outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) || + (pH264Dec->hMFCH264Handle.bFlashPlayerMode != OMX_FALSE)) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + /** Fill Output Buffer **/ + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int actualWidth = outputInfo.img_width; + int actualHeight = outputInfo.img_height; + int actualImageSize = actualWidth * actualHeight; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + actualImageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + actualImageSize + actualImageSize / 4; + pOutputData->dataLen = (actualImageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, actualWidth, actualHeight, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + actualWidth = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (actualWidth * actualHeight * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420p out for ThumbnailMode/Flash player mode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pH264Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pH264Dec->hFIMCHandle, pPhys, + pYUVBuf, actualWidth, actualHeight, + OMX_SEC_COLOR_FormatANBYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + actualWidth, + actualHeight); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + actualWidth, + actualHeight / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pH264Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pH264Dec->hFIMCHandle, pPhys, + pYUVBuf, actualWidth, actualHeight, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + actualWidth, + actualHeight); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + actualWidth, + actualHeight / 2); + break; + } + } + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + pH264Dec->hMFCH264Handle.outputIndexTimestamp++; + pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + pOutputData->dataLen = 0; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_H264Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL endOfFrame = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_H264_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_H264_Decode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_BOOL bFlashPlayerMode = OMX_FALSE; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_DEC, componentName) == 0) { + bFlashPlayerMode = OMX_FALSE; + } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_FP_DEC, componentName) == 0) { + bFlashPlayerMode = OMX_TRUE; + } else { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_DEC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Dec = SEC_OSAL_Malloc(sizeof(SEC_H264DEC_HANDLE)); + if (pH264Dec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pH264Dec, 0, sizeof(SEC_H264DEC_HANDLE)); + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec; + + if (bFlashPlayerMode == OMX_FALSE) + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_DEC); + else + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_FP_DEC); + + pH264Dec->hMFCH264Handle.bFlashPlayerMode = bFlashPlayerMode; +#ifdef S3D_SUPPORT + pH264Dec->hMFCH264Handle.bS3DMode = OMX_FALSE; +#endif + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + if (bFlashPlayerMode != OMX_FALSE) { + pSECPort->portDefinition.nBufferCountActual = MAX_H264_FP_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_H264_FP_VIDEO_INPUTBUFFER_NUM; + } + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + if (bFlashPlayerMode != OMX_FALSE) { + pSECPort->portDefinition.nBufferCountActual = MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM; + } + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); + pH264Dec->AVCComponent[i].nPortIndex = i; + pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; + pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; + } + + pOMXComponent->GetParameter = &SEC_MFC_H264Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_H264Dec_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_H264Dec_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_H264Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Dec_bufferProcess; + pSECComponent->sec_checkInputFrame = &Check_H264_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pH264Dec != NULL) { + SEC_OSAL_Free(pH264Dec); + pH264Dec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.h b/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.h new file mode 100644 index 0000000..06e3116 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/h264/SEC_OMX_H264dec.h @@ -0,0 +1,79 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264dec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_DEC_COMPONENT +#define SEC_OMX_H264_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + + +#define MAX_H264_FP_VIDEO_INPUTBUFFER_NUM 4 +#define MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM 4 + +typedef struct _SEC_MFC_H264DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFC; + OMX_BOOL bFlashPlayerMode; +#ifdef S3D_SUPPORT + OMX_BOOL bS3DMode; +#endif + OMX_S32 returnCodec; +} SEC_MFC_H264DEC_HANDLE; + +typedef struct _SEC_H264DEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_H264DEC_HANDLE hMFCH264Handle; + + /* CSC FIMC handle */ +#ifdef USE_CSC_FIMC + OMX_PTR hFIMCHandle; +#endif +} SEC_H264DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/h264/library_register.c b/exynos/multimedia/openmax/component/video/dec/h264/library_register.c new file mode 100644 index 0000000..579a071 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/h264/library_register.c @@ -0,0 +1,60 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) +{ + FunctionIn(); + + if (secComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPONENT_H264_DEC); + SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPONENT_H264_DEC_ROLE); + secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video decoder H.264 for flash player */ + SEC_OSAL_Strcpy(secComponents[1]->componentName, SEC_OMX_COMPONENT_H264_FP_DEC); + SEC_OSAL_Strcpy(secComponents[1]->roles[0], SEC_OMX_COMPONENT_H264_DEC_ROLE); + secComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/video/dec/h264/library_register.h b/exynos/multimedia/openmax/component/video/dec/h264/library_register.h new file mode 100644 index 0000000..be7384b --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/h264/library_register.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_REG +#define SEC_OMX_H264_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* H.264 */ +#define SEC_OMX_COMPONENT_H264_DEC "OMX.SEC.AVC.Decoder" +#define SEC_OMX_COMPONENT_H264_FP_DEC "OMX.SEC.FP.AVC.Decoder" +#define SEC_OMX_COMPONENT_H264_DEC_ROLE "video_decoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/exynos/multimedia/openmax/component/video/dec/mpeg4/Android.mk b/exynos/multimedia/openmax/component/video/dec/mpeg4/Android.mk new file mode 100644 index 0000000..d45c727 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/mpeg4/Android.mk @@ -0,0 +1,52 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Mpeg4dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.M4V.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +ifeq ($(BOARD_USE_CSC_FIMC), true) +ifeq ($(BOARD_USE_V4L2_ION), false) +LOCAL_CFLAGS += -DUSE_CSC_FIMC +endif +endif +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +LOCAL_SHARED_LIBRARIES += libhwconverter +endif + +#ifeq ($(BOARD_USE_V4L2_ION),true) +#LOCAL_SHARED_LIBRARIES += libion +#endif + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c b/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c new file mode 100644 index 0000000..5969c71 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c @@ -0,0 +1,2048 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4dec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "library_register.h" +#include "SEC_OMX_Mpeg4dec.h" +#include "SsbSipMfcApi.h" +#include "color_space_convertor.h" + +#ifdef USE_ANB +#include "SEC_OSAL_Android.h" +#endif + +/* To use CSC FIMC in SEC OMX, gralloc should allocate physical memory using FIMC */ +/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ +#ifdef USE_CSC_FIMC +#include "csc_fimc.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define MPEG4_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH + +/* MPEG4 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; + +/* H.263 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { + /* Baseline (Profile 0) */ + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}, + /* Profile 1 */ + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level70}, + /* Profile 2 */ + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level70}, + /* Profile 3, restricted up to SD resolution */ + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level70}}; + +static OMX_HANDLETYPE ghMFCHandle = NULL; +static OMX_BOOL gbFIMV1 = OMX_FALSE; + +static int Check_Mpeg4_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + OMX_U32 len; + int readStream; + unsigned startCode; + OMX_BOOL bFrameStart; + + len = 0; + bFrameStart = OMX_FALSE; + + if (flag & OMX_BUFFERFLAG_CODECCONFIG) { + if (*pInputStream == 0x03) { /* FIMV1 */ + if (ghMFCHandle != NULL) { + BitmapInfoHhr *pInfoHeader; + SSBSIP_MFC_IMG_RESOLUTION imgResolution; + + pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1); + imgResolution.width = pInfoHeader->BiWidth; + imgResolution.height = pInfoHeader->BiHeight; + SsbSipMfcDecSetConfig(ghMFCHandle, MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, &imgResolution); + + SEC_OSAL_Log(SEC_LOG_TRACE, "width(%d), height(%d)", imgResolution.width, imgResolution.height); + gbFIMV1 = OMX_TRUE; + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + } + } + + if (gbFIMV1) { + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + + if (bPreviousFrameEOF == OMX_FALSE) + bFrameStart = OMX_TRUE; + + startCode = 0xFFFFFFFF; + if (bFrameStart == OMX_FALSE) { + /* find VOP start code */ + while(startCode != 0x1B6) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + } + + /* find next VOP start code */ + startCode = 0xFFFFFFFF; + while ((startCode != 0x1B6)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + + *pbEndOfFrame = OMX_TRUE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); + + return len - 4; + +EXIT : + *pbEndOfFrame = OMX_FALSE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +static int Check_H263_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + OMX_U32 len; + int readStream; + unsigned startCode; + OMX_BOOL bFrameStart = 0; + unsigned pTypeMask = 0x03; + unsigned pType = 0; + + len = 0; + bFrameStart = OMX_FALSE; + + if (bPreviousFrameEOF == OMX_FALSE) + bFrameStart = OMX_TRUE; + + startCode = 0xFFFFFFFF; + if (bFrameStart == OMX_FALSE) { + /* find PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */ + while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + + readStream = *(pInputStream + len + 1); + pType = readStream & pTypeMask; + + len++; + if (len > buffSize) + goto EXIT; + } + } + + /* find next PSC */ + startCode = 0xFFFFFFFF; + pType = 0; + while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + + readStream = *(pInputStream + len + 1); + pType = readStream & pTypeMask; + + len++; + if (len > buffSize) + goto EXIT; + } + + *pbEndOfFrame = OMX_TRUE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize); + + return len - 3; + +EXIT : + + *pbEndOfFrame = OMX_FALSE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +OMX_BOOL Check_Stream_PrefixCode(OMX_U8 *pInputStream, OMX_U32 streamSize, CODEC_TYPE codecType) +{ + switch (codecType) { + case CODEC_TYPE_MPEG4: + if (gbFIMV1) { + return OMX_TRUE; + } else { + if (streamSize < 3) { + return OMX_FALSE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x01)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } + } + break; + case CODEC_TYPE_H263: + if (streamSize > 0) + return OMX_TRUE; + else + return OMX_FALSE; + default: + SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType); + return OMX_FALSE; + } +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); + else + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; + } else { + pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcH263Param->eProfile; + pDstProfileLevel->eLevel = pSrcH263Param->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + //((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; + } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + //((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + realWidth = pSECPort->portDefinition.format.video.nFrameWidth; + realHeight = pSECPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.nBufferSize = + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + /* + * To do: Check validity of profile & level parameters + */ + + pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; + } else { + /* + * To do: Check validity of profile & level parameters + */ + + pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex]; + pDstH263Param->eProfile = pSrcProfileLevel->eProfile; + pDstH263Param->eLevel = pSrcProfileLevel->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); + else + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); + + if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecExe(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; + + FunctionIn(); + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + } else { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ghMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; + + /* Allocate decoder's input buffer */ + /* Get first input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[0].dataSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + /* Get second input buffer */ + pStreamBuffer = NULL; + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[1].dataSize = 0; + pVideoDec->indexInputBuffer = 0; + + pVideoDec->bFirstFrame = OMX_TRUE; + + pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + pVideoDec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + } +#endif + + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0; + + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +#ifdef USE_CSC_FIMC + pMpeg4Dec->hFIMCHandle = csc_fimc_open(); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + + FunctionIn(); + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = NULL; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { + pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); + pVideoDec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.hDecFrameStart = NULL; + } +#endif + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + ghMFCHandle = hMFCHandle = NULL; + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL; + } + +#ifdef USE_CSC_FIMC + if (pMpeg4Dec->hFIMCHandle != NULL) { + csc_fimc_close(pMpeg4Dec->hFIMCHandle); + pMpeg4Dec->hFIMCHandle = NULL; + } +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 configValue; + int bufWidth; + int bufHeight; + OMX_U32 FrameBufferYSize = 0; + OMX_U32 FrameBufferUVSize = 0; + OMX_BOOL outputDataValid = OMX_FALSE; + + FunctionIn(); + + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE MFCCodecType; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + if (gbFIMV1) + MFCCodecType = FIMV1_DEC; + else + MFCCodecType = MPEG4_DEC; + } else { + MFCCodecType = H263_DEC; + } + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Set mpeg4 deblocking filter enable */ + configValue = 1; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_POST_ENABLE, &configValue); + + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + configValue = 0; // the number that you want to delay + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); + } else { + configValue = MPEG4_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); + } + + SsbSipMfcDecSetInBuf(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); + if (pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + if (SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { + ret = OMX_ErrorMFCInit; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecGetConfig failed", __FUNCTION__); + goto EXIT; + } + + /** Update Frame Size **/ + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, // The command was completed + OMX_DirOutput, // This is the port index + 0, + NULL); + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + } else { + pOutputData->dataLen = 0; + ret = OMX_ErrorInputDataDecodeYet; + } + goto EXIT; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecInit failed", __FUNCTION__); + ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + + if ((pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && + (pVideoDec->bFirstFrame == OMX_FALSE)) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + /* wait for mfc decode done */ + if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if ((SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + outputDataValid = OMX_TRUE; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + outputDataValid = OMX_FALSE; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + outputDataValid = OMX_FALSE; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { + pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + + outputDataValid = OMX_FALSE; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + } + + if (ret == OMX_ErrorInputDataDecodeYet) { + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } + + if ((Check_Stream_PrefixCode(pInputData->dataBuffer, oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + SsbSipMfcDecSetConfig(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + SsbSipMfcDecSetInBuf(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; + + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + + SEC_OSAL_SleepMillisec(0); + + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE) && + (outputDataValid == OMX_FALSE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + pVideoDec->bFirstFrame = OMX_FALSE; + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + } + + /** Fill Output Buffer **/ + if (outputDataValid == OMX_TRUE) { + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pMpeg4Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pMpeg4Dec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_COLOR_FormatYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pMpeg4Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pMpeg4Dec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + } else { + pOutputData->dataLen = 0; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 configValue; + OMX_S32 returnCodec; + int bufWidth; + int bufHeight; + OMX_U32 FrameBufferYSize; + OMX_U32 FrameBufferUVSize; + + FunctionIn(); + + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE MFCCodecType; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + if (gbFIMV1) + MFCCodecType = FIMV1_DEC; + else + MFCCodecType = MPEG4_DEC; + } else { + MFCCodecType = H263_DEC; + } + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Set mpeg4 deblocking filter enable */ + configValue = 1; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_POST_ENABLE, &configValue); + + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + configValue = 0; // the number that you want to delay + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); + } else { + configValue = MPEG4_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); + } + + returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + if (SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { + ret = OMX_ErrorMFCInit; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecGetConfig failed", __FUNCTION__); + goto EXIT; + } + + /** Update Frame Size **/ + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, // The command was completed + OMX_DirOutput, // This is the port index + 0, + NULL); + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + } else { + pOutputData->dataLen = 0; + ret = OMX_ErrorInputDataDecodeYet; + } + goto EXIT; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecInit failed", __FUNCTION__); + ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) { + pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); + + returnCodec = SsbSipMfcDecExe(hMFCHandle, oneFrameSize); + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + if ((SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + /** Fill Output Buffer **/ + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pMpeg4Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pMpeg4Dec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_SEC_COLOR_FormatANBYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pMpeg4Dec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pMpeg4Dec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + pOutputData->dataLen = 0; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL bCheckPrefix = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_Mpeg4_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_Mpeg4_Decode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType = -1; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H263_DEC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_DEC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Dec = SEC_OSAL_Malloc(sizeof(SEC_MPEG4_HANDLE)); + if (pMpeg4Dec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pMpeg4Dec, 0, sizeof(SEC_MPEG4_HANDLE)); + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec; + pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MPEG4_DEC); + else + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H263_DEC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + if (codecType == CODEC_TYPE_MPEG4) { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (codecType == CODEC_TYPE_MPEG4) { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); + pMpeg4Dec->mpeg4Component[i].nPortIndex = i; + pMpeg4Dec->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; + pMpeg4Dec->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level3; + } + } else { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); + pMpeg4Dec->h263Component[i].nPortIndex = i; + pMpeg4Dec->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2; + pMpeg4Dec->h263Component[i].eLevel = OMX_VIDEO_H263Level45; + } + } + + pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Dec_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_Mpeg4Dec_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_Mpeg4Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Dec_bufferProcess; + if (codecType == CODEC_TYPE_MPEG4) + pSECComponent->sec_checkInputFrame = &Check_Mpeg4_Frame; + else + pSECComponent->sec_checkInputFrame = &Check_H263_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pMpeg4Dec != NULL) { + SEC_OSAL_Free(pMpeg4Dec); + ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h b/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h new file mode 100644 index 0000000..c844ff9 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h @@ -0,0 +1,97 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4dec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_DEC_COMPONENT +#define SEC_OMX_MPEG4_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + + +typedef enum _CODEC_TYPE +{ + CODEC_TYPE_H263, + CODEC_TYPE_MPEG4 +} CODEC_TYPE; + +/* + * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file + */ +typedef struct _BitmapInfoHhr +{ + OMX_U32 BiSize; + OMX_U32 BiWidth; + OMX_U32 BiHeight; + OMX_U16 BiPlanes; + OMX_U16 BiBitCount; + OMX_U32 BiCompression; + OMX_U32 BiSizeImage; + OMX_U32 BiXPelsPerMeter; + OMX_U32 BiYPelsPerMeter; + OMX_U32 BiClrUsed; + OMX_U32 BiClrImportant; +} BitmapInfoHhr; + +typedef struct _SEC_MFC_MPEG4_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFC; + CODEC_TYPE codecType; + OMX_S32 returnCodec; +} SEC_MFC_MPEG4_HANDLE; + +typedef struct _SEC_MPEG4_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_MPEG4_HANDLE hMFCMpeg4Handle; + + /* CSC FIMC handle */ +#ifdef USE_CSC_FIMC + OMX_PTR hFIMCHandle; +#endif +} SEC_MPEG4_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.c b/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.c new file mode 100644 index 0000000..2ae1b0d --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.c @@ -0,0 +1,63 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - video decoder MPEG4 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MPEG4_DEC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video decoder H.263 */ + SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPONENT_H263_DEC); + SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPONENT_H263_DEC_ROLE); + ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.h b/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.h new file mode 100644 index 0000000..40aec73 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/mpeg4/library_register.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_DEC_REG +#define SEC_OMX_MPEG4_DEC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define SEC_OMX_COMPONENT_MPEG4_DEC "OMX.SEC.MPEG4.Decoder" +#define SEC_OMX_COMPONENT_MPEG4_DEC_ROLE "video_decoder.mpeg4" + +/* H.263 */ +#define SEC_OMX_COMPONENT_H263_DEC "OMX.SEC.H263.Decoder" +#define SEC_OMX_COMPONENT_H263_DEC_ROLE "video_decoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/exynos/multimedia/openmax/component/video/dec/vc1/Android.mk b/exynos/multimedia/openmax/component/video/dec/vc1/Android.mk new file mode 100644 index 0000000..9412233 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vc1/Android.mk @@ -0,0 +1,52 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Wmvdec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.WMV.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +ifeq ($(BOARD_USE_CSC_FIMC), true) +ifeq ($(BOARD_USE_V4L2_ION), false) +LOCAL_CFLAGS += -DUSE_CSC_FIMC +endif +endif +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +LOCAL_SHARED_LIBRARIES += libhwconverter +endif + +#ifeq ($(BOARD_USE_V4L2_ION),true) +#LOCAL_SHARED_LIBRARIES += libion +#endif + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.c b/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.c new file mode 100644 index 0000000..ebc2a0f --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.c @@ -0,0 +1,1960 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Wmvdec.c + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.8.16 : Create + * 2010.8.20 : Support WMV3 (Vc-1 Simple/Main Profile) + * 2010.8.21 : Support WMvC1 (Vc-1 Advanced Profile) + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_Memory.h" +#include "library_register.h" +#include "SEC_OMX_Wmvdec.h" +#include "SsbSipMfcApi.h" +#include "SEC_OSAL_Event.h" +#include "color_space_convertor.h" + +#ifdef USE_ANB +#include "SEC_OSAL_Android.h" +#endif + +/* To use CSC FIMC in SEC OMX, gralloc should allocate physical memory using FIMC */ +/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ +#ifdef USE_CSC_FIMC +#include "csc_fimc.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_WMV_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define WMV_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH + +/* ASF parser does not send start code on OpenCORE */ +#define WO_START_CODE + +static OMX_HANDLETYPE ghMFCHandle = NULL; +static WMV_FORMAT gWvmFormat = WMV_FORMAT_UNKNOWN; + +const OMX_U32 wmv3 = 0x33564d57; +const OMX_U32 wvc1 = 0x31435657; +const OMX_U32 wmva = 0x41564d57; + +static int Check_Wmv_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + OMX_U32 compressionID; + OMX_BOOL bFrameStart; + OMX_U32 len, readStream; + OMX_U32 startCode; + + SEC_OSAL_Log(SEC_LOG_TRACE, "buffSize = %d", buffSize); + + len = 0; + bFrameStart = OMX_FALSE; + + if (flag & OMX_BUFFERFLAG_CODECCONFIG) { + BitmapInfoHhr *pBitmapInfoHeader; + pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream; + + compressionID = pBitmapInfoHeader->BiCompression; + if (compressionID == wmv3) { + SEC_OSAL_Log(SEC_LOG_TRACE, "WMV_FORMAT_WMV3"); + gWvmFormat = WMV_FORMAT_WMV3; + + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + else if ((compressionID == wvc1) || (compressionID == wmva)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "WMV_FORMAT_VC1"); + gWvmFormat = WMV_FORMAT_VC1; + +#ifdef WO_START_CODE +/* ASF parser does not send start code on OpenCORE */ + *pbEndOfFrame = OMX_TRUE; + return buffSize; +#endif + } + } + + if (gWvmFormat == WMV_FORMAT_WMV3) { + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + +#ifdef WO_START_CODE +/* ASF parser does not send start code on OpenCORE */ + if (gWvmFormat == WMV_FORMAT_VC1) { + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } +#else + /* TODO : for comformanc test based on common buffer scheme w/o parser */ + + if (bPreviousFrameEOF == OMX_FALSE) + bFrameStart = OMX_TRUE; + + startCode = 0xFFFFFFFF; + if (bFrameStart == OMX_FALSE) { + /* find Frame start code */ + while(startCode != 0x10D) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + } + + /* find next Frame start code */ + startCode = 0xFFFFFFFF; + while ((startCode != 0x10D)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + + *pbEndOfFrame = OMX_TRUE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); + + return len - 4; +#endif + +EXIT : + *pbEndOfFrame = OMX_FALSE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +OMX_BOOL Check_Stream_PrefixCode(OMX_U8 *pInputStream, OMX_U32 streamSize, WMV_FORMAT wmvFormat) +{ + switch (wmvFormat) { + case WMV_FORMAT_WMV3: + if (streamSize > 0) + return OMX_TRUE; + else + return OMX_FALSE; + break; + case WMV_FORMAT_VC1: + +#ifdef WO_START_CODE + /* ASF parser does not send start code on OpenCORE */ + if (streamSize > 3) + return OMX_TRUE; + else + return OMX_FALSE; + break; +#else + /* TODO : for comformanc test based on common buffer scheme w/o parser */ + if (streamSize < 3) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: streamSize is too small (%d)", __FUNCTION__, streamSize); + return OMX_FALSE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x01)) { + return OMX_TRUE; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Cannot find prefix", __FUNCTION__); + return OMX_FALSE; + } +#endif + break; + + default: + SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} + +OMX_BOOL Make_Stream_MetaData(OMX_U8 *pInputStream, OMX_U32 *pStreamSize, WMV_FORMAT wmvFormat) +{ + OMX_U32 width, height; + OMX_U8 *pCurrBuf = pInputStream; + OMX_U32 currPos = 0; + + FunctionIn(); + + /* Sequence Layer Data Structure */ + OMX_U8 const_C5[4] = {0x00, 0x00, 0x00, 0xc5}; + OMX_U8 const_04[4] = {0x04, 0x00, 0x00, 0x00}; + OMX_U8 const_0C[4] = {0x0C, 0x00, 0x00, 0x00}; + OMX_U8 struct_B_1[4] = {0xB3, 0x19, 0x00, 0x00}; + OMX_U8 struct_B_2[4] = {0x44, 0x62, 0x05, 0x00}; + OMX_U8 struct_B_3[4] = {0x0F, 0x00, 0x00, 0x00}; + OMX_U8 struct_C[4] = {0x30, 0x00, 0x00, 0x00}; + + switch (wmvFormat) { + case WMV_FORMAT_WMV3: + if (*pStreamSize >= BITMAPINFOHEADER_SIZE) { + BitmapInfoHhr *pBitmapInfoHeader; + pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream; + + width = pBitmapInfoHeader->BiWidth; + height = pBitmapInfoHeader->BiHeight; + if (*pStreamSize > BITMAPINFOHEADER_SIZE) + SEC_OSAL_Memcpy(struct_C, pInputStream+BITMAPINFOHEADER_SIZE, 4); + + SEC_OSAL_Memcpy(pCurrBuf + currPos, const_C5, 4); + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos, const_04, 4); + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_C, 4); + currPos +=4; + + /* struct_A : VERT_SIZE */ + pCurrBuf[currPos] = height & 0xFF; + pCurrBuf[currPos+1] = (height>>8) & 0xFF; + pCurrBuf[currPos+2] = (height>>16) & 0xFF; + pCurrBuf[currPos+3] = (height>>24) & 0xFF; + currPos +=4; + + /* struct_A : HORIZ_SIZE */ + pCurrBuf[currPos] = width & 0xFF; + pCurrBuf[currPos+1] = (width>>8) & 0xFF; + pCurrBuf[currPos+2] = (width>>16) & 0xFF; + pCurrBuf[currPos+3] = (width>>24) & 0xFF; + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos,const_0C, 4); + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_1, 4); + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_2, 4); + currPos +=4; + + SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_3, 4); + currPos +=4; + + *pStreamSize = currPos; + return OMX_TRUE; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize); + return OMX_FALSE; + } + break; + case WMV_FORMAT_VC1: + if (*pStreamSize >= BITMAPINFOHEADER_ASFBINDING_SIZE) { + SEC_OSAL_Memcpy(pCurrBuf, pInputStream + BITMAPINFOHEADER_ASFBINDING_SIZE, *pStreamSize - BITMAPINFOHEADER_ASFBINDING_SIZE); + *pStreamSize -= BITMAPINFOHEADER_ASFBINDING_SIZE; + return OMX_TRUE; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize); + return OMX_FALSE; + } + break; + default: + SEC_OSAL_Log(SEC_LOG_WARNING, "%s: It is not necessary to make bitstream metadata for wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} + +#ifdef WO_START_CODE +OMX_BOOL Make_Stream_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize, WMV_FORMAT wmvFormat) +{ + OMX_U8 frameStartCode[4] = {0x00, 0x00, 0x01, 0x0d}; + OMX_U32 i; + + switch (wmvFormat) { + case WMV_FORMAT_WMV3: + return OMX_TRUE; + break; + + case WMV_FORMAT_VC1: + /* Should find better way to shift data */ + SEC_OSAL_Memmove(pInputStream+4, pInputStream, streamSize); + SEC_OSAL_Memcpy(pInputStream, frameStartCode, 4); + + return OMX_TRUE; + break; + + default: + SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} +#endif + +OMX_ERRORTYPE SEC_MFC_WmvDec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoWmv: + { + OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = NULL; + SEC_WMV_HANDLE *pWmvDec = NULL; + ret = SEC_OMX_Check_SizeVersion(pDstWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstWmvParam->nPortIndex > OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + } + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcWmvParam = &pWmvDec->WmvComponent[pDstWmvParam->nPortIndex]; + + SEC_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE); + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_WMV_HANDLE *pWmvDec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_WmvDec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoWmv: + { + OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = NULL; + OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure; + SEC_WMV_HANDLE *pWmvDec = NULL; + ret = SEC_OMX_Check_SizeVersion(pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcWmvParam->nPortIndex > OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstWmvParam = &pWmvDec->WmvComponent[pSrcWmvParam->nPortIndex]; + + SEC_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + realWidth = pSECPort->portDefinition.format.video.nFrameWidth; + realHeight = pSECPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.nBufferSize = + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_WMV_HANDLE *pWmvDec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_WmvDec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_WmvDec_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_WmvDec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_WmvDec_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorUnsupportedIndex; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); + + if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pWmvDec->hMFCWmvHandle.returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_WMV_HANDLE *pWmvDec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; + + FunctionIn(); + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + } else { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ghMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle = hMFCHandle; + + /* Allocate decoder's input buffer */ + /* Get first input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[0].dataSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + /* Get second input buffer */ + pStreamBuffer = NULL; + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[1].dataSize = 0; + pVideoDec->indexInputBuffer = 0; + + pVideoDec->bFirstFrame = OMX_TRUE; + + pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + pVideoDec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pWmvDec->hMFCWmvHandle.returnCodec = MFC_RET_OK; + } +#endif + + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pWmvDec->hMFCWmvHandle.indexTimestamp = 0; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +#ifdef USE_CSC_FIMC + pWmvDec->hFIMCHandle = csc_fimc_open(); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_WMV_HANDLE *pWmvDec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + + FunctionIn(); + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = NULL; + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { + pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); + pVideoDec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.hDecFrameStart = NULL; + } +#endif + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + pWmvDec->hMFCWmvHandle.hMFCHandle = NULL; + } + +#ifdef USE_CSC_FIMC + if (pWmvDec->hFIMCHandle != NULL) { + csc_fimc_close(pWmvDec->hFIMCHandle); + pWmvDec->hFIMCHandle = NULL; + } +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Wmv_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 configValue = 0; + OMX_BOOL bMetaData = OMX_FALSE; + OMX_BOOL bStartCode = OMX_FALSE; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize = 0; + OMX_U32 FrameBufferUVSize = 0; + OMX_BOOL outputDataValid = OMX_FALSE; + + FunctionIn(); + + if (pWmvDec->hMFCWmvHandle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE MFCCodecType; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) + MFCCodecType = VC1RCV_DEC; + else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) + MFCCodecType = VC1_DEC; + else + MFCCodecType = UNKNOWN_TYPE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "codec type = %d", MFCCodecType); + + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + configValue = 0; // the number that you want to delay + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); + } else { + configValue = WMV_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); + } + + bMetaData = Make_Stream_MetaData(pInputData->dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bMetaData == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream MetaData"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } + + SsbSipMfcDecSetInBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer, + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pWmvDec->hMFCWmvHandle.returnCodec = SsbSipMfcDecInit(pWmvDec->hMFCWmvHandle.hMFCHandle, MFCCodecType, oneFrameSize); + if (pWmvDec->hMFCWmvHandle.returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { + ret = OMX_ErrorMFCInit; + SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecGetConfig failed"); + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "## nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + /** Update Frame Size **/ + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + SEC_UpdateFrameSize(pOMXComponent); + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, // The command was completed + OMX_DirOutput, // This is the port index + 0, + NULL); + } + + pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_TRUE; + + if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + } else { + +#ifdef WO_START_CODE +/* ASF parser does not send start code on OpenCORE */ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; +#else +/* TODO : for comformanc test based on common buffer scheme w/o parser */ + pOutputData->dataLen = 0; + ret = OMX_ErrorInputDataDecodeYet; +#endif + } + goto EXIT; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecInit failed"); + ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->nFlags; + + if ((pWmvDec->hMFCWmvHandle.returnCodec == MFC_RET_OK) && (pVideoDec->bFirstFrame == OMX_FALSE)) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + /* wait for mfc decode done */ + if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + status = SsbSipMfcDecGetOutBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if ((SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + outputDataValid = OMX_TRUE; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp++; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + outputDataValid = OMX_FALSE; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + outputDataValid = OMX_FALSE; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { + pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + + outputDataValid = OMX_FALSE; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + } + +#ifdef WO_START_CODE + if (pInputData->allocSize < oneFrameSize+4) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Can't attach startcode due to lack of buffer space"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } + + bStartCode = Make_Stream_StartCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bStartCode == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream Start Code"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } +#endif + + if (ret == OMX_ErrorInputDataDecodeYet) { + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "SsbSipMfcDecExe oneFrameSize = %d", oneFrameSize); + + if ((Check_Stream_PrefixCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pWmvDec->hMFCWmvHandle.indexTimestamp)); + pWmvDec->hMFCWmvHandle.indexTimestamp++; + pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; + } + + SsbSipMfcDecSetInBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer, + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; +#ifdef WO_START_CODE + pVideoDec->NBDecThread.oneFrameSize = oneFrameSize + 4; /* Frame Start Code */ +#else + pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; +#endif + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; + pWmvDec->hMFCWmvHandle.returnCodec = MFC_RET_OK; + + SEC_OSAL_SleepMillisec(0); + + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE) && + (outputDataValid == OMX_FALSE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + pVideoDec->bFirstFrame = OMX_FALSE; + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + } + + /** Fill Output Buffer **/ + if (outputDataValid == OMX_TRUE) { + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pWmvDec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pWmvDec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_SEC_COLOR_FormatANBYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pWmvDec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pWmvDec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + } else { + pOutputData->dataLen = 0; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Wmv_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 configValue = 0; + OMX_S32 returnCodec = 0; + OMX_BOOL bMetaData = OMX_FALSE; + OMX_BOOL bStartCode = OMX_FALSE; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize; + OMX_U32 FrameBufferUVSize; + + FunctionIn(); + + if (pWmvDec->hMFCWmvHandle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE MFCCodecType; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) + MFCCodecType = VC1RCV_DEC; + else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) + MFCCodecType = VC1_DEC; + else + MFCCodecType = UNKNOWN_TYPE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "codec type = %d", MFCCodecType); + + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + configValue = 0; // the number that you want to delay + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); + } else { + configValue = WMV_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); + } + + bMetaData = Make_Stream_MetaData(pInputData->dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bMetaData == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream MetaData"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } + + returnCodec = SsbSipMfcDecInit(pWmvDec->hMFCWmvHandle.hMFCHandle, MFCCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { + ret = OMX_ErrorMFCInit; + SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecGetConfig failed"); + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "## nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + /** Update Frame Size **/ + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, + pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); + + SEC_UpdateFrameSize(pOMXComponent); + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, // The command was completed + OMX_DirOutput, // This is the port index + 0, + NULL); + } + + pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_TRUE; + + if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + } else { + +#ifdef WO_START_CODE +/* ASF parser does not send start code on OpenCORE */ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; +#else +/* TODO : for comformanc test based on common buffer scheme w/o parser */ + pOutputData->dataLen = 0; + ret = OMX_ErrorInputDataDecodeYet; +#endif + } + goto EXIT; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecInit failed"); + ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + +#ifdef WO_START_CODE + if (pInputData->allocSize < oneFrameSize+4) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Can't attach startcode due to lack of buffer space"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } + + bStartCode = Make_Stream_StartCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bStartCode == OMX_FALSE) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream Start Code"); + ret = OMX_ErrorMFCInit; + goto EXIT; + } +#endif + + SEC_OSAL_Log(SEC_LOG_TRACE, "SsbSipMfcDecExe oneFrameSize = %d", oneFrameSize); + + if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pWmvDec->hMFCWmvHandle.wmvFormat) == OMX_TRUE) { + pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pWmvDec->hMFCWmvHandle.indexTimestamp)); + +#ifdef WO_START_CODE + returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, oneFrameSize+4); /* Frame Start Code */ +#else + returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, oneFrameSize); +#endif + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { + pWmvDec->hMFCWmvHandle.indexTimestamp++; + pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; + } + + if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + /** Fill Output Buffer **/ + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + OMX_U32 stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pWmvDec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pWmvDec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_SEC_COLOR_FormatANBYUV420SemiPlanar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: +#ifdef USE_CSC_FIMC + if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (pWmvDec->hFIMCHandle != NULL)) { + void *pPhys[3]; + SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pPhys); + pYUVBuf[0] = outputInfo.YPhyAddr; + pYUVBuf[1] = outputInfo.CPhyAddr; + csc_fimc_convert_nv12t(pWmvDec->hFIMCHandle, pPhys, + pYUVBuf, width, height, + OMX_COLOR_FormatYUV420Planar); + break; + } +#endif + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + pWmvDec->hMFCWmvHandle.outputIndexTimestamp++; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + pOutputData->dataLen = 0; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_WmvDec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL bCheckPrefix = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + goto EXIT; + } + + pWmvDec->hMFCWmvHandle.wmvFormat = gWvmFormat; + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_Wmv_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_Wmv_Decode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + SEC_WMV_HANDLE *pWmvDec = NULL; + OMX_S32 wmvFormat = WMV_FORMAT_UNKNOWN; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: parameters are null, ret:%X", ret); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_WMV_DEC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: SEC_OMX_VideoDecodeComponentInit error, ret: %X", ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_DEC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: componentName alloc error, ret: %X", ret); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pWmvDec = SEC_OSAL_Malloc(sizeof(SEC_WMV_HANDLE)); + if (pWmvDec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: SEC_WMV_HANDLE alloc error, ret: %X", ret); + goto EXIT; + } + SEC_OSAL_Memset(pWmvDec, 0, sizeof(SEC_WMV_HANDLE)); + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec; + pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat; + + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_WMV_DEC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/wmv"); + + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pWmvDec->WmvComponent[i], OMX_VIDEO_PARAM_WMVTYPE); + pWmvDec->WmvComponent[i].nPortIndex = i; + pWmvDec->WmvComponent[i].eFormat = OMX_VIDEO_WMVFormat9; + } + + pOMXComponent->GetParameter = &SEC_MFC_WmvDec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_WmvDec_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_WmvDec_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_WmvDec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_WmvDec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_WmvDec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_WmvDec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_WmvDec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_WmvDec_bufferProcess; + pSECComponent->sec_checkInputFrame = &Check_Wmv_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_WMV_HANDLE *pWmvDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pWmvDec != NULL) { + SEC_OSAL_Free(pWmvDec); + pWmvDec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.h b/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.h new file mode 100644 index 0000000..c68b644 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vc1/SEC_OMX_Wmvdec.h @@ -0,0 +1,99 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Wmvdec.h + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.8.20 : Create + */ + +#ifndef SEC_OMX_WMV_DEC_COMPONENT +#define SEC_OMX_WMV_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + +#define BITMAPINFOHEADER_SIZE 40 +#define BITMAPINFOHEADER_ASFBINDING_SIZE 41 +#define COMPRESSION_POS 16 + +typedef enum WMV_FORMAT { + WMV_FORMAT_VC1, + WMV_FORMAT_WMV3, + WMV_FORMAT_UNKNOWN +} WMV_FORMAT; + +/* + * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file + */ +typedef struct _BitmapInfoHhr +{ + OMX_U32 BiSize; + OMX_U32 BiWidth; + OMX_U32 BiHeight; + OMX_U16 BiPlanes; + OMX_U16 BiBitCount; + OMX_U32 BiCompression; + OMX_U32 BiSizeImage; + OMX_U32 BiXPelsPerMeter; + OMX_U32 BiYPelsPerMeter; + OMX_U32 BiClrUsed; + OMX_U32 BiClrImportant; +} BitmapInfoHhr; + +typedef struct _SEC_MFC_WMV_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFC; + WMV_FORMAT wmvFormat; + OMX_S32 returnCodec; +} SEC_MFC_WMV_HANDLE; + +typedef struct _SEC_WMV_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_WMVTYPE WmvComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_WMV_HANDLE hMFCWmvHandle; + + /* CSC FIMC handle */ +#ifdef USE_CSC_FIMC + OMX_PTR hFIMCHandle; +#endif +} SEC_WMV_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/vc1/library_register.c b/exynos/multimedia/openmax/component/video/dec/vc1/library_register.c new file mode 100644 index 0000000..ce04f18 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vc1/library_register.c @@ -0,0 +1,57 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.8.20 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_WMV_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) { + goto EXIT; + } + + /* component 1 - video decoder WMV */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_WMV_DEC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_WMV_DEC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} \ No newline at end of file diff --git a/exynos/multimedia/openmax/component/video/dec/vc1/library_register.h b/exynos/multimedia/openmax/component/video/dec/vc1/library_register.h new file mode 100644 index 0000000..adac586 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vc1/library_register.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author HyeYeon Chung (hyeon.chung.chung@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_WMV_DEC_REG +#define SEC_OMX_WMV_DEC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* WMV */ +#define SEC_OMX_COMPONENT_WMV_DEC "OMX.SEC.WMV.Decoder" +#define SEC_OMX_COMPONENT_WMV_DEC_ROLE "video_decoder.wmv" + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/exynos/multimedia/openmax/component/video/dec/vp8/Android.mk b/exynos/multimedia/openmax/component/video/dec/vp8/Android.mk new file mode 100644 index 0000000..e4629a6 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vp8/Android.mk @@ -0,0 +1,47 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Vp8dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.VP8.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +LOCAL_SHARED_LIBRARIES += libhwconverter +endif + +#ifeq ($(BOARD_USE_V4L2_ION),true) +#LOCAL_SHARED_LIBRARIES += libion +#endif + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.c b/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.c new file mode 100644 index 0000000..1642ac2 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.c @@ -0,0 +1,1547 @@ +/* + * + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vp8dec.c + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 1.1.0 + * @history + * 2011.11.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "library_register.h" +#include "SEC_OMX_Vp8dec.h" +#include "SsbSipMfcApi.h" +#include "color_space_convertor.h" + +#ifdef USE_ANB +#include "SEC_OSAL_Android.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VP8_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH /* Full frame search not support*/ + +static int Check_VP8_Frame(OMX_U8 *pInputStream, int buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + /* Uncompressed data Chunk comprises a common + (for key frames and interframes) 3-byte frame tag that + contains four fields + - 1-bit frame type (0 - key frame, 1 - inter frame) + - 3-bit version number (0 - 3 are defined as four different + profiles with different decoding complexity) + - 1-bit show_frame flag ( 0 - current frame not for display, + 1 - current frame is for dispaly) + - 19-bit field - size of the first data partition in bytes + + Key Frames : frame tag followed by 7 bytes of uncompressed + data + 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a) + Next 4-bytes: Width & height, Horizontal and vertical scale information + 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) + 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) + */ + int width, height; + int horizSscale, vertScale; + + FunctionIn(); + + *pbEndOfFrame = OMX_TRUE; + + /*Check for Key frame*/ + if (!(pInputStream[0] & 0x01)){ + /* Key Frame Start code*/ + if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { + SEC_OSAL_Log(SEC_LOG_ERROR, " VP8 Key Frame Start Code not Found"); + *pbEndOfFrame = OMX_FALSE; + } + SEC_OSAL_Log(SEC_LOG_TRACE, " VP8 Found Key Frame Start Code"); + width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff; + horizSscale = pInputStream[7] >> 6; + height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff; + vertScale = pInputStream[9] >> 6; + SEC_OSAL_Log(SEC_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale); + } + + FunctionOut(); + return buffSize; +} + +OMX_BOOL Check_VP8_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "streamSize: %d",streamSize); + if (streamSize < 3) { + return OMX_FALSE; + } + + if (!(pInputStream[0] & 0x01)){ + /* Key Frame Start code*/ + if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { + SEC_OSAL_Log(SEC_LOG_ERROR, " VP8 Key Frame Start Code not Found"); + return OMX_FALSE; + } + SEC_OSAL_Log(SEC_LOG_TRACE, " VP8 Found Key Frame Start Code"); + } + + return OMX_TRUE; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE); + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + realWidth = pSECPort->portDefinition.format.video.nFrameWidth; + realHeight = pSECPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + pSECOutputPort->portDefinition.nBufferSize = + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); + + if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pVp8Dec->hMFCVp8Handle.returnCodec = SsbSipMfcDecExe(pVp8Dec->hMFCVp8Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + OMX_PTR hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; + + pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + } else { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVp8Dec->hMFCVp8Handle.hMFCHandle = hMFCHandle; + + /* Allocate decoder's input buffer */ + /* Get first input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[0].dataSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + /* Get second input buffer */ + pStreamBuffer = NULL; + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; + pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; + pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; + pVideoDec->MFCDecInputBuffer[1].dataSize = 0; + pVideoDec->indexInputBuffer = 0; + + pVideoDec->bFirstFrame = OMX_TRUE; + + pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + pVideoDec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pVp8Dec->hMFCVp8Handle.returnCodec = MFC_RET_OK; + } +#endif + + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pVp8Dec->hMFCVp8Handle.indexTimestamp = 0; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0; + + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + OMX_PTR hMFCHandle = NULL; + + FunctionIn(); + + pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; + + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = NULL; + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { + pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); + pVideoDec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.hDecFrameStart = NULL; + } +#endif + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 setConfVal = 0; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize = 0; + OMX_U32 FrameBufferUVSize = 0; + OMX_BOOL outputDataValid = OMX_FALSE; + + FunctionIn(); + + if (pVp8Dec->hMFCVp8Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE eCodecType = VP8_DEC; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Default number in the driver is optimized */ + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + setConfVal = 0; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } else { + setConfVal = VP8_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); + + setConfVal = 8; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } + + SsbSipMfcDecSetInBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer, + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pVp8Dec->hMFCVp8Handle.returnCodec = SsbSipMfcDecInit(pVp8Dec->hMFCVp8Handle.hMFCHandle, eCodecType, oneFrameSize); + if (pVp8Dec->hMFCVp8Handle.returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); + SEC_OSAL_Log(SEC_LOG_ERROR, "set width height information : %d, %d", + pSECInputPort->portDefinition.format.video.nFrameWidth, + pSECInputPort->portDefinition.format.video.nFrameHeight); + SEC_OSAL_Log(SEC_LOG_ERROR, "mfc width height information : %d, %d", + imgResol.width, imgResol.height); + + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); + + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send Port Settings changed call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + + pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_TRUE; + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorInputDataDecodeYet; + goto EXIT; + } else { + ret = OMX_ErrorMFCInit; + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->nFlags; + + if ((pVp8Dec->hMFCVp8Handle.returnCodec == MFC_RET_OK) && + (pVideoDec->bFirstFrame == OMX_FALSE)) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + /* wait for mfc decode done */ + if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); + pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + status = SsbSipMfcDecGetOutBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if ((SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + outputDataValid = OMX_TRUE; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + outputDataValid = OMX_FALSE; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + outputDataValid = OMX_FALSE; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { + pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + + outputDataValid = OMX_FALSE; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + } + + if (ret == OMX_ErrorInputDataDecodeYet) { + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } + + if ((Check_VP8_StartCode(pInputData->dataBuffer, oneFrameSize) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pVp8Dec->hMFCVp8Handle.indexTimestamp)); + pVp8Dec->hMFCVp8Handle.indexTimestamp++; + pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + SsbSipMfcDecSetInBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer, + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; + pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; + + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); + pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; + pVp8Dec->hMFCVp8Handle.returnCodec = MFC_RET_OK; + + SEC_OSAL_SleepMillisec(0); + + pVideoDec->indexInputBuffer++; + pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; + + if ((pVideoDec->bFirstFrame == OMX_TRUE) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE) && + (outputDataValid == OMX_FALSE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + pVideoDec->bFirstFrame = OMX_FALSE; + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + } + + /** Fill Output Buffer **/ + if (outputDataValid == OMX_TRUE) { + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + unsigned int stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (width * height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 SP/P Output mode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + break; + case OMX_COLOR_FormatYUV420Planar: + default: + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + } else { + pOutputData->dataLen = 0; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_VP8_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 setConfVal = 0; + OMX_S32 returnCodec = 0; + int bufWidth = 0; + int bufHeight = 0; + OMX_U32 FrameBufferYSize; + OMX_U32 FrameBufferUVSize; + + FunctionIn(); + + if (pVp8Dec->hMFCVp8Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE eCodecType = VP8_DEC; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Default number in the driver is optimized */ + if (pVideoDec->bThumbnailMode == OMX_TRUE) { + setConfVal = 0; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } else { + setConfVal = VP8_DEC_NUM_OF_EXTRA_BUFFERS; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); + } + + returnCodec = SsbSipMfcDecInit(pVp8Dec->hMFCVp8Handle.hMFCHandle, eCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + + SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); + SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", + pSECInputPort->portDefinition.format.video.nFrameWidth, + pSECInputPort->portDefinition.format.video.nFrameHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", + imgResol.width, imgResol.height); + + /** Update Frame Size **/ + if ((pSECInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || + (pSECInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); + /* change width and height information */ + pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send Port Settings changed call back **/ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + + pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_TRUE; + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorInputDataDecodeYet; + goto EXIT; + } else { + ret = OMX_ErrorMFCInit; + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; +#endif + + if (Check_VP8_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { + pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pVp8Dec->hMFCVp8Handle.indexTimestamp)); + + returnCodec = SsbSipMfcDecExe(pVp8Dec->hMFCVp8Handle.hMFCHandle, oneFrameSize); + } else { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); + FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); + + if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { + pVp8Dec->hMFCVp8Handle.indexTimestamp++; + pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; + } + + if ((SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + /* For timestamp correction. if mfc support frametype detect */ + SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); +#ifdef NEED_TIMESTAMP_REORDER + if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; + } +#else + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; +#endif + SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + /** Fill Output Buffer **/ + void *pOutputBuf = (void *)pOutputData->dataBuffer; + void *pYUVBuf[3]; + + int frameSize = bufWidth * bufHeight; + int width = outputInfo.img_width; + int height = outputInfo.img_height; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + pOutputData->dataLen = (imageSize * 3) / 2; + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + unsigned int stride; + SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); + width = stride; + pOutputData->dataLen = sizeof(void *); + } +#endif + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (width * height * 3) / 2; + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 SP/P Output mode"); + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); + SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); + pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + case OMX_COLOR_FormatYUV420Planar: + default: + csc_tiled_to_linear_y_neon( + (unsigned char *)pYUVBuf[0], + (unsigned char *)outputInfo.YVirAddr, + width, + height); + csc_tiled_to_linear_uv_deinterleave_neon( + (unsigned char *)pYUVBuf[1], + (unsigned char *)pYUVBuf[2], + (unsigned char *)outputInfo.CVirAddr, + width, + height / 2); + break; + } + } + +#ifdef USE_ANB + if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { + SEC_OSAL_UnlockANB(pOutputData->dataBuffer); + } +#endif + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) + ret = OMX_ErrorInputDataDecodeYet; + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + } + pOutputData->dataLen = 0; + + /* ret = OMX_ErrorUndefined; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_VP8Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL endOfFrame = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_VP8_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_VP8_Decode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + //OMX_BOOL bFlashPlayerMode = OMX_FALSE; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_VP8_DEC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_DEC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pVp8Dec = SEC_OSAL_Malloc(sizeof(SEC_VP8DEC_HANDLE)); + if (pVp8Dec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pVp8Dec, 0, sizeof(SEC_VP8DEC_HANDLE)); + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec; + + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_VP8_DEC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /*for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); + pH264Dec->AVCComponent[i].nPortIndex = i; + pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; + pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; + }*/ + + pOMXComponent->GetParameter = &SEC_MFC_VP8Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_VP8Dec_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_VP8Dec_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_VP8Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_VP8Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_VP8Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_VP8Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_VP8Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_VP8Dec_bufferProcess; + pSECComponent->sec_checkInputFrame = &Check_VP8_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_VP8DEC_HANDLE *pVp8Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pVp8Dec != NULL) { + SEC_OSAL_Free(pVp8Dec); + pVp8Dec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.h b/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.h new file mode 100644 index 0000000..40ce20c --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vp8/SEC_OMX_Vp8dec.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vp8dec.h + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 1.1.0 + * @history + * 2011.10.10 : Create + */ + +#ifndef SEC_OMX_VP8_DEC_COMPONENT +#define SEC_OMX_VP8_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + + +typedef struct _SEC_MFC_VP8DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFC; + OMX_S32 returnCodec; +} SEC_MFC_VP8DEC_HANDLE; + +typedef struct _SEC_VP8DEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_VP8DEC_HANDLE hMFCVp8Handle; +} SEC_VP8DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/dec/vp8/library_register.c b/exynos/multimedia/openmax/component/video/dec/vp8/library_register.c new file mode 100644 index 0000000..13f7f4a --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vp8/library_register.c @@ -0,0 +1,58 @@ +/* + * + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 1.1.0 + * @history + * 2011.11.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VP8_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - video decoder VP8 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_VP8_DEC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_VP8_DEC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/video/dec/vp8/library_register.h b/exynos/multimedia/openmax/component/video/dec/vp8/library_register.h new file mode 100644 index 0000000..5e17150 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/dec/vp8/library_register.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 1.1.0 + * @history + * 2011.11.15 : Create + */ + +#ifndef SEC_OMX_VP8_DEC_REG +#define SEC_OMX_VP8_DEC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* VP8 */ +#define SEC_OMX_COMPONENT_VP8_DEC "OMX.SEC.VP8.Decoder" +#define SEC_OMX_COMPONENT_VP8_DEC_ROLE "video_decoder.vpx" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/enc/Android.mk b/exynos/multimedia/openmax/component/video/enc/Android.mk new file mode 100644 index 0000000..e13d54d --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Venc.c + +LOCAL_MODULE := libSEC_OMX_Venc +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +ifeq ($(BOARD_USE_STOREMETADATA), true) +LOCAL_CFLAGS += -DUSE_STOREMETADATA +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.c b/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.c new file mode 100644 index 0000000..d3f16b9 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.c @@ -0,0 +1,1802 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Venc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OMX_Venc.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_ETC.h" +#include "color_space_convertor.h" + +#ifdef USE_STOREMETADATA +#include "SEC_OSAL_Android.h" +#endif + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VIDEO_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((secOutputPort->portDefinition.format.video.nFrameWidth != + secInputPort->portDefinition.format.video.nFrameWidth) || + (secOutputPort->portDefinition.format.video.nFrameHeight != + secInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + secOutputPort->portDefinition.format.video.nFrameWidth = + secInputPort->portDefinition.format.video.nFrameWidth; + secOutputPort->portDefinition.format.video.nFrameHeight = + secInputPort->portDefinition.format.video.nFrameHeight; + width = secOutputPort->portDefinition.format.video.nStride = + secInputPort->portDefinition.format.video.nStride; + height = secOutputPort->portDefinition.format.video.nSliceHeight = + secInputPort->portDefinition.format.video.nSliceHeight; + + if (width && height) + secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + } + + return ; +} + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pSECPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + SEC_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = temp_buffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + SEC_OSAL_Free(temp_buffer); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { + (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, + pSECComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { + if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { + if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); + pSECPort->bufferHeader[i]->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pSECPort->assignedBufferNum--; + if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]); + pSECPort->bufferHeader[i] = NULL; + pBufferHdr = NULL; + } + pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECPort->assignedBufferNum == 0) { + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT* pSECPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + if ((pSECComponent->currentState == OMX_StateExecuting) && + (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) + return OMX_TRUE; + else + return OMX_FALSE; +} + +static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; + secOMXInputPort->markType.hMarkTargetComponent = NULL; + secOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + if (CHECK_PORT_TUNNELED(secOMXInputPort)) { + OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); + } else { + bufferHeader->nFilledLen = 0; + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE* message = NULL; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid = OMX_TRUE; + dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; + dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; + pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; + pSECComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { + OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); + } else { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + /* reset dataBuffer */ + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE *message = NULL; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid =OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + + return ret; +} + +static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; + + processData->dataLen = 0; + processData->remainDataLen = 0; + processData->usedDataLen = 0; + processData->nFlags = 0; + processData->timeStamp = 0; + + return ret; +} + +OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_U32 checkedSize = 0; + OMX_BOOL flagEOS = OMX_FALSE; + OMX_BOOL flagEOF = OMX_FALSE; + OMX_BOOL previousFrameEOF = OMX_FALSE; + + if (inputUseBuffer->dataValid == OMX_TRUE) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } + + if (inputData->dataLen == 0) { + previousFrameEOF = OMX_TRUE; + } else { + previousFrameEOF = OMX_FALSE; + } + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + flagEOF = OMX_TRUE; + checkedSize = checkInputStreamLen; + if (checkedSize == 0) { + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + int width = pSECPort->portDefinition.format.video.nFrameWidth; + int height = pSECPort->portDefinition.format.video.nFrameHeight; + inputUseBuffer->remainDataLen = inputUseBuffer->dataLen = (width * height * 3) / 2; + checkedSize = checkInputStreamLen = inputUseBuffer->remainDataLen; + inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS; + } + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) { + flagEOS = OMX_TRUE; + } + } else { + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + int width = pSECPort->portDefinition.format.video.nFrameWidth; + int height = pSECPort->portDefinition.format.video.nFrameHeight; + unsigned int oneFrameSize = 0; + + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + oneFrameSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + oneFrameSize = ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048); + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_Preprocessor_InputData: eColorFormat is wrong"); + break; + } + + if (previousFrameEOF == OMX_TRUE) { + if (checkInputStreamLen >= oneFrameSize) { + checkedSize = oneFrameSize; + flagEOF = OMX_TRUE; + } else { + flagEOF = OMX_FALSE; + } + } else { + if (checkInputStreamLen >= (oneFrameSize - inputData->dataLen)) { + checkedSize = oneFrameSize - inputData->dataLen; + flagEOF = OMX_TRUE; + } else { + flagEOF = OMX_FALSE; + } + } + + if ((flagEOF == OMX_FALSE) && (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + flagEOF = OMX_TRUE; + flagEOS = OMX_TRUE; + } + } + + if (flagEOF == OMX_TRUE) { + copySize = checkedSize; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); + } else { + copySize = checkInputStreamLen; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); + } + + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) + pSECComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if ((pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12TPhysicalAddress) && + (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LPhysicalAddress) && + (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LVirtualAddress)) { + if (flagEOF == OMX_TRUE) { + OMX_U32 width, height; + + width = pSECPort->portDefinition.format.video.nFrameWidth; + height = pSECPort->portDefinition.format.video.nFrameHeight; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->MFCEncInputBuffer[%d].YVirAddr : 0x%x", pVideoEnc->indexInputBuffer, pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->MFCEncInputBuffer[%d].CVirAddr : 0x%x", pVideoEnc->indexInputBuffer, pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr); + + SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Ysize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Csize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); + + if (pSECPort->bStoreMetaData == OMX_FALSE) { + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + /* YUV420Planar case it needed changed interleave UV plane (MFC spec.)*/ + SEC_OSAL_Memcpy(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr, + checkInputStream, (width * height)); + csc_interleave_memcpy_neon(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr, + checkInputStream + (width * height), + checkInputStream + (((width * height) * 5) / 4), + width * height >> 2); + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + SEC_OSAL_Memcpy(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr, + checkInputStream, (width * height)); + SEC_OSAL_Memcpy(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr, + checkInputStream + (width * height), (width * height / 2)); + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + SEC_OSAL_Memcpy(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr, + checkInputStream, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Memcpy(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr, + checkInputStream + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); + break; + default: + break; + } + } +#ifdef USE_METADATABUFFERTYPE + else { + if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + OMX_PTR ppBuf[3]; + OMX_PTR pOutBuffer; + + SEC_OSAL_GetInfoFromMetaData(inputData, ppBuf); + SEC_OSAL_LockANBHandle((OMX_U32)ppBuf[0], width, height, OMX_COLOR_FormatAndroidOpaque, &pOutBuffer); + + csc_ARGB8888_to_YUV420SP(pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr, + pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr, + pOutBuffer, width, height); + + SEC_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]); + } + } +#endif + } + } + + inputUseBuffer->dataLen -= copySize; /* ???????????? do not need ?????????????? */ + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + inputData->dataLen += copySize; + inputData->remainDataLen += copySize; + + if (previousFrameEOF == OMX_TRUE) { + inputData->timeStamp = inputUseBuffer->timeStamp; + inputData->nFlags = inputUseBuffer->nFlags; + } + + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } + } else { + if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); + flagEOF = OMX_FALSE; + } + + if (inputUseBuffer->remainDataLen == 0) { + if(flagEOF == OMX_FALSE) + SEC_InputBufferReturn(pOMXComponent); + } else { + inputUseBuffer->dataValid = OMX_TRUE; + } + } + + if (flagEOF == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + } + + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + return ret; +} + +OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp){ + pSECComponent->checkTimeStamp.startTimeStamp = -19761123; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + + if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = outputData->remainDataLen; + if (copySize > 0) + SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (outputData->dataBuffer + outputData->usedDataLen), + copySize); + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = outputData->nFlags; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_TRUE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + SEC_OutputBufferReturn(pOMXComponent); + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than encoded data size Out Length"); + + ret = OMX_FALSE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + if (((pSECComponent->currentState == OMX_StatePause) || + (pSECComponent->currentState == OMX_StateIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + } + + while (SEC_Check_BufferProcess_State(pSECComponent) && !pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = SEC_OutputBufferGetQueue(pSECComponent); + if ((ret == OMX_ErrorUndefined) || + (secInputPort->portState != OMX_StateIdle) || + (secOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pSECComponent->remainOutputData == OMX_FALSE) { + if (pSECComponent->reInputData == OMX_FALSE) { + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = SEC_InputBufferGetQueue(pSECComponent); + break; + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); + + if (inputUseBuffer->remainDataLen == 0) + SEC_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataEncodeYet) + pSECComponent->reInputData = OMX_TRUE; + else + pSECComponent->reInputData = OMX_FALSE; + } + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + + if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) + pSECComponent->remainOutputData = OMX_TRUE; + else + pSECComponent->remainOutputData = OMX_FALSE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pSECComponent->portParam.nPorts; + portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + + if (portIndex == INPUT_PORT_INDEX) { + supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + switch (index) { + case supportFormat_0: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_1: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_2: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12LPhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_4: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_5: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12LVirtualAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_6: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatAndroidOpaque; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + } + } else if (portIndex == OUTPUT_PORT_INDEX) { + supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; + portFormat->eColorFormat = portDefinition->format.video.eColorFormat; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + videoRateControl->eControlRate = pVideoEnc->eControlRate[portIndex]; + videoRateControl->nTargetBitrate = portDefinition->format.video.nBitrate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoQuantization: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoQuantizationControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + videoQuantizationControl->nQpI = pVideoEnc->quantization.nQpI; + videoQuantizationControl->nQpP = pVideoEnc->quantization.nQpP; + videoQuantizationControl->nQpB = pVideoEnc->quantization.nQpB; + } + ret = OMX_ErrorNone; + + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize); + +#ifdef USE_STOREMETADATA + if ((portIndex == 0) && + (pSECPort->bStoreMetaData == OMX_TRUE) && + (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LVirtualAddress)) { + portDefinition->nBufferSize = MAX_INPUT_METADATA_BUFFER_SIZE; + } +#endif + } + break; + default: + { + ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + portDefinition->format.video.eColorFormat = portFormat->eColorFormat; + portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; + portDefinition->format.video.xFramerate = portFormat->xFramerate; + } + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + pVideoEnc->eControlRate[portIndex] = videoRateControl->eControlRate; + portDefinition->format.video.nBitrate = videoRateControl->nTargetBitrate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoQuantization: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoQuantizationControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + pVideoEnc->quantization.nQpI = videoQuantizationControl->nQpI; + pVideoEnc->quantization.nQpP = videoQuantizationControl->nQpP; + pVideoEnc->quantization.nQpB = videoQuantizationControl->nQpB; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if(pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_UpdateFrameSize(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECOutputPort->portDefinition.nBufferSize: %d", + pSECOutputPort->portDefinition.nBufferSize); + } + ret = OMX_ErrorNone; + } + break; +#ifdef USE_STOREMETADATA + case OMX_IndexParamStoreMetaDataBuffer: + { + ret = SEC_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; +#endif + default: + { + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; + OMX_U32 portIndex = pEncodeBitrate->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pEncodeBitrate->nEncodeBitrate = pSECPort->portDefinition.format.video.nBitrate; + } + } + break; + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; + OMX_U32 portIndex = pFramerate->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pFramerate->xEncodeFramerate = pSECPort->portDefinition.format.video.xFramerate; + } + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) + { + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; + OMX_U32 portIndex = pEncodeBitrate->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portDefinition.format.video.nBitrate = pEncodeBitrate->nEncodeBitrate; + } + } + break; + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; + OMX_U32 portIndex = pFramerate->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portDefinition.format.video.xFramerate = pFramerate->xEncodeFramerate; + } + } + break; + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure; + SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + OMX_U32 portIndex = pIntraRefreshVOP->nPortIndex; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVEncBase->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP; + } + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + +#ifdef USE_STOREMETADATA + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) { + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer; + } else { + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); + } +#else + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoEnc = SEC_OSAL_Malloc(sizeof(SEC_OMX_VIDEOENC_COMPONENT)); + if (pVideoEnc == NULL) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OSAL_Memset(pVideoEnc, 0, sizeof(SEC_OMX_VIDEOENC_COMPONENT)); + pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; + + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + pVideoEnc->configChange = OMX_FALSE; + pVideoEnc->quantization.nQpI = 20; + pVideoEnc->quantization.nQpP = 20; + pVideoEnc->quantization.nQpB = 20; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = 0; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; + + pSECPort->bStoreMetaData = OMX_FALSE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; + + pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; + + pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; + pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; + pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; + pSECComponent->sec_BufferReset = &SEC_BufferReset; + pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; + pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OSAL_Free(pVideoEnc); + pSECComponent->hComponentHandle = pVideoEnc = NULL; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); + pSECPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = SEC_OMX_Port_Destructor(pOMXComponent); + + ret = SEC_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.h b/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.h new file mode 100644 index 0000000..b16b372 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/SEC_OMX_Venc.h @@ -0,0 +1,163 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Venc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_VIDEO_ENCODE +#define SEC_OMX_VIDEO_ENCODE + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" + +#define MAX_VIDEO_INPUTBUFFER_NUM 5 +#define MAX_VIDEO_OUTPUTBUFFER_NUM 4 + +#define DEFAULT_FRAME_WIDTH 176 +#define DEFAULT_FRAME_HEIGHT 144 + +#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT / 2)) + /* (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 */ +#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE DEFAULT_VIDEO_INPUT_BUFFER_SIZE + +#define MFC_INPUT_BUFFER_NUM_MAX 2 + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 7 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 + +#ifdef USE_STOREMETADATA +// The largest metadata buffer size advertised +// when metadata buffer mode is used for video encoding +#define MAX_INPUT_METADATA_BUFFER_SIZE (64) +#endif + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} MFC_ENC_ADDR_INFO; + +typedef struct _SEC_MFC_NBENC_THREAD +{ + OMX_HANDLETYPE hNBEncodeThread; + OMX_HANDLETYPE hEncFrameStart; + OMX_HANDLETYPE hEncFrameEnd; + OMX_BOOL bExitEncodeThread; + OMX_BOOL bEncoderRun; +} SEC_MFC_NBENC_THREAD; + +typedef struct _MFC_ENC_INPUT_BUFFER +{ + void *YPhyAddr; // physical address of Y + void *CPhyAddr; // physical address of CbCr + void *YVirAddr; // virtual address of Y + void *CVirAddr; // virtual address of CbCr + int YBufferSize; // input buffer alloc size of Y + int CBufferSize; // input buffer alloc size of CbCr + int YDataSize; // input size of Y data + int CDataSize; // input size of CbCr data +} MFC_ENC_INPUT_BUFFER; + +typedef struct _SEC_OMX_VIDEOENC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + SEC_MFC_NBENC_THREAD NBEncThread; + + OMX_BOOL configChange; + OMX_BOOL IntraRefreshVOP; + OMX_VIDEO_CONTROLRATETYPE eControlRate[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_QUANTIZATIONTYPE quantization; + OMX_BOOL bFirstFrame; + MFC_ENC_INPUT_BUFFER MFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; +} SEC_OMX_VIDEOENC_COMPONENT; + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer); +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/enc/h264/Android.mk b/exynos/multimedia/openmax/component/video/enc/h264/Android.mk new file mode 100644 index 0000000..435fbf7 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/h264/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_H264enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.AVC.Encoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/enc \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.c b/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.c new file mode 100644 index 0000000..dfba49d --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.c @@ -0,0 +1,1582 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264enc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Venc.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_Android.h" +#include "library_register.h" +#include "SEC_OMX_H264enc.h" +#include "SsbSipMfcApi.h" +#include "color_space_convertor.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_H264_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* H.264 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; + + +OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile) +{ + OMX_U32 ret = 0; //default OMX_VIDEO_AVCProfileMain + + if (profile == OMX_VIDEO_AVCProfileMain) + ret = 0; + else if (profile == OMX_VIDEO_AVCProfileHigh) + ret = 1; + else if (profile == OMX_VIDEO_AVCProfileBaseline) + ret = 2; + + return ret; +} + +OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level) +{ + OMX_U32 ret = 40; //default OMX_VIDEO_AVCLevel4 + + if (level == OMX_VIDEO_AVCLevel1) + ret = 10; + else if (level == OMX_VIDEO_AVCLevel1b) + ret = 9; + else if (level == OMX_VIDEO_AVCLevel11) + ret = 11; + else if (level == OMX_VIDEO_AVCLevel12) + ret = 12; + else if (level == OMX_VIDEO_AVCLevel13) + ret = 13; + else if (level == OMX_VIDEO_AVCLevel2) + ret = 20; + else if (level == OMX_VIDEO_AVCLevel21) + ret = 21; + else if (level == OMX_VIDEO_AVCLevel22) + ret = 22; + else if (level == OMX_VIDEO_AVCLevel3) + ret = 30; + else if (level == OMX_VIDEO_AVCLevel31) + ret = 31; + else if (level == OMX_VIDEO_AVCLevel32) + ret = 32; + else if (level == OMX_VIDEO_AVCLevel4) + ret = 40; + + return ret; +} + +OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size) +{ + OMX_U32 i; + + for (i = 0; i < size - 3; i++) { + if ((pBuffer[i] == 0x00) && + (pBuffer[i + 1] == 0x00) && + (pBuffer[i + 2] == 0x00) && + (pBuffer[i + 3] == 0x01)) + return (pBuffer + i); + } + + return NULL; +} + +void H264PrintParams(SSBSIP_MFC_ENC_H264_PARAM *h264Arg) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", h264Arg->SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", h264Arg->SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", h264Arg->ProfileIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", h264Arg->LevelIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", h264Arg->IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberReferenceFrames : %d\n", h264Arg->NumberReferenceFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberRefForPframes : %d\n", h264Arg->NumberRefForPframes); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", h264Arg->SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", h264Arg->SliceArgument); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", h264Arg->NumberBFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterDisable : %d\n", h264Arg->LoopFilterDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterAlphaC0Offset : %d\n", h264Arg->LoopFilterAlphaC0Offset); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterBetaOffset : %d\n", h264Arg->LoopFilterBetaOffset); + SEC_OSAL_Log(SEC_LOG_TRACE, "SymbolMode : %d\n", h264Arg->SymbolMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "PictureInterlace : %d\n", h264Arg->PictureInterlace); + SEC_OSAL_Log(SEC_LOG_TRACE, "Transform8x8Mode : %d\n", h264Arg->Transform8x8Mode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", h264Arg->RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", h264Arg->PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", h264Arg->LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", h264Arg->CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", h264Arg->CrPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", h264Arg->EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableMBRateControl : %d\n", h264Arg->EnableMBRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", h264Arg->FrameRate); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", h264Arg->Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", h264Arg->FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", h264Arg->QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", h264Arg->QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", h264Arg->CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "DarkDisable : %d\n", h264Arg->DarkDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "SmoothDisable : %d\n", h264Arg->SmoothDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "StaticDisable : %d\n", h264Arg->StaticDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "ActivityDisable : %d\n", h264Arg->ActivityDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", h264Arg->FrameMap); +} + +void Set_H264Enc_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pH264Arg->codecType = H264_ENC; + pH264Arg->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pH264Arg->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pH264Arg->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + pH264Arg->SliceMode = 0; + pH264Arg->RandomIntraMBRefresh = 0; + pH264Arg->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pH264Arg->QSCodeMax = 51; + pH264Arg->QSCodeMin = 10; + pH264Arg->PadControlOn = 0; // 0: disable, 1: enable + pH264Arg->LumaPadVal = 0; + pH264Arg->CbPadVal = 0; + pH264Arg->CrPadVal = 0; + + pH264Arg->ProfileIDC = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile); //0; //(OMX_VIDEO_AVCProfileMain) + pH264Arg->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); //40; //(OMX_VIDEO_AVCLevel4) + pH264Arg->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + pH264Arg->SliceArgument = 0; // Slice mb/byte size number + pH264Arg->NumberBFrames = 0; // 0 ~ 2 + pH264Arg->NumberReferenceFrames = 1; + pH264Arg->NumberRefForPframes = 1; + pH264Arg->LoopFilterDisable = 1; // 1: Loop Filter Disable, 0: Filter Enable + pH264Arg->LoopFilterAlphaC0Offset = 0; + pH264Arg->LoopFilterBetaOffset = 0; + pH264Arg->SymbolMode = 0; // 0: CAVLC, 1: CABAC + pH264Arg->PictureInterlace = 0; + pH264Arg->Transform8x8Mode = 0; // 0: 4x4, 1: allow 8x8 + pH264Arg->DarkDisable = 1; + pH264Arg->SmoothDisable = 1; + pH264Arg->StaticDisable = 1; + pH264Arg->ActivityDisable = 1; + + pH264Arg->FrameQp = pVideoEnc->quantization.nQpI; + pH264Arg->FrameQp_P = pVideoEnc->quantization.nQpP; + pH264Arg->FrameQp_B = pVideoEnc->quantization.nQpB; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateVariable: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 1; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; + pH264Arg->EnableMBRateControl = 0; + pH264Arg->CBRPeriodRf = 100; + break; + } + + switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: +#ifdef USE_METADATABUFFERTYPE + case OMX_COLOR_FormatAndroidOpaque: +#endif + pH264Arg->FrameMap = NV12_LINEAR; + break; + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12Tiled: + default: + pH264Arg->FrameMap = NV12_TILE; + break; + } + + H264PrintParams(pH264Arg); +} + +void Change_H264Enc_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + int set_conf_IntraRefreshVOP = 1; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, + MFC_ENC_SETCONF_FRAME_TYPE, + &set_conf_IntraRefreshVOP); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + if (pH264Arg->IDRPeriod != (int)pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1) { + int set_conf_IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, + MFC_ENC_SETCONF_I_PERIOD, + &set_conf_IDRPeriod); + } + if (pH264Arg->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { + int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + &set_conf_bitrate); + } + if (pH264Arg->FrameRate != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { + int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + &set_conf_framerate); + } + + Set_H264Enc_Param(pH264Arg, pSECComponent); + H264PrintParams(pH264Arg); +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pProfileLevel = supportedAVCProfileLevels; + maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; + pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex]; + pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; + pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + switch (nIndex) { + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure; + OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames; + } + } + break; + default: + ret = SEC_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + switch (nIndex) { + case OMX_IndexConfigVideoIntraPeriod: + { + SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1; + + pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames; + + ret = OMX_ErrorNone; + } + break; + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure; + OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1)) + pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames; + else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + } + break; + default: + ret = SEC_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + if (ret == OMX_ErrorNone) + pVideoEnc->configChange = OMX_TRUE; + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { + *pIndexType = OMX_IndexConfigVideoIntraPeriod; + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + while (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameStart); + + if (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameEnd); + } + } + +EXIT: + FunctionOut(); + SEC_OSAL_ThreadExit(NULL); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + OMX_PTR hMFCHandle = NULL; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Function Codec) encoder and CMM(Codec Memory Management) driver open */ + switch (pSECInputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); + break; + default: { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpenExt(&buf_type); + break; + } + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Enc->hMFCH264Handle.hMFCHandle = hMFCHandle; + + Set_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); + + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pH264Enc->hMFCH264Handle.mfcVideoAvc)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* Allocate encoder's input buffer */ + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->MFCEncInputBuffer[0].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; + pVideoEnc->MFCEncInputBuffer[0].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; + pVideoEnc->MFCEncInputBuffer[0].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; + pVideoEnc->MFCEncInputBuffer[0].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; + pVideoEnc->MFCEncInputBuffer[0].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; + pVideoEnc->MFCEncInputBuffer[0].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + pVideoEnc->MFCEncInputBuffer[0].YDataSize = 0; + pVideoEnc->MFCEncInputBuffer[0].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); + + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->MFCEncInputBuffer[1].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; + pVideoEnc->MFCEncInputBuffer[1].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; + pVideoEnc->MFCEncInputBuffer[1].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; + pVideoEnc->MFCEncInputBuffer[1].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; + pVideoEnc->MFCEncInputBuffer[1].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; + pVideoEnc->MFCEncInputBuffer[1].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + pVideoEnc->MFCEncInputBuffer[1].YDataSize = 0; + pVideoEnc->MFCEncInputBuffer[1].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); + + pVideoEnc->indexInputBuffer = 0; + + pVideoEnc->bFirstFrame = OMX_TRUE; + +#ifdef NONBLOCK_MODE_PROCESS + pVideoEnc->NBEncThread.bExitEncodeThread = OMX_FALSE; + pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; + SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoEnc->NBEncThread.hNBEncodeThread, + SEC_MFC_EncodeThread, + pOMXComponent)) { + pH264Enc->hMFCH264Handle.returnCodec = MFC_RET_OK; + } +#endif + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Enc->hMFCH264Handle.indexTimestamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_H264ENC_HANDLE *pH264Enc = NULL; + OMX_PTR hMFCHandle = NULL; + + FunctionIn(); + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoEnc->NBEncThread.hNBEncodeThread != NULL) { + pVideoEnc->NBEncThread.bExitEncodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); + SEC_OSAL_ThreadTerminate(pVideoEnc->NBEncThread.hNBEncodeThread); + pVideoEnc->NBEncThread.hNBEncodeThread = NULL; + } + + if(pVideoEnc->NBEncThread.hEncFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameEnd); + pVideoEnc->NBEncThread.hEncFrameEnd = NULL; + } + + if(pVideoEnc->NBEncThread.hEncFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameStart); + pVideoEnc->NBEncThread.hEncFrameStart = NULL; + } +#endif + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + if (hMFCHandle != NULL) { + SsbSipMfcEncClose(hMFCHandle); + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Encode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo; + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + + FunctionIn(); + + if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + OMX_U8 *p = NULL; + int iSpsSize = 0; + int iPpsSize = 0; + + p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4); + + iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; + + iPpsSize = outputInfo.headerSize - iSpsSize; + pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = (OMX_U8 *)outputInfo.StrmVirAddr + iSpsSize; + pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + } + + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = 0; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; + + ret = OMX_ErrorInputDataEncodeYet; + goto EXIT; + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)){ + /* Dummy input data for get out encoded last frame */ + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + } else { + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: { +#ifndef USE_METADATABUFFERTYPE + /* USE_FIMC_FRAME_BUFFER */ + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); +#else + OMX_PTR ppBuf[3]; + SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); + + SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); +#endif + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + } + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + addrInfo.pAddrY = *((void **)pInputData->dataBuffer); + addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); + + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + default: + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + break; + } + } + + pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + + if ((pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) && + (pVideoEnc->bFirstFrame == OMX_FALSE)) { + OMX_S32 indexTimestamp = 0; + + /* wait for mfc encode done */ + if (pVideoEnc->NBEncThread.bEncoderRun != OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameEnd); + pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->usedDataLen = 0; + + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + + ret = OMX_ErrorNone; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pH264Enc->hMFCH264Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + if (pSECComponent->getAllDelayBuffer == OMX_TRUE) { + ret = OMX_ErrorInputDataEncodeYet; + } + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataEncodeYet; + } + if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pOutputData->dataLen = 0; + pOutputData->usedDataLen = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_BUFFERFLAG_EOS!!!"); + ret = OMX_ErrorNone; + } + } + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe Failed!!!\n", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pVideoEnc->indexInputBuffer++; + pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pVideoEnc->configChange == OMX_TRUE) { + Change_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); + + /* mfc encode start */ + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); + pVideoEnc->NBEncThread.bEncoderRun = OMX_TRUE; + pH264Enc->hMFCH264Handle.indexTimestamp++; + pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + pVideoEnc->bFirstFrame = OMX_FALSE; + SEC_OSAL_SleepMillisec(0); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Encode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo; + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if (returnCodec != MFC_RET_OK) + { + SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + OMX_U8 *p = NULL; + int iSpsSize = 0; + int iPpsSize = 0; + + p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4); + + iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; + + iPpsSize = outputInfo.headerSize - iSpsSize; + pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = (OMX_U8 *)outputInfo.StrmVirAddr + iSpsSize; + pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + } + + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = 0; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; + + ret = OMX_ErrorInputDataEncodeYet; + goto EXIT; + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: { +#ifndef USE_METADATABUFFERTYPE + /* USE_FIMC_FRAME_BUFFER */ + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); +#else + OMX_PTR ppBuf[3]; + SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); + + SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); +#endif + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + } + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + addrInfo.pAddrY = *((void **)pInputData->dataBuffer); + addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); + + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + default: + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + break; + } + + returnCodec = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); + if (returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pVideoEnc->indexInputBuffer++; + pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pVideoEnc->configChange == OMX_TRUE) { + Change_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); + + returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); + if (returnCodec == MFC_RET_OK) { + OMX_S32 indexTimestamp = 0; + + pH264Enc->hMFCH264Handle.indexTimestamp++; + pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + + returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->usedDataLen = 0; + + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + + ret = OMX_ErrorNone; + } + } + + if (returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe OR SsbSipMfcEncGetOutBuf Failed!!!\n", __func__); + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Encode */ +OMX_ERRORTYPE SEC_MFC_H264Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL endOfFrame = OMX_FALSE; + OMX_BOOL flagEOS = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_H264_Encode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_H264_Encode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataEncodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + /* pOutputData->usedDataLen = 0; */ + pOutputData->remainDataLen = pOutputData->dataLen - pOutputData->usedDataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_ENC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_ENC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Enc = SEC_OSAL_Malloc(sizeof(SEC_H264ENC_HANDLE)); + if (pH264Enc == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pH264Enc, 0, sizeof(SEC_H264ENC_HANDLE)); + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc; + + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_ENC); + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); + pH264Enc->AVCComponent[i].nPortIndex = i; + pH264Enc->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; + pH264Enc->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel31; + + pH264Enc->AVCComponent[i].nPFrames = 20; + } + + pOMXComponent->GetParameter = &SEC_MFC_H264Enc_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_H264Enc_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_H264Enc_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_H264Enc_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Enc_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Enc_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Enc_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Enc_bufferProcess; + pSECComponent->sec_checkInputFrame = NULL; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pH264Enc != NULL) { + SEC_OSAL_Free(pH264Enc); + pH264Enc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.h b/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.h new file mode 100644 index 0000000..cc0a94f --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/h264/SEC_OMX_H264enc.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264enc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_ENC_COMPONENT +#define SEC_OMX_H264_ENC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "SsbSipMfcApi.h" + + +typedef struct _EXTRA_DATA +{ + OMX_PTR pHeaderSPS; + OMX_U32 SPSLen; + OMX_PTR pHeaderPPS; + OMX_U32 PPSLen; +} EXTRA_DATA; + +typedef struct _SEC_MFC_H264ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + SSBSIP_MFC_ENC_H264_PARAM mfcVideoAvc; + SSBSIP_MFC_ENC_INPUT_INFO inputInfo; +/* SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; */ + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + EXTRA_DATA headerData; + OMX_S32 returnCodec; +} SEC_MFC_H264ENC_HANDLE; + +typedef struct _SEC_H264ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_H264ENC_HANDLE hMFCH264Handle; +} SEC_H264ENC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/enc/h264/library_register.c b/exynos/multimedia/openmax/component/video/enc/h264/library_register.c new file mode 100644 index 0000000..e24e126 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/h264/library_register.c @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) +{ + FunctionIn(); + + if (secComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPONENT_H264_ENC); + SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPONENT_H264_ENC_ROLE); + secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/video/enc/h264/library_register.h b/exynos/multimedia/openmax/component/video/enc/h264/library_register.h new file mode 100644 index 0000000..9511e3c --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/h264/library_register.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_REG +#define SEC_OMX_H264_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* H.264 */ +#define SEC_OMX_COMPONENT_H264_ENC "OMX.SEC.AVC.Encoder" +#define SEC_OMX_COMPONENT_H264_ENC_ROLE "video_encoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/exynos/multimedia/openmax/component/video/enc/mpeg4/Android.mk b/exynos/multimedia/openmax/component/video/enc/mpeg4/Android.mk new file mode 100644 index 0000000..ad6a604 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/mpeg4/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Mpeg4enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.M4V.Encoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) +LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc libsecosal libsecbasecomponent \ + libseccscapi libsecmfcapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libSEC_OMX_Resourcemanager + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/enc \ + $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c b/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c new file mode 100644 index 0000000..ebfbe6e --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c @@ -0,0 +1,1774 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4enc.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Venc.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Android.h" +#include "library_register.h" +#include "SEC_OMX_Mpeg4enc.h" +#include "SsbSipMfcApi.h" +#include "color_space_convertor.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* MPEG4 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; + +/* H.263 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}}; + +OMX_U32 OMXMpeg4ProfileToMFCProfile(OMX_VIDEO_MPEG4PROFILETYPE profile) +{ + OMX_U32 ret; + + switch (profile) { + case OMX_VIDEO_MPEG4ProfileSimple: + ret = 0; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedSimple: + ret = 1; + break; + default: + ret = 0; + }; + + return ret; +} +OMX_U32 OMXMpeg4LevelToMFCLevel(OMX_VIDEO_MPEG4LEVELTYPE level) +{ + OMX_U32 ret; + + switch (level) { + case OMX_VIDEO_MPEG4Level0: + ret = 0; + break; + case OMX_VIDEO_MPEG4Level0b: + ret = 9; + break; + case OMX_VIDEO_MPEG4Level1: + ret = 1; + break; + case OMX_VIDEO_MPEG4Level2: + ret = 2; + break; + case OMX_VIDEO_MPEG4Level3: + ret = 3; + break; + case OMX_VIDEO_MPEG4Level4: + case OMX_VIDEO_MPEG4Level4a: + ret = 4; + break; + case OMX_VIDEO_MPEG4Level5: + ret = 5; + break; + default: + ret = 0; + }; + + return ret; +} + +void Mpeg4PrintParams(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", pMpeg4Param->SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", pMpeg4Param->SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", pMpeg4Param->IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", pMpeg4Param->SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", pMpeg4Param->RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", pMpeg4Param->EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", pMpeg4Param->Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", pMpeg4Param->FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", pMpeg4Param->FrameQp_P); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", pMpeg4Param->QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", pMpeg4Param->QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", pMpeg4Param->CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", pMpeg4Param->PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", pMpeg4Param->LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", pMpeg4Param->CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", pMpeg4Param->CrPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", pMpeg4Param->FrameMap); + + /* MPEG4 specific parameters */ + SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", pMpeg4Param->ProfileIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", pMpeg4Param->LevelIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_B : %d\n", pMpeg4Param->FrameQp_B); + SEC_OSAL_Log(SEC_LOG_TRACE, "TimeIncreamentRes : %d\n", pMpeg4Param->TimeIncreamentRes); + SEC_OSAL_Log(SEC_LOG_TRACE, "VopTimeIncreament : %d\n", pMpeg4Param->VopTimeIncreament); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", pMpeg4Param->SliceArgument); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", pMpeg4Param->NumberBFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "DisableQpelME : %d\n", pMpeg4Param->DisableQpelME); +} + +void H263PrintParams(SSBSIP_MFC_ENC_H263_PARAM *pH263Param) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", pH263Param->SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", pH263Param->SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", pH263Param->IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", pH263Param->SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", pH263Param->RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", pH263Param->EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", pH263Param->Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", pH263Param->FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", pH263Param->FrameQp_P); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", pH263Param->QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", pH263Param->QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", pH263Param->CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", pH263Param->PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", pH263Param->LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", pH263Param->CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", pH263Param->CrPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", pH263Param->FrameMap); + + /* H.263 specific parameters */ + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", pH263Param->FrameRate); +} + +void Set_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pMpeg4Param->codecType = MPEG4_ENC; + pMpeg4Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pMpeg4Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pMpeg4Param->IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pMpeg4Param->SliceMode = 0; + pMpeg4Param->RandomIntraMBRefresh = 0; + pMpeg4Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pMpeg4Param->QSCodeMax = 30; + pMpeg4Param->QSCodeMin = 10; + pMpeg4Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pMpeg4Param->LumaPadVal = 0; + pMpeg4Param->CbPadVal = 0; + pMpeg4Param->CrPadVal = 0; + + pMpeg4Param->ProfileIDC = OMXMpeg4ProfileToMFCProfile(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eProfile); + pMpeg4Param->LevelIDC = OMXMpeg4LevelToMFCLevel(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eLevel); + pMpeg4Param->TimeIncreamentRes = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + pMpeg4Param->VopTimeIncreament = 1; + pMpeg4Param->SliceArgument = 0; /* MB number or byte number */ + pMpeg4Param->NumberBFrames = 0; /* 0(not used) ~ 2 */ + pMpeg4Param->DisableQpelME = 1; + + pMpeg4Param->FrameQp = pVideoEnc->quantization.nQpI; + pMpeg4Param->FrameQp_P = pVideoEnc->quantization.nQpP; + pMpeg4Param->FrameQp_B = pVideoEnc->quantization.nQpB; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateVariable: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pMpeg4Param->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pMpeg4Param->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pMpeg4Param->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pMpeg4Param->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pMpeg4Param->EnableFRMRateControl = 0; + pMpeg4Param->CBRPeriodRf = 100; + break; + } + + switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: +#ifdef METADATABUFFERTYPE + case OMX_COLOR_FormatAndroidOpaque: +#endif + pMpeg4Param->FrameMap = NV12_LINEAR; + break; + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12Tiled: + default: + pMpeg4Param->FrameMap = NV12_TILE; + break; + } + + Mpeg4PrintParams(pMpeg4Param); +} + +void Change_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + int set_conf_IntraRefreshVOP = 1; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_FRAME_TYPE, + &set_conf_IntraRefreshVOP); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + + if (pMpeg4Param->IDRPeriod != (int)pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1) { + int set_conf_IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_I_PERIOD, + &set_conf_IDRPeriod); + } + if (pMpeg4Param->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { + int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + &set_conf_bitrate); + } + if (pMpeg4Param->TimeIncreamentRes != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { + int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + &set_conf_framerate); + } + + Set_Mpeg4Enc_Param(pMpeg4Param, pSECComponent); + Mpeg4PrintParams(pMpeg4Param); +} + +void Set_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pH263Param->codecType = H263_ENC; + pH263Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pH263Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pH263Param->IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pH263Param->SliceMode = 0; + pH263Param->RandomIntraMBRefresh = 0; + pH263Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pH263Param->QSCodeMax = 30; + pH263Param->QSCodeMin = 10; + pH263Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pH263Param->LumaPadVal = 0; + pH263Param->CbPadVal = 0; + pH263Param->CrPadVal = 0; + + pH263Param->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + + pH263Param->FrameQp = pVideoEnc->quantization.nQpI; + pH263Param->FrameQp_P = pVideoEnc->quantization.nQpP; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateVariable: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH263Param->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pH263Param->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pH263Param->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH263Param->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH263Param->EnableFRMRateControl = 0; + pH263Param->CBRPeriodRf = 100; + break; + } + + switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + case OMX_COLOR_FormatYUV420SemiPlanar: + pH263Param->FrameMap = NV12_LINEAR; + break; + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12Tiled: + default: + pH263Param->FrameMap = NV12_TILE; + break; + } + + H263PrintParams(pH263Param); +} + +void Change_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + int set_conf_IntraRefreshVOP = 1; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_FRAME_TYPE, + &set_conf_IntraRefreshVOP); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + if (pH263Param->IDRPeriod != (int)pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1) { + int set_conf_IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_I_PERIOD, + &set_conf_IDRPeriod); + } + if (pH263Param->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { + int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + &set_conf_bitrate); + } + if (pH263Param->FrameRate != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { + int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + &set_conf_framerate); + } + + Set_H263Enc_Param(pH263Param, pSECComponent); + H263PrintParams(pH263Param); +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcH263Param = &pMpeg4Enc->h263Component[pDstH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); + else + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; + } else { + pSrcH263Param = &pMpeg4Enc->h263Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcH263Param->eProfile; + pDstProfileLevel->eLevel = pSrcH263Param->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstH263Param = &pMpeg4Enc->h263Component[pSrcH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + //((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; + } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + //((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + /* + * To do: Check validity of profile & level parameters + */ + + pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; + } else { + /* + * To do: Check validity of profile & level parameters + */ + + pDstH263Param = &pMpeg4Enc->h263Component[pSrcProfileLevel->nPortIndex]; + pDstH263Param->eProfile = pSrcProfileLevel->eProfile; + pDstH263Param->eLevel = pSrcProfileLevel->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + + switch (nIndex) { + case OMX_IndexConfigVideoIntraPeriod: + { + SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1; + + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames; + else + pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames; + + ret = OMX_ErrorNone; + } + break; + default: + ret = SEC_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + if (ret == OMX_ErrorNone) + pVideoEnc->configChange = OMX_TRUE; + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { + *pIndexType = OMX_IndexConfigVideoIntraPeriod; + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); + else + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + while (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameStart); + + if (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncExe(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle); + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameEnd); + } + } + +EXIT: + FunctionOut(); + SEC_OSAL_ThreadExit(NULL); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Format Codec) encoder and CMM(Codec Memory Management) driver open */ + switch (pSECInputPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); + break; + default: { + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpenExt(&buf_type); + break; + } + } + + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; + + /* set MFC ENC VIDEO PARAM and initialize MFC encoder instance */ + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + Set_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam)); + } else { + Set_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam)); + } + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* Allocate encoder's input buffer */ + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->MFCEncInputBuffer[0].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; + pVideoEnc->MFCEncInputBuffer[0].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; + pVideoEnc->MFCEncInputBuffer[0].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; + pVideoEnc->MFCEncInputBuffer[0].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; + pVideoEnc->MFCEncInputBuffer[0].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; + pVideoEnc->MFCEncInputBuffer[0].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + pVideoEnc->MFCEncInputBuffer[0].YDataSize = 0; + pVideoEnc->MFCEncInputBuffer[0].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); + + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->MFCEncInputBuffer[1].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; + pVideoEnc->MFCEncInputBuffer[1].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; + pVideoEnc->MFCEncInputBuffer[1].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; + pVideoEnc->MFCEncInputBuffer[1].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; + pVideoEnc->MFCEncInputBuffer[1].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; + pVideoEnc->MFCEncInputBuffer[1].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + pVideoEnc->MFCEncInputBuffer[1].YDataSize = 0; + pVideoEnc->MFCEncInputBuffer[1].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); + + pVideoEnc->indexInputBuffer = 0; + + pVideoEnc->bFirstFrame = OMX_TRUE; + +#ifdef NONBLOCK_MODE_PROCESS + pVideoEnc->NBEncThread.bExitEncodeThread = OMX_FALSE; + pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; + SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoEnc->NBEncThread.hNBEncodeThread, + SEC_MFC_EncodeThread, + pOMXComponent)) { + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + } +#endif + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + + FunctionIn(); + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; +#ifdef NONBLOCK_MODE_PROCESS + if (pVideoEnc->NBEncThread.hNBEncodeThread != NULL) { + pVideoEnc->NBEncThread.bExitEncodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); + SEC_OSAL_ThreadTerminate(pVideoEnc->NBEncThread.hNBEncodeThread); + pVideoEnc->NBEncThread.hNBEncodeThread = NULL; + } + + if(pVideoEnc->NBEncThread.hEncFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameEnd); + pVideoEnc->NBEncThread.hEncFrameEnd = NULL; + } + + if(pVideoEnc->NBEncThread.hEncFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameStart); + pVideoEnc->NBEncThread.hEncFrameStart = NULL; + } +#endif + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + if (hMFCHandle != NULL) { + SsbSipMfcEncClose(hMFCHandle); + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo); + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + + FunctionIn(); + + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) + { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = 0; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + + ret = OMX_ErrorInputDataEncodeYet; + goto EXIT; + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)){ + /* Dummy input data for get out encoded last frame */ + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + } else { + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: { +#ifndef USE_METADATABUFFERTYPE + /* USE_FIMC_FRAME_BUFFER */ + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); +#else + OMX_PTR ppBuf[3]; + SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); + + SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); +#endif + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + } + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + addrInfo.pAddrY = *((void **)pInputData->dataBuffer); + addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); + + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + default: + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + break; + } + } + + pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + + if ((pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && + (pVideoEnc->bFirstFrame == OMX_FALSE)) { + OMX_S32 indexTimestamp = 0; + + /* wait for mfc encode done */ + if (pVideoEnc->NBEncThread.bEncoderRun != OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameEnd); + pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; + } + + SEC_OSAL_SleepMillisec(0); + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &outputInfo); + if ((SsbSipMfcEncGetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->usedDataLen = 0; + + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + + ret = OMX_ErrorNone; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + if (pSECComponent->getAllDelayBuffer == OMX_TRUE) { + ret = OMX_ErrorInputDataEncodeYet; + } + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataEncodeYet; + } + if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pOutputData->dataLen = 0; + pOutputData->usedDataLen = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_BUFFERFLAG_EOS!!!"); + ret = OMX_ErrorNone; + } + } + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe Failed!!!\n", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pVideoEnc->indexInputBuffer++; + pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pVideoEnc->configChange == OMX_TRUE) { + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + Change_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); + else + Change_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); + + /* mfc encode start */ + SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); + pVideoEnc->NBEncThread.bEncoderRun = OMX_TRUE; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + pVideoEnc->bFirstFrame = OMX_FALSE; + SEC_OSAL_SleepMillisec(0); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo); + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + if (returnCodec != MFC_RET_OK) + { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = 0; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + + ret = OMX_ErrorInputDataEncodeYet; + goto EXIT; + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) + pSECComponent->bUseFlagEOF = OMX_TRUE; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + switch (pSECPort->portDefinition.format.video.eColorFormat) { + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: { +#ifndef USE_METADATABUFFERTYPE + /* USE_FIMC_FRAME_BUFFER */ + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); +#else + OMX_PTR ppBuf[3]; + SEC_OSAL_GetInfoFromMetaData(pInputData,ppBuf); + + SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); +#endif + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + } + case OMX_SEC_COLOR_FormatNV12LVirtualAddress: + addrInfo.pAddrY = *((void **)pInputData->dataBuffer); + addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); + + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + break; + default: + pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; + pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; + pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; + pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; + break; + } + + returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); + if (returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pVideoEnc->indexInputBuffer++; + pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pVideoEnc->configChange == OMX_TRUE) { + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + Change_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); + else + Change_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); + + returnCodec = SsbSipMfcEncExe(hMFCHandle); + if (returnCodec == MFC_RET_OK) { + OMX_S32 indexTimestamp = 0; + + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + + returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + + if ((SsbSipMfcEncGetConfig(hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + ret = OMX_ErrorNone; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + } + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Encode */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + goto EXIT; + } + +#ifdef NONBLOCK_MODE_PROCESS + ret = SEC_MFC_Mpeg4_Encode_Nonblock(pOMXComponent, pInputData, pOutputData); +#else + ret = SEC_MFC_Mpeg4_Encode_Block(pOMXComponent, pInputData, pOutputData); +#endif + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataEncodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType = -1; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MPEG4_ENC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H263_ENC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_ENC_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Enc = SEC_OSAL_Malloc(sizeof(SEC_MPEG4ENC_HANDLE)); + if (pMpeg4Enc == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4ENC_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pMpeg4Enc, 0, sizeof(SEC_MPEG4ENC_HANDLE)); + pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; + pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Enc; + pMpeg4Enc->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MPEG4_ENC); + else + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H263_ENC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate= (15 << 16); + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate= (15 << 16); + if (codecType == CODEC_TYPE_MPEG4) { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (codecType == CODEC_TYPE_MPEG4) { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Enc->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); + pMpeg4Enc->mpeg4Component[i].nPortIndex = i; + pMpeg4Enc->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; + pMpeg4Enc->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level4; + + pMpeg4Enc->mpeg4Component[i].nPFrames = 10; + pMpeg4Enc->mpeg4Component[i].nBFrames = 0; /* No support for B frames */ + pMpeg4Enc->mpeg4Component[i].nMaxPacketSize = 256; /* Default value */ + pMpeg4Enc->mpeg4Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + pMpeg4Enc->mpeg4Component[i].bGov = OMX_FALSE; + + } + } else { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Enc->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); + pMpeg4Enc->h263Component[i].nPortIndex = i; + pMpeg4Enc->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline; + pMpeg4Enc->h263Component[i].eLevel = OMX_VIDEO_H263Level45; + + pMpeg4Enc->h263Component[i].nPFrames = 20; + pMpeg4Enc->h263Component[i].nBFrames = 0; /* No support for B frames */ + pMpeg4Enc->h263Component[i].bPLUSPTYPEAllowed = OMX_FALSE; + pMpeg4Enc->h263Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + pMpeg4Enc->h263Component[i].bForceRoundingTypeToZero = OMX_TRUE; + pMpeg4Enc->h263Component[i].nPictureHeaderRepetition = 0; + pMpeg4Enc->h263Component[i].nGOBHeaderInterval = 0; + } + } + + pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Enc_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Enc_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_Mpeg4Enc_GetConfig; + pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Enc_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_Mpeg4Enc_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Enc_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Enc_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Enc_bufferProcess; + pSECComponent->sec_checkInputFrame = NULL; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; + if (pMpeg4Enc != NULL) { + SEC_OSAL_Free(pMpeg4Enc); + pMpeg4Enc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h b/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h new file mode 100644 index 0000000..aa32c42 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4enc.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_ENC_COMPONENT +#define SEC_OMX_MPEG4_ENC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SsbSipMfcApi.h" + + +typedef enum _CODEC_TYPE +{ + CODEC_TYPE_H263, + CODEC_TYPE_MPEG4 +} CODEC_TYPE; + +typedef struct _SEC_MFC_MPEG4ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + SSBSIP_MFC_ENC_MPEG4_PARAM mpeg4MFCParam; + SSBSIP_MFC_ENC_H263_PARAM h263MFCParam; + SSBSIP_MFC_ENC_INPUT_INFO inputInfo; + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + CODEC_TYPE codecType; + OMX_S32 returnCodec; +} SEC_MFC_MPEG4ENC_HANDLE; + +typedef struct _SEC_MPEG4ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_MPEG4ENC_HANDLE hMFCMpeg4Handle; +} SEC_MPEG4ENC_HANDLE; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.c b/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.c new file mode 100644 index 0000000..d43b2d7 --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.c @@ -0,0 +1,64 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - video encoder MPEG4 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MPEG4_ENC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video encoder H.263 */ + SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPONENT_H263_ENC); + SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPONENT_H263_ENC_ROLE); + ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.h b/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.h new file mode 100644 index 0000000..42a168b --- /dev/null +++ b/exynos/multimedia/openmax/component/video/enc/mpeg4/library_register.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_ENC_REG +#define SEC_OMX_MPEG4_ENC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define SEC_OMX_COMPONENT_MPEG4_ENC "OMX.SEC.MPEG4.Encoder" +#define SEC_OMX_COMPONENT_MPEG4_ENC_ROLE "video_encoder.mpeg4" + +/* H.263 */ +#define SEC_OMX_COMPONENT_H263_ENC "OMX.SEC.H263.Encoder" +#define SEC_OMX_COMPONENT_H263_ENC_ROLE "video_encoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/exynos/multimedia/openmax/core/Android.mk b/exynos/multimedia/openmax/core/Android.mk new file mode 100644 index 0000000..8922e4b --- /dev/null +++ b/exynos/multimedia/openmax/core/Android.mk @@ -0,0 +1,26 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := SEC_OMX_Component_Register.c \ + SEC_OMX_Core.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libSEC_OMX_Core + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libsecosal libsecbasecomponent +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils \ + libSEC_OMX_Resourcemanager + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_TOP)/component/common + +include $(BUILD_SHARED_LIBRARY) + diff --git a/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.c b/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.c new file mode 100644 index 0000000..27a8805 --- /dev/null +++ b/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.c @@ -0,0 +1,264 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Component_Register.c + * @brief SEC OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OMX_Component.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Library.h" +#include "SEC_OMX_Component_Register.h" +#include "SEC_OMX_Macros.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_COMP_REGS" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + int componentNum = 0, roleNum = 0, totalCompNum = 0; + int read; + char *libName; + size_t len; + const char *errorMsg; + DIR *dir; + struct dirent *d; + + int (*SEC_OMX_COMPONENT_Library_Register)(SECRegisterComponentType **secComponents); + SECRegisterComponentType **secComponentsTemp; + SEC_OMX_COMPONENT_REGLIST *componentList; + + FunctionIn(); + + dir = opendir(SEC_OMX_INSTALL_PATH); + if (dir == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + componentList = (SEC_OMX_COMPONENT_REGLIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + libName = SEC_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); + + while ((d = readdir(dir)) != NULL) { + OMX_HANDLETYPE soHandle; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s", d->d_name); + + if (SEC_OSAL_Strncmp(d->d_name, "libOMX.SEC.", SEC_OSAL_Strlen("libOMX.SEC.")) == 0) { + SEC_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); + SEC_OSAL_Strcpy(libName, SEC_OMX_INSTALL_PATH); + SEC_OSAL_Strcat(libName, d->d_name); + SEC_OSAL_Log(SEC_LOG_ERROR, "Path & libName : %s", libName); + if ((soHandle = SEC_OSAL_dlopen(libName, RTLD_NOW)) != NULL) { + SEC_OSAL_dlerror(); /* clear error*/ + if ((SEC_OMX_COMPONENT_Library_Register = SEC_OSAL_dlsym(soHandle, "SEC_OMX_COMPONENT_Library_Register")) != NULL) { + int i = 0; + unsigned int j = 0; + + componentNum = (*SEC_OMX_COMPONENT_Library_Register)(NULL); + secComponentsTemp = (SECRegisterComponentType **)SEC_OSAL_Malloc(sizeof(SECRegisterComponentType*) * componentNum); + for (i = 0; i < componentNum; i++) { + secComponentsTemp[i] = SEC_OSAL_Malloc(sizeof(SECRegisterComponentType)); + SEC_OSAL_Memset(secComponentsTemp[i], 0, sizeof(SECRegisterComponentType)); + } + (*SEC_OMX_COMPONENT_Library_Register)(secComponentsTemp); + + for (i = 0; i < componentNum; i++) { + SEC_OSAL_Strcpy(componentList[totalCompNum].component.componentName, secComponentsTemp[i]->componentName); + for (j = 0; j < secComponentsTemp[i]->totalRoleNum; j++) + SEC_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], secComponentsTemp[i]->roles[j]); + componentList[totalCompNum].component.totalRoleNum = secComponentsTemp[i]->totalRoleNum; + + SEC_OSAL_Strcpy(componentList[totalCompNum].libName, libName); + + totalCompNum++; + } + for (i = 0; i < componentNum; i++) { + SEC_OSAL_Free(secComponentsTemp[i]); + } + + SEC_OSAL_Free(secComponentsTemp); + } else { + if ((errorMsg = SEC_OSAL_dlerror()) != NULL) + SEC_OSAL_Log(SEC_LOG_WARNING, "dlsym failed: %s", errorMsg); + } + SEC_OSAL_dlclose(soHandle); + } else { + SEC_OSAL_Log(SEC_LOG_WARNING, "dlopen failed: %s", SEC_OSAL_dlerror()); + } + } else { + /* not a component name line. skip */ + continue; + } + } + + SEC_OSAL_Free(libName); + + closedir(dir); + + *compList = componentList; + *compNum = totalCompNum; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + SEC_OSAL_Free(componentList); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentAPICheck(OMX_COMPONENTTYPE *component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if ((NULL == component->GetComponentVersion) || + (NULL == component->SendCommand) || + (NULL == component->GetParameter) || + (NULL == component->SetParameter) || + (NULL == component->GetConfig) || + (NULL == component->SetConfig) || + (NULL == component->GetExtensionIndex) || + (NULL == component->GetState) || + (NULL == component->ComponentTunnelRequest) || + (NULL == component->UseBuffer) || + (NULL == component->AllocateBuffer) || + (NULL == component->FreeBuffer) || + (NULL == component->EmptyThisBuffer) || + (NULL == component->FillThisBuffer) || + (NULL == component->SetCallbacks) || + (NULL == component->ComponentDeInit) || + (NULL == component->UseEGLImage) || + (NULL == component->ComponentRoleEnum)) + ret = OMX_ErrorInvalidComponent; + else + ret = OMX_ErrorNone; + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_HANDLETYPE libHandle; + OMX_COMPONENTTYPE *pOMXComponent; + + FunctionIn(); + + OMX_ERRORTYPE (*SEC_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + + libHandle = SEC_OSAL_dlopen((OMX_STRING)sec_component->libName, RTLD_NOW); + if (!libHandle) { + ret = OMX_ErrorInvalidComponentName; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OMX_ComponentInit = SEC_OSAL_dlsym(libHandle, "SEC_OMX_ComponentInit"); + if (!SEC_OMX_ComponentInit) { + SEC_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)SEC_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); + INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); + ret = (*SEC_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, (OMX_STRING)sec_component->componentName); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pOMXComponent); + SEC_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } else { + if (SEC_OMX_ComponentAPICheck(pOMXComponent) != OMX_ErrorNone) { + if (NULL != pOMXComponent->ComponentDeInit) + pOMXComponent->ComponentDeInit(pOMXComponent); + SEC_OSAL_Free(pOMXComponent); + SEC_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + sec_component->libHandle = libHandle; + sec_component->pOMXComponent = pOMXComponent; + ret = OMX_ErrorNone; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + + FunctionIn(); + + if (!sec_component) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = sec_component->pOMXComponent; + if (pOMXComponent != NULL) { + pOMXComponent->ComponentDeInit(pOMXComponent); + SEC_OSAL_Free(pOMXComponent); + sec_component->pOMXComponent = NULL; + } + + if (sec_component->libHandle != NULL) { + SEC_OSAL_dlclose(sec_component->libHandle); + sec_component->libHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + diff --git a/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.h b/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.h new file mode 100644 index 0000000..75b8ac5 --- /dev/null +++ b/exynos/multimedia/openmax/core/SEC_OMX_Component_Register.h @@ -0,0 +1,75 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Component_Register.h + * @brief SEC OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_COMPONENT_REG +#define SEC_OMX_COMPONENT_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_Component.h" + + +typedef struct _SECRegisterComponentType +{ + OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; + OMX_U8 roles[MAX_OMX_COMPONENT_ROLE_NUM][MAX_OMX_COMPONENT_ROLE_SIZE]; + OMX_U32 totalRoleNum; +} SECRegisterComponentType; + +typedef struct _SEC_OMX_COMPONENT_REGLIST +{ + SECRegisterComponentType component; + OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; +} SEC_OMX_COMPONENT_REGLIST; + +struct SEC_OMX_COMPONENT; +typedef struct _SEC_OMX_COMPONENT +{ + OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; + OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; + OMX_HANDLETYPE libHandle; + OMX_COMPONENTTYPE *pOMXComponent; + struct _SEC_OMX_COMPONENT *nextOMXComp; +} SEC_OMX_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum); +OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList); +OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component); +OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/core/SEC_OMX_Core.c b/exynos/multimedia/openmax/core/SEC_OMX_Core.c new file mode 100644 index 0000000..fa7477b --- /dev/null +++ b/exynos/multimedia/openmax/core/SEC_OMX_Core.c @@ -0,0 +1,364 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Core.c + * @brief SEC OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Core.h" +#include "SEC_OMX_Component_Register.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OMX_Resourcemanager.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_OMX_CORE" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +static int gInitialized = 0; +static OMX_U32 gComponentNum = 0; + +static SEC_OMX_COMPONENT_REGLIST *gComponentList = NULL; +static SEC_OMX_COMPONENT *gLoadComponentList = NULL; +static OMX_HANDLETYPE ghLoadComponentListMutex = NULL; + + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (gInitialized == 0) { + if (SEC_OMX_Component_Register(&gComponentList, &gComponentNum)) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : %s", "OMX_ErrorInsufficientResources"); + goto EXIT; + } + + ret = SEC_OMX_ResourceManager_Init(); + if (OMX_ErrorNone != ret) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : SEC_OMX_ResourceManager_Init failed"); + goto EXIT; + } + + ret = SEC_OSAL_MutexCreate(&ghLoadComponentListMutex); + if (OMX_ErrorNone != ret) { + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : SEC_OSAL_MutexCreate(&ghLoadComponentListMutex) failed"); + goto EXIT; + } + + gInitialized = 1; + SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_Init : %s", "OMX_ErrorNone"); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + SEC_OSAL_MutexTerminate(ghLoadComponentListMutex); + ghLoadComponentListMutex = NULL; + + SEC_OMX_ResourceManager_Deinit(); + + if (OMX_ErrorNone != SEC_OMX_Component_Unregister(gComponentList)) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + gComponentList = NULL; + gComponentNum = 0; + gInitialized = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (nIndex >= gComponentNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + snprintf(cComponentName, nNameLength, "%s", gComponentList[nIndex].component.componentName); + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE *pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE *pCallBacks) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_COMPONENT *loadComponent; + SEC_OMX_COMPONENT *currentComponent; + unsigned int i = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "ComponentName : %s", cComponentName); + + for (i = 0; i < gComponentNum; i++) { + if (SEC_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { + loadComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT)); + SEC_OSAL_Memset(loadComponent, 0, sizeof(SEC_OMX_COMPONENT)); + + SEC_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); + SEC_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); + ret = SEC_OMX_ComponentLoad(loadComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(loadComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData); + if (ret != OMX_ErrorNone) { + SEC_OMX_ComponentUnload(loadComponent); + SEC_OSAL_Free(loadComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OSAL_MutexLock(ghLoadComponentListMutex); + if (gLoadComponentList == NULL) { + gLoadComponentList = loadComponent; + } else { + currentComponent = gLoadComponentList; + while (currentComponent->nextOMXComp != NULL) { + currentComponent = currentComponent->nextOMXComp; + } + currentComponent->nextOMXComp = loadComponent; + } + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + + *pHandle = loadComponent->pOMXComponent; + ret = OMX_ErrorNone; + SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_GetHandle : %s", "OMX_ErrorNone"); + goto EXIT; + } + } + + ret = OMX_ErrorComponentNotFound; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_COMPONENT *currentComponent; + SEC_OMX_COMPONENT *deleteComponent; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + if (!hComponent) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_MutexLock(ghLoadComponentListMutex); + currentComponent = gLoadComponentList; + if (gLoadComponentList->pOMXComponent == hComponent) { + deleteComponent = gLoadComponentList; + gLoadComponentList = gLoadComponentList->nextOMXComp; + } else { + while ((currentComponent != NULL) && (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) + currentComponent = currentComponent->nextOMXComp; + + if (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) { + deleteComponent = currentComponent->nextOMXComp; + currentComponent->nextOMXComp = deleteComponent->nextOMXComp; + } else if (currentComponent == NULL) { + ret = OMX_ErrorComponentNotFound; + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + goto EXIT; + } + } + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + + SEC_OMX_ComponentUnload(deleteComponent); + SEC_OSAL_Free(deleteComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput) +{ + OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; + +EXIT: + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI) +{ + OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; + +EXIT: + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + int max_role_num = 0; + OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE]; + int i = 0, j = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + *pNumComps = 0; + + for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { + max_role_num = gComponentList[i].component.totalRoleNum; + + for (j = 0; j < max_role_num; j++) { + if (SEC_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { + if (compNames != NULL) { + SEC_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); + } + *pNumComps = (*pNumComps + 1); + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_BOOL detectComp = OMX_FALSE; + int compNum = 0, totalRoleNum = 0; + int i = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { + if (gComponentList != NULL) { + if (SEC_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) { + *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum; + compNum = i; + detectComp = OMX_TRUE; + break; + } + } else { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } + + if (detectComp == OMX_FALSE) { + *pNumRoles = 0; + ret = OMX_ErrorComponentNotFound; + goto EXIT; + } + + if (roles != NULL) { + for (i = 0; i < totalRoleNum; i++) { + SEC_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); + } + } + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/core/SEC_OMX_Core.h b/exynos/multimedia/openmax/core/SEC_OMX_Core.h new file mode 100644 index 0000000..c60cd52 --- /dev/null +++ b/exynos/multimedia/openmax/core/SEC_OMX_Core.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Core.h + * @brief SEC OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_CORE +#define SEC_OMX_CORE + +#include "SEC_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE *pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE *pCallBacks); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Audio.h b/exynos/multimedia/openmax/include/khronos/OMX_Audio.h new file mode 100644 index 0000000..04f1a99 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Audio.h @@ -0,0 +1,1311 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** @file OMX_Audio.h - OpenMax IL version 1.1.2 + * The structures needed by Audio components to exchange + * parameters and configuration data with the componenmilts. + */ + +#ifndef OMX_Audio_h +#define OMX_Audio_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup midi MIDI + * @ingroup audio + */ + +/** @defgroup effects Audio effects + * @ingroup audio + */ + +/** @defgroup audio OpenMAX IL Audio Domain + * Structures for OpenMAX IL Audio domain + * @{ + */ + +/** Enumeration used to define the possible audio codings. + * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must + * be done in a vendor specific way. Since this is for an audio + * processing element this enum is relevant. However, for another + * type of component other enums would be in this area. + */ +typedef enum OMX_AUDIO_CODINGTYPE { + OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ + OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ + OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ + OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ + OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ + OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ + OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ + OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ + OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ + OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ + OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ + OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ + OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ + OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ + OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ + OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ + OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ + OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ + OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ + OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ + OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ + OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ + OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ + OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ + OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ + OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ + OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ + OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ + OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CodingMax = 0x7FFFFFFF +} OMX_AUDIO_CODINGTYPE; + + +/** The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output audio + * path. If additional information is needed to define the parameters of the + * port (such as frequency), additional structures must be sent such as the + * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. + */ +typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; /**< MIME type of data for the port */ + OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference + for an output device, + otherwise this field is 0 */ + OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is + supported by the OMX component */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this + port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PORTDEFINITIONTYPE; + + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PARAM_PORTFORMATTYPE; + + +/** PCM mode type */ +typedef enum OMX_AUDIO_PCMMODETYPE { + OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ + OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_PCMModeMax = 0x7FFFFFFF +} OMX_AUDIO_PCMMODETYPE; + + +typedef enum OMX_AUDIO_CHANNELTYPE { + OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ + OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ + OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ + OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ + OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ + OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ + OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ + OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ + OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ + OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ + OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELTYPE; + +#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ +#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ + +/** PCM format description */ +typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ + OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ + OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ + OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for + non-interleaved data (e.g. block data) */ + OMX_U32 nBitPerSample; /**< Bit per sample */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ + OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ + +} OMX_AUDIO_PARAM_PCMMODETYPE; + + +/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate + * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. + */ +typedef enum OMX_AUDIO_CHANNELMODETYPE { + OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those + two channels changes accordingly to each channel information */ + OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between + 2 channels for higher compression gain */ + OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half + the bitrate of the overall bitrate */ + OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ + OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELMODETYPE; + + +typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { + OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MP3STREAMFORMATTYPE; + +/** MP3 params */ +typedef struct OMX_AUDIO_PARAM_MP3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ +} OMX_AUDIO_PARAM_MP3TYPE; + + +typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { + OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ + OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ + OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ + OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ + OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ + OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ + OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ + OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AACSTREAMFORMATTYPE; + + +/** AAC mode type. Note that the term profile is used with the MPEG-2 + * standard and the term object type and profile is used with MPEG-4 */ +typedef enum OMX_AUDIO_AACPROFILETYPE{ + OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ + OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ + OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ + OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ + OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ + OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ + OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ + OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ + OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ + OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ + OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACObjectMax = 0x7FFFFFFF +} OMX_AUDIO_AACPROFILETYPE; + + +/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for encoder configuration and optional as decoder info output. + * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ +#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ +#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ +#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ +#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ +#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ +#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ +#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ + +/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for ER encoder configuration and optional as decoder info output */ +#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ +#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ +#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ +#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ +#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ + + +/** AAC params */ +typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. + Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). + Use 0 to let encoder decide */ + OMX_U32 nAACtools; /**< AAC tool usage */ + OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ + OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ + OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ +} OMX_AUDIO_PARAM_AACPROFILETYPE; + + +/** VORBIS params */ +typedef struct OMX_AUDIO_PARAM_VORBISTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ + OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ + + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). + In the default mode of operation, teh quality level is 3. + Normal quality range is 0 - 10. */ + OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the + normal VBR encoding, but allows hard or soft bitrate + constraints to be enforced by the encoder. This mode can + be slower, and may also be lower quality. It is + primarily useful for streaming. */ + OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on + non-stereo streams). Useful for lower-bitrate encoding. */ +} OMX_AUDIO_PARAM_VORBISTYPE; + + +/** WMA Version */ +typedef enum OMX_AUDIO_WMAFORMATTYPE { + OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ + OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ + OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ + OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ + OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_WMAFORMATTYPE; + + +/** WMA Profile */ +typedef enum OMX_AUDIO_WMAPROFILETYPE { + OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ + OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ + OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ + OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ + OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF +} OMX_AUDIO_WMAPROFILETYPE; + + +/** WMA params */ +typedef struct OMX_AUDIO_PARAM_WMATYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ + OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ + OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ + OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ + OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ +} OMX_AUDIO_PARAM_WMATYPE; + +/** + * RealAudio format + */ +typedef enum OMX_AUDIO_RAFORMATTYPE { + OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ + OMX_AUDIO_RA8, /**< RealAudio 8 codec */ + OMX_AUDIO_RA9, /**< RealAudio 9 codec */ + OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ + OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ + OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ + OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ + OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ + OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_RAFORMATTYPE; + +/** RA (Real Audio) params */ +typedef struct OMX_AUDIO_PARAM_RATYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ + OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ + OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ + OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ + OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ + OMX_U32 nNumRegions; /**< is the number of regions value */ + OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ +} OMX_AUDIO_PARAM_RATYPE; + + +/** SBC Allocation Method Type */ +typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { + OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ + OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ + OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF +} OMX_AUDIO_SBCALLOCMETHODTYPE; + + +/** SBC params */ +typedef struct OMX_AUDIO_PARAM_SBCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBlocks; /**< Number of blocks */ + OMX_U32 nSubbands; /**< Number of subbands */ + OMX_U32 nBitPool; /**< Bitpool value */ + OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ +} OMX_AUDIO_PARAM_SBCTYPE; + + +/** ADPCM stream format parameters */ +typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ADPCMTYPE; + + +/** G723 rate */ +typedef enum OMX_AUDIO_G723RATE { + OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_G723ModeLow, /**< 5300 bps */ + OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ + OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G723ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G723RATE; + + +/** G723 - Sample rate must be 8 KHz */ +typedef struct OMX_AUDIO_PARAM_G723TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ + OMX_BOOL bPostFilter; /**< Enable Post Filter */ +} OMX_AUDIO_PARAM_G723TYPE; + + +/** ITU G726 (ADPCM) rate */ +typedef enum OMX_AUDIO_G726MODE { + OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ + OMX_AUDIO_G726Mode16, /**< 16 kbps */ + OMX_AUDIO_G726Mode24, /**< 24 kbps */ + OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ + OMX_AUDIO_G726Mode40, /**< 40 kbps */ + OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G726ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G726MODE; + + +/** G.726 stream format parameters - must be at 8KHz */ +typedef struct OMX_AUDIO_PARAM_G726TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_G726MODE eG726Mode; +} OMX_AUDIO_PARAM_G726TYPE; + + +/** G729 coder type */ +typedef enum OMX_AUDIO_G729TYPE { + OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ + OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ + OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ + OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ + OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G729Max = 0x7FFFFFFF +} OMX_AUDIO_G729TYPE; + + +/** G729 stream format parameters - fixed 6KHz sample rate */ +typedef struct OMX_AUDIO_PARAM_G729TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G729TYPE eBitType; +} OMX_AUDIO_PARAM_G729TYPE; + + +/** AMR Frame format */ +typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { + OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance + (Standard) Format */ + OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface + Format 1 */ + OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface + Format 2*/ + OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage + Format */ + OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time + Transport Protocol Payload Format */ + OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ + OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AMRFRAMEFORMATTYPE; + + +/** AMR band mode */ +typedef enum OMX_AUDIO_AMRBANDMODETYPE { + OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ + OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ + OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ + OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ + OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ + OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ + OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ + OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ + OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ + OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ + OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ + OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ + OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ + OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ + OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ + OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ + OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ + OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRBANDMODETYPE; + + +/** AMR Discontinuous Transmission mode */ +typedef enum OMX_AUDIO_AMRDTXMODETYPE { + OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ + OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 1 (VAD1) is enabled */ + OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 2 (VAD2) is enabled */ + OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between + Off, VAD1 or VAD2 modes */ + + OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ + + OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRDTXMODETYPE; + + +/** AMR params */ +typedef struct OMX_AUDIO_PARAM_AMRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate read only field */ + OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ + OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ + OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ +} OMX_AUDIO_PARAM_AMRTYPE; + + +/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMFRTYPE; + + +/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMHRTYPE; + + +/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMEFRTYPE; + + +/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAFRTYPE; + + +/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAEFRTYPE; + + +/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCFRTYPE; + + +/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCEFRTYPE; + +/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCHRTYPE; + + +/** CDMA Rate types */ +typedef enum OMX_AUDIO_CDMARATETYPE { + OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ + OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ + OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ + OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ + OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ + OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ + OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CDMARateMax = 0x7FFFFFFF +} OMX_AUDIO_CDMARATETYPE; + + +/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP8TYPE; + + +/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP13TYPE; + + +/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_EVRCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ +} OMX_AUDIO_PARAM_EVRCTYPE; + + +/** SMV ( up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_SMVTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ +} OMX_AUDIO_PARAM_SMVTYPE; + + +/** MIDI Format + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIFORMATTYPE +{ + OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ + OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ + OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ + OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ + OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ + OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ + OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ + OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ + OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIFORMATTYPE; + + +/** MIDI params + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDITYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire + MIDI file passed in, otherwise if 0x0, the MIDI data + is merged and streamed (instead of passed as an + entire MIDI file) */ + OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound + bank at initialization */ + OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ +} OMX_AUDIO_PARAM_MIDITYPE; + + +/** Type of the MIDI sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { + OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ + OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ + OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ + OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ + OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKTYPE; + + +/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { + OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ + OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; + + +/** MIDI params to load/unload user soundbank + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ + OMX_U32 nDLSSize; /**< Size in bytes */ + OMX_PTR pDLSData; /**< Pointer to DLS file data */ + OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ + OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ +} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; + + +/** Structure for Live MIDI events and MIP messages. + * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ + OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an + array for the MIP message buffer, where the size is + indicated by nMidiEventSize */ +} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; + + +/** MIDI sound bank/ program pair in a given channel + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ + OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ + OMX_U16 nIDSoundBank; /**< Sound bank ID */ + OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks + by index if multiple banks are present */ +} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; + + +/** MIDI control + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 + format based on JAVA MMAPI (JSR-135) requirement */ + OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point + number based on JSR-135 requirement */ + OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 + fixed-point number based on JSR-135 requirement */ + OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ + OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback + will stop automatically. Set to zero if not used */ + OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ + OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ + OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ + OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ + +} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; + + +/** MIDI Playback States + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { + OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to + other defined states */ + OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. + The MIDI engine is currently processing + MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being + primed. The MIDI engine is currently + processing MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but + not playing. The MIDI engine is currently + processing MIDI events. The transition to + this state is only possible from the + OMX_AUDIO_MIDIPlayBackStatePlaying state, + when the 'playback head' reaches the end + of media data or the playback stops due + to stop time set.*/ + OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently + playing. The MIDI engine is currently + processing MIDI events.*/ + OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS + resource constraints */ + OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and + SP-MIDI content constraints, there is + no audible MIDI content during playback + currently. The situation may change if + resources are freed later.*/ + OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; + + +/** MIDI status + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. + NOTE: May not return a meaningful value until the entire + file is parsed and buffered. */ + OMX_U32 nDuration; /**< The length of the currently open MIDI resource + in milliseconds. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nPosition; /**< Current Position of the MIDI resource being played + in milliseconds */ + OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful + value until the entire file is parsed and buffered. */ + OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently + open MIDI resource. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing + MIDI resource. NOTE: May not return a meaningful value until + the entire file is parsed and buffered. */ + OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ +} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; + + +/** MIDI Meta Event structure one per Meta Event. + * MIDI Meta Events are like audio metadata, except that they are interspersed + * with the MIDI content throughout the file and are not localized in the header. + * As such, it is necessary to retrieve information about these Meta Events from + * the engine, as it encounters these Meta Events within the MIDI content. + * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, + * author, default tempo, etc.) scattered throughout the file. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U32 nTrack; /**< track number for the meta event */ + OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ +} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; + + +/** MIDI Meta Event Data structure - one per Meta Event. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U8 nData[1]; /**< array of one or more bytes of meta data + as indicated by the nMetaEventSize field */ +} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; + + +/** Audio Volume adjustment for a port */ +typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) + or logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. The values + for volume are in mB (millibels = 1/100 dB) relative + to a gain of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ +} OMX_AUDIO_CONFIG_VOLUMETYPE; + + +/** Audio Volume adjustment for a channel */ +typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply volume settings + to all channels */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or + logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. + The values for volume are in mB + (millibels = 1/100 dB) relative to a gain + of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; + + +/** Audio balance setting */ +typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's balance. Select the + output port to adjust the master + balance. */ + OMX_S32 nBalance; /**< balance setting for this port + (-100 to 100, where -100 indicates + all left, and no right */ +} OMX_AUDIO_CONFIG_BALANCETYPE; + + +/** Audio Port mute */ +typedef struct OMX_AUDIO_CONFIG_MUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's mute. Select the + output port to adjust the master + mute. */ + OMX_BOOL bMute; /**< Mute setting for this port */ +} OMX_AUDIO_CONFIG_MUTETYPE; + + +/** Audio Channel mute */ +typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply mute settings + to all channels */ + OMX_BOOL bMute; /**< Mute setting for this channel */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; + + + +/** Enable / Disable for loudness control, which boosts bass and to a + * smaller extent high end frequencies to compensate for hearing + * ability at the extreme ends of the audio spectrum + */ +typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bLoudness; /**< Enable/disable for loudness */ +} OMX_AUDIO_CONFIG_LOUDNESSTYPE; + + +/** Enable / Disable for bass, which controls low frequencies + */ +typedef struct OMX_AUDIO_CONFIG_BASSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for bass control */ + OMX_S32 nBass; /**< bass setting for the port, as a + continuous value from -100 to 100 + (0 means no change in bass level)*/ +} OMX_AUDIO_CONFIG_BASSTYPE; + + +/** Enable / Disable for treble, which controls high frequencies tones + */ +typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for treble control */ + OMX_S32 nTreble; /**< treble setting for the port, as a + continuous value from -100 to 100 + (0 means no change in treble level) */ +} OMX_AUDIO_CONFIG_TREBLETYPE; + + +/** An equalizer is typically used for two reasons: to compensate for an + * sub-optimal frequency response of a system to make it sound more natural + * or to create intentionally some unnatural coloring to the sound to create + * an effect. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for equalizer */ + OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is + N-1, where N is the number of bands, lower limit is 0 */ + OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a + read only element and is used to determine + the lower, center and upper frequency of + this band. */ + OMX_BS32 sBandLevel; /**< band level in millibels */ +} OMX_AUDIO_CONFIG_EQUALIZERTYPE; + + +/** Stereo widening mode type + * @ingroup effects + */ +typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { + OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ + OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ + OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF +} OMX_AUDIO_STEREOWIDENINGTYPE; + + +/** Control for stereo widening, which is a special 2-channel + * case of the audio virtualizer effect. For example, for 5.1-channel + * output, it translates to virtual surround sound. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ + OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ + OMX_U32 nStereoWidening; /**< stereo widening setting for the port, + as a continuous value from 0 to 100 */ +} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; + + +/** The chorus effect (or ``choralizer'') is any signal processor which makes + * one sound source (such as a voice) sound like many such sources singing + * (or playing) in unison. Since performance in unison is never exact, chorus + * effects simulate this by making independently modified copies of the input + * signal. Modifications may include (1) delay, (2) frequency shift, and + * (3) amplitude modulation. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for chorus */ + OMX_BU32 sDelay; /**< average delay in milliseconds */ + OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ + OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of + delay (i.e. 0 to 100) */ + OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ +} OMX_AUDIO_CONFIG_CHORUSTYPE; + + +/** Reverberation is part of the reflected sound that follows the early + * reflections. In a typical room, this consists of a dense succession of + * echoes whose energy decays exponentially. The reverberation effect structure + * as defined here includes both (early) reflections as well as (late) reverberations. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ + OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect + (i.e. both early reflections and late + reverberation) in millibels */ + OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies + relative to the intensity at low + frequencies in millibels */ + OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections + (relative to room value), in millibels */ + OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative + to the direct path, in milliseconds */ + OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation + relative to room level, in millibels */ + OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection + to the beginning of the late reverberation + section, in milliseconds */ + OMX_BU32 sDecayTime; /**< Late reverberation decay time at low + frequencies, in milliseconds */ + OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative + to low frequency decay time in percent */ + OMX_U32 nDensity; /**< Modal density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is + the frequency used as the reference for all + the high-frequency settings above */ + +} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; + + +/** Possible settings for the Echo Cancelation structure to use + * @ingroup effects + */ +typedef enum OMX_AUDIO_ECHOCANTYPE { + OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ + OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - + echo from plastics and face */ + OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for + Hands Free operation */ + OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for + Car Kit (longer echo) */ + OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_EchoCanMax = 0x7FFFFFFF +} OMX_AUDIO_ECHOCANTYPE; + + +/** Enable / Disable for echo cancelation, which removes undesired echo's + * from the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ +} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; + + +/** Enable / Disable for noise reduction, which undesired noise from + * the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ +} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Component.h b/exynos/multimedia/openmax/include/khronos/OMX_Component.h new file mode 100644 index 0000000..d595640 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Component.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** OMX_Component.h - OpenMax IL version 1.1.2 + * The OMX_Component header file contains the definitions used to define + * the public interface of a component. This header file is intended to + * be used by both the application and the component. + */ + +#ifndef OMX_Component_h +#define OMX_Component_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include +#include +#include +#include + +/** @ingroup comp */ +typedef enum OMX_PORTDOMAINTYPE { + OMX_PortDomainAudio, + OMX_PortDomainVideo, + OMX_PortDomainImage, + OMX_PortDomainOther, + OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_PortDomainMax = 0x7ffffff +} OMX_PORTDOMAINTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_PORTDEFINITIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ + OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ + OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ + OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ + OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by + OMX_CommandPortEnable/OMX_CommandPortDisable. + When disabled a port is unpopulated. A disabled port + is not populated with buffers on a transition to IDLE. */ + OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by + nBufferCountActual. A disabled port is always unpopulated. + An enabled port is populated on a transition to OMX_StateIdle + and unpopulated on a transition to loaded. */ + OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ + union { + OMX_AUDIO_PORTDEFINITIONTYPE audio; + OMX_VIDEO_PORTDEFINITIONTYPE video; + OMX_IMAGE_PORTDEFINITIONTYPE image; + OMX_OTHER_PORTDEFINITIONTYPE other; + } format; + OMX_BOOL bBuffersContiguous; + OMX_U32 nBufferAlignment; +} OMX_PARAM_PORTDEFINITIONTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_U32TYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nU32; /**< U32 value */ +} OMX_PARAM_U32TYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONPOLICYTYPE { + OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ + OMX_SuspensionEnabled, /**< Suspension allowed */ + OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspensionPolicyMax = 0x7fffffff +} OMX_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONPOLICYTYPE ePolicy; +} OMX_PARAM_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONTYPE { + OMX_NotSuspended, /**< component is not suspended */ + OMX_Suspended, /**< component is suspended */ + OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspendMax = 0x7FFFFFFF +} OMX_SUSPENSIONTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONTYPE eType; +} OMX_PARAM_SUSPENSIONTYPE ; + +typedef struct OMX_CONFIG_BOOLEANTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnabled; +} OMX_CONFIG_BOOLEANTYPE; + +/* Parameter specifying the content uri to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTURITYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes, including + actual URI name */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 contentURI[1]; /**< The URI name */ +} OMX_PARAM_CONTENTURITYPE; + +/* Parameter specifying the pipe to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTPIPETYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_HANDLETYPE hPipe; /**< The pipe handle*/ +} OMX_PARAM_CONTENTPIPETYPE; + +/** @ingroup rpm */ +typedef struct OMX_RESOURCECONCEALMENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment + methods (like degrading algorithm quality to + lower resource consumption or functional bypass) + on a component as a resolution to resource conflicts. */ +} OMX_RESOURCECONCEALMENTTYPE; + + +/** @ingroup metadata */ +typedef enum OMX_METADATACHARSETTYPE { + OMX_MetadataCharsetUnknown = 0, + OMX_MetadataCharsetASCII, + OMX_MetadataCharsetBinary, + OMX_MetadataCharsetCodePage1252, + OMX_MetadataCharsetUTF8, + OMX_MetadataCharsetJavaConformantUTF8, + OMX_MetadataCharsetUTF7, + OMX_MetadataCharsetImapUTF7, + OMX_MetadataCharsetUTF16LE, + OMX_MetadataCharsetUTF16BE, + OMX_MetadataCharsetGB12345, + OMX_MetadataCharsetHZGB2312, + OMX_MetadataCharsetGB2312, + OMX_MetadataCharsetGB18030, + OMX_MetadataCharsetGBK, + OMX_MetadataCharsetBig5, + OMX_MetadataCharsetISO88591, + OMX_MetadataCharsetISO88592, + OMX_MetadataCharsetISO88593, + OMX_MetadataCharsetISO88594, + OMX_MetadataCharsetISO88595, + OMX_MetadataCharsetISO88596, + OMX_MetadataCharsetISO88597, + OMX_MetadataCharsetISO88598, + OMX_MetadataCharsetISO88599, + OMX_MetadataCharsetISO885910, + OMX_MetadataCharsetISO885913, + OMX_MetadataCharsetISO885914, + OMX_MetadataCharsetISO885915, + OMX_MetadataCharsetShiftJIS, + OMX_MetadataCharsetISO2022JP, + OMX_MetadataCharsetISO2022JP1, + OMX_MetadataCharsetISOEUCJP, + OMX_MetadataCharsetSMS7Bit, + OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataCharsetTypeMax= 0x7FFFFFFF +} OMX_METADATACHARSETTYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASCOPETYPE +{ + OMX_MetadataScopeAllLevels, + OMX_MetadataScopeTopLevel, + OMX_MetadataScopePortLevel, + OMX_MetadataScopeNodeLevel, + OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataScopeTypeMax = 0x7fffffff +} OMX_METADATASCOPETYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASEARCHMODETYPE +{ + OMX_MetadataSearchValueSizeByIndex, + OMX_MetadataSearchItemByIndex, + OMX_MetadataSearchNextItemByKey, + OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataSearchTypeMax = 0x7fffffff +} OMX_METADATASEARCHMODETYPE; +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemCount; +} OMX_CONFIG_METADATAITEMCOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemIndex; + OMX_METADATASEARCHMODETYPE eSearchMode; + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U8 nKeySizeUsed; + OMX_U8 nKey[128]; + OMX_METADATACHARSETTYPE eValueCharset; + OMX_STRING sLanguageCountry; + OMX_U32 nValueMaxSize; + OMX_U32 nValueSizeUsed; + OMX_U8 nValue[1]; +} OMX_CONFIG_METADATAITEMTYPE; + +/* @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNumNodes; +} OMX_CONFIG_CONTAINERNODECOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNodeIndex; + OMX_U32 nNodeID; + OMX_STRING cNodeName; + OMX_BOOL bIsLeafType; +} OMX_CONFIG_CONTAINERNODEIDTYPE; + +/** @ingroup metadata */ +typedef struct OMX_PARAM_METADATAFILTERTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and + * the three key fields below are ignored */ + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U32 nKeySizeUsed; + OMX_U8 nKey [128]; + OMX_U32 nLanguageCountrySizeUsed; + OMX_U8 nLanguageCountry[128]; + OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. + * retained for query later). If false then + * key is not part of filter */ +} OMX_PARAM_METADATAFILTERTYPE; + +/** The OMX_HANDLETYPE structure defines the component handle. The component + * handle is used to access all of the component's public methods and also + * contains pointers to the component's private data area. The component + * handle is initialized by the OMX core (with help from the component) + * during the process of loading the component. After the component is + * successfully loaded, the application can safely access any of the + * component's public functions (although some may return an error because + * the state is inappropriate for the access). + * + * @ingroup comp + */ +typedef struct OMX_COMPONENTTYPE +{ + /** The size of this structure, in bytes. It is the responsibility + of the allocator of this structure to fill in this value. Since + this structure is allocated by the GetHandle function, this + function will fill in this value. */ + OMX_U32 nSize; + + /** nVersion is the version of the OMX specification that the structure + is built against. It is the responsibility of the creator of this + structure to initialize this value and every user of this structure + should verify that it knows how to use the exact version of + this structure found herein. */ + OMX_VERSIONTYPE nVersion; + + /** pComponentPrivate is a pointer to the component private data area. + This member is allocated and initialized by the component when the + component is first loaded. The application should not access this + data area. */ + OMX_PTR pComponentPrivate; + + /** pApplicationPrivate is a pointer that is a parameter to the + OMX_GetHandle method, and contains an application private value + provided by the IL client. This application private data is + returned to the IL Client by OMX in all callbacks */ + OMX_PTR pApplicationPrivate; + + /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL + specification for details on the GetComponentVersion method. + */ + OMX_ERRORTYPE (*GetComponentVersion)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE* pComponentVersion, + OMX_OUT OMX_VERSIONTYPE* pSpecVersion, + OMX_OUT OMX_UUIDTYPE* pComponentUUID); + + /** refer to OMX_SendCommand in OMX_core.h or the OMX IL + specification for details on the SendCommand method. + */ + OMX_ERRORTYPE (*SendCommand)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam1, + OMX_IN OMX_PTR pCmdData); + + /** refer to OMX_GetParameter in OMX_core.h or the OMX IL + specification for details on the GetParameter method. + */ + OMX_ERRORTYPE (*GetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_SetParameter in OMX_core.h or the OMX IL + specification for details on the SetParameter method. + */ + OMX_ERRORTYPE (*SetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_GetConfig in OMX_core.h or the OMX IL + specification for details on the GetConfig method. + */ + OMX_ERRORTYPE (*GetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_SetConfig in OMX_core.h or the OMX IL + specification for details on the SetConfig method. + */ + OMX_ERRORTYPE (*SetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL + specification for details on the GetExtensionIndex method. + */ + OMX_ERRORTYPE (*GetExtensionIndex)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE* pIndexType); + + + /** refer to OMX_GetState in OMX_core.h or the OMX IL + specification for details on the GetState method. + */ + OMX_ERRORTYPE (*GetState)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE* pState); + + + /** The ComponentTunnelRequest method will interact with another OMX + component to determine if tunneling is possible and to setup the + tunneling. The return codes for this method can be used to + determine if tunneling is not possible, or if tunneling is not + supported. + + Base profile components (i.e. non-interop) do not support this + method and should return OMX_ErrorNotImplemented + + The interop profile component MUST support tunneling to another + interop profile component with a compatible port parameters. + A component may also support proprietary communication. + + If proprietary communication is supported the negotiation of + proprietary communication is done outside of OMX in a vendor + specific way. It is only required that the proper result be + returned and the details of how the setup is done is left + to the component implementation. + + When this method is invoked when nPort in an output port, the + component will: + 1. Populate the pTunnelSetup structure with the output port's + requirements and constraints for the tunnel. + + When this method is invoked when nPort in an input port, the + component will: + 1. Query the necessary parameters from the output port to + determine if the ports are compatible for tunneling + 2. If the ports are compatible, the component should store + the tunnel step provided by the output port + 3. Determine which port (either input or output) is the buffer + supplier, and call OMX_SetParameter on the output port to + indicate this selection. + + The component will return from this call within 5 msec. + + @param [in] hComp + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle method. + @param [in] nPort + nPort is used to select the port on the component to be used + for tunneling. + @param [in] hTunneledComp + Handle of the component to tunnel with. This is the component + handle returned by the call to the OMX_GetHandle method. When + this parameter is 0x0 the component should setup the port for + communication with the application / IL Client. + @param [in] nPortOutput + nPortOutput is used indicate the port the component should + tunnel with. + @param [in] pTunnelSetup + Pointer to the tunnel setup structure. When nPort is an output port + the component should populate the fields of this structure. When + When nPort is an input port the component should review the setup + provided by the component with the output port. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup tun + */ + + OMX_ERRORTYPE (*ComponentTunnelRequest)( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); + + /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL + specification for details on the UseBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*UseBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8* pBuffer); + + /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL + specification for details on the AllocateBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*AllocateBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); + + /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL + specification for details on the FreeBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FreeBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL + specification for details on the EmptyThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL + specification for details on the FillThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FillThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The SetCallbacks method is used by the core to specify the callback + structure from the application to the component. This is a blocking + call. The component will return from this call within 5 msec. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] pCallbacks + pointer to an OMX_CALLBACKTYPE structure used to provide the + callback information to the component + @param [in] pAppData + pointer to an application defined value. It is anticipated that + the application will pass a pointer to a data structure or a "this + pointer" in this area to allow the callback (in the application) + to determine the context of the call + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*SetCallbacks)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData); + + /** ComponentDeInit method is used to deinitialize the component + providing a means to free any resources allocated at component + initialization. NOTE: After this call the component handle is + not valid for further use. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*ComponentDeInit)( + OMX_IN OMX_HANDLETYPE hComponent); + + /** @ingroup buf */ + OMX_ERRORTYPE (*UseEGLImage)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void* eglImage); + + OMX_ERRORTYPE (*ComponentRoleEnum)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex); + +} OMX_COMPONENTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/exynos/multimedia/openmax/include/khronos/OMX_ContentPipe.h b/exynos/multimedia/openmax/include/khronos/OMX_ContentPipe.h new file mode 100644 index 0000000..5f6310c --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_ContentPipe.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 + * The OMX_ContentPipe header file contains the definitions used to define + * the public interface for content piples. This header file is intended to + * be used by the component. + */ + +#ifndef OMX_CONTENTPIPE_H +#define OMX_CONTENTPIPE_H + +#ifndef KD_EACCES +/* OpenKODE error codes. CPResult values may be zero (indicating success + or one of the following values) */ +#define KD_EACCES (1) +#define KD_EADDRINUSE (2) +#define KD_EAGAIN (5) +#define KD_EBADF (7) +#define KD_EBUSY (8) +#define KD_ECONNREFUSED (9) +#define KD_ECONNRESET (10) +#define KD_EDEADLK (11) +#define KD_EDESTADDRREQ (12) +#define KD_ERANGE (35) +#define KD_EEXIST (13) +#define KD_EFBIG (14) +#define KD_EHOSTUNREACH (15) +#define KD_EINVAL (17) +#define KD_EIO (18) +#define KD_EISCONN (20) +#define KD_EISDIR (21) +#define KD_EMFILE (22) +#define KD_ENAMETOOLONG (23) +#define KD_ENOENT (24) +#define KD_ENOMEM (25) +#define KD_ENOSPC (26) +#define KD_ENOSYS (27) +#define KD_ENOTCONN (28) +#define KD_EPERM (33) +#define KD_ETIMEDOUT (36) +#define KD_EILSEQ (19) +#endif + +/** Map types from OMX standard types only here so interface is as generic as possible. */ +typedef OMX_U32 CPresult; +typedef char * CPstring; +typedef void * CPhandle; +typedef OMX_U32 CPuint; +typedef OMX_S32 CPint; +typedef char CPbyte; +typedef OMX_BOOL CPbool; + +/** enumeration of origin types used in the CP_PIPETYPE's Seek function + * @ingroup cp + */ +typedef enum CP_ORIGINTYPE { + CP_OriginBegin, + CP_OriginCur, + CP_OriginEnd, + CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_OriginMax = 0X7FFFFFFF +} CP_ORIGINTYPE; + +/** enumeration of contact access types used in the CP_PIPETYPE's Open function + * @ingroup cp + */ +typedef enum CP_ACCESSTYPE { + CP_AccessRead, + CP_AccessWrite, + CP_AccessReadWrite , + CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_AccessMax = 0X7FFFFFFF +} CP_ACCESSTYPE; + +/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function + * @ingroup cp + */ +typedef enum CP_CHECKBYTESRESULTTYPE +{ + CP_CheckBytesOk, /**< There are at least the request number + of bytes available */ + CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes + and presently lacks sufficient bytes. + Client will be called when they are + sufficient bytes are available. */ + CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes + but those available are less than those + requested */ + CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream + and no more bytes are available. */ + CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ + CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_CheckBytesMax = 0X7FFFFFFF +} CP_CHECKBYTESRESULTTYPE; + +/** enumeration of content pipe events sent to the client callback. + * @ingroup cp + */ +typedef enum CP_EVENTTYPE{ + CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ + CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ + CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/ + CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_EventMax = 0X7FFFFFFF +} CP_EVENTTYPE; + +/** content pipe definition + * @ingroup cp + */ +typedef struct CP_PIPETYPE +{ + /** Open a content stream for reading or writing. */ + CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); + + /** Close a content stream. */ + CPresult (*Close)( CPhandle hContent ); + + /** Create a content source and open it for writing. */ + CPresult (*Create)( CPhandle *hContent, CPstring szURI ); + + /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ + CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); + + /** Seek to certain position in the content relative to the specified origin. */ + CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); + + /** Retrieve the current position relative to the start of the content. */ + CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); + + /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ + CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. + Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also + returns the size of the block actually read. Content pointer advances the by the returned size. + Note: pipe provides pointer. This function is appropriate for large reads. The client must call + ReleaseReadBuffer when done with buffer. + + In some cases the requested block may not reside in contiguous memory within the + pipe implementation. For instance if the pipe leverages a circular buffer then the requested + block may straddle the boundary of the circular buffer. By default a pipe implementation + performs a copy in this case to provide the block to the pipe client in one contiguous buffer. + If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory + boundary. Here the client may retrieve the data in segments over successive calls. */ + CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); + + /** Release a buffer obtained by ReadBuffer back to the pipe. */ + CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); + + /** Write data of the specified size to the content (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ + CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe used to write data to the content. + Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate + for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ + CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); + + /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the + the contents of the buffer to content and advance content pointer by the size of the buffer */ + CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); + + /** Register a per-handle client callback with the content pipe. */ + CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); + +} CP_PIPETYPE; + +#endif + diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Core.h b/exynos/multimedia/openmax/include/khronos/OMX_Core.h new file mode 100644 index 0000000..a076f2f --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Core.h @@ -0,0 +1,1431 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** OMX_Core.h - OpenMax IL version 1.1.2 + * The OMX_Core header file contains the definitions used by both the + * application and the component to access common items. + */ + +#ifndef OMX_Core_h +#define OMX_Core_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** The OMX_COMMANDTYPE enumeration is used to specify the action in the + * OMX_SendCommand macro. + * @ingroup core + */ +typedef enum OMX_COMMANDTYPE +{ + OMX_CommandStateSet, /**< Change the component state */ + OMX_CommandFlush, /**< Flush the data queue(s) of a component */ + OMX_CommandPortDisable, /**< Disable a port on a component. */ + OMX_CommandPortEnable, /**< Enable a port on a component. */ + OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ + OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_CommandMax = 0X7FFFFFFF +} OMX_COMMANDTYPE; + + + +/** The OMX_STATETYPE enumeration is used to indicate or change the component + * state. This enumeration reflects the current state of the component when + * used with the OMX_GetState macro or becomes the parameter in a state change + * command when used with the OMX_SendCommand macro. + * + * The component will be in the Loaded state after the component is initially + * loaded into memory. In the Loaded state, the component is not allowed to + * allocate or hold resources other than to build it's internal parameter + * and configuration tables. The application will send one or more + * SetParameters/GetParameters and SetConfig/GetConfig commands to the + * component and the component will record each of these parameter and + * configuration changes for use later. When the application sends the + * Idle command, the component will acquire the resources needed for the + * specified configuration and will transition to the idle state if the + * allocation is successful. If the component cannot successfully + * transition to the idle state for any reason, the state of the component + * shall be fully rolled back to the Loaded state (e.g. all allocated + * resources shall be released). When the component receives the command + * to go to the Executing state, it shall begin processing buffers by + * sending all input buffers it holds to the application. While + * the component is in the Idle state, the application may also send the + * Pause command. If the component receives the pause command while in the + * Idle state, the component shall send all input buffers it holds to the + * application, but shall not begin processing buffers. This will allow the + * application to prefill buffers. + * + * @ingroup comp + */ + +typedef enum OMX_STATETYPE +{ + OMX_StateInvalid, /**< component has detected that it's internal data + structures are corrupted to the point that + it cannot determine it's state properly */ + OMX_StateLoaded, /**< component has been loaded but has not completed + initialization. The OMX_SetParameter macro + and the OMX_GetParameter macro are the only + valid macros allowed to be sent to the + component in this state. */ + OMX_StateIdle, /**< component initialization has been completed + successfully and the component is ready to + to start. */ + OMX_StateExecuting, /**< component has accepted the start command and + is processing data (if data is available) */ + OMX_StatePause, /**< component has received pause command */ + OMX_StateWaitForResources, /**< component is waiting for resources, either after + preemption or before it gets the resources requested. + See specification for complete details. */ + OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_StateMax = 0X7FFFFFFF +} OMX_STATETYPE; + +/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These + * errors should cover most of the common failure cases. However, + * vendors are free to add additional error messages of their own as + * long as they follow these rules: + * 1. Vendor error messages shall be in the range of 0x90000000 to + * 0x9000FFFF. + * 2. Vendor error messages shall be defined in a header file provided + * with the component. No error messages are allowed that are + * not defined. + */ +typedef enum OMX_ERRORTYPE +{ + OMX_ErrorNone = 0, + + /** There were insufficient resources to perform the requested operation */ + OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, + + /** There was an error, but the cause of the error could not be determined */ + OMX_ErrorUndefined = (OMX_S32) 0x80001001, + + /** The component name string was not valid */ + OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, + + /** No component with the specified name string was found */ + OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, + + /** The component specified did not have a "OMX_ComponentInit" or + "OMX_ComponentDeInit entry point */ + OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, + + /** One or more parameters were not valid */ + OMX_ErrorBadParameter = (OMX_S32) 0x80001005, + + /** The requested function is not implemented */ + OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, + + /** The buffer was emptied before the next buffer was ready */ + OMX_ErrorUnderflow = (OMX_S32) 0x80001007, + + /** The buffer was not available when it was needed */ + OMX_ErrorOverflow = (OMX_S32) 0x80001008, + + /** The hardware failed to respond as expected */ + OMX_ErrorHardware = (OMX_S32) 0x80001009, + + /** The component is in the state OMX_StateInvalid */ + OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, + + /** Stream is found to be corrupt */ + OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, + + /** Ports being connected are not compatible */ + OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, + + /** Resources allocated to an idle component have been + lost resulting in the component returning to the loaded state */ + OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, + + /** No more indicies can be enumerated */ + OMX_ErrorNoMore = (OMX_S32) 0x8000100E, + + /** The component detected a version mismatch */ + OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, + + /** The component is not ready to return data at this time */ + OMX_ErrorNotReady = (OMX_S32) 0x80001010, + + /** There was a timeout that occurred */ + OMX_ErrorTimeout = (OMX_S32) 0x80001011, + + /** This error occurs when trying to transition into the state you are already in */ + OMX_ErrorSameState = (OMX_S32) 0x80001012, + + /** Resources allocated to an executing or paused component have been + preempted, causing the component to return to the idle state */ + OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the allocation of buffers (on a transition from the LOADED to the IDLE state or + on a port restart) when it deems that it has waited an unusually long time for the supplier + to send it an allocated buffer via a UseBuffer call. */ + OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the deallocation of buffers (on a transition from the IDLE to LOADED state or + on a port stop) when it deems that it has waited an unusually long time for the supplier + to request the deallocation of a buffer header via a FreeBuffer call. */ + OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, + + /** A supplier port sends this error to the IL client (via the EventHandler callback) + during the stopping of a port (either on a transition from the IDLE to LOADED + state or a port stop) when it deems that it has waited an unusually long time for + the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ + OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, + + /** Attempting a state transtion that is not allowed */ + OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, + + /* Attempting a command that is not allowed during the present state. */ + OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, + + /** The values encapsulated in the parameter or config structure are not supported. */ + OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, + + /** The parameter or config indicated by the given index is not supported. */ + OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, + + /** The port index supplied is incorrect. */ + OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, + + /** The port has lost one or more of its buffers and it thus unpopulated. */ + OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, + + /** Component suspended due to temporary loss of resources */ + OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, + + /** Component suspended due to an inability to acquire dynamic resources */ + OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, + + /** When the macroblock error reporting is enabled the component returns new error + for every frame that has errors */ + OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, + + /** A component reports this error when it cannot parse or determine the format of an input stream. */ + OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, + + /** The content open operation failed. */ + OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, + + /** The content creation operation failed. */ + OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, + + /** Separate table information is being used */ + OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, + + /** Tunneling is unsupported by the component*/ + OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, + + OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ErrorMax = 0x7FFFFFFF +} OMX_ERRORTYPE; + +/** @ingroup core */ +typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); + +/** @ingroup core */ +typedef struct OMX_COMPONENTREGISTERTYPE +{ + const char * pName; /* Component name, 128 byte limit (including '\0') applies */ + OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ +} OMX_COMPONENTREGISTERTYPE; + +/** @ingroup core */ +extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; + +/** @ingroup rpm */ +typedef struct OMX_PRIORITYMGMTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nGroupPriority; /**< Priority of the component group */ + OMX_U32 nGroupID; /**< ID of the component group */ +} OMX_PRIORITYMGMTTYPE; + +/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ +#define OMX_MAX_STRINGNAME_SIZE 128 + +/** @ingroup comp */ +typedef struct OMX_PARAM_COMPONENTROLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ +} OMX_PARAM_COMPONENTROLETYPE; + +/** End of Stream Buffer Flag: + * + * A component sets EOS when it has no more data to emit on a particular + * output port. Thus an output port shall set EOS on the last buffer it + * emits. A component's determination of when an output port should + * cease sending data is implemenation specific. + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_EOS 0x00000001 + +/** Start Time Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the STARTTIME + * flag on the buffer that contains the starting timestamp for the + * stream. The starting timestamp corresponds to the first data that + * should be displayed at startup or after a seek. + * The first timestamp of the stream is not necessarily the start time. + * For instance, in the case of a seek to a particular video frame, + * the target frame may be an interframe. Thus the first buffer of + * the stream will be the intra-frame preceding the target frame and + * the starttime will occur with the target frame (with any other + * required frames required to reconstruct the target intervening). + * + * The STARTTIME flag is directly associated with the buffer's + * timestamp ' thus its association to buffer data and its + * propagation is identical to the timestamp's. + * + * When a Sync Component client receives a buffer with the + * STARTTIME flag it shall perform a SetConfig on its sync port + * using OMX_ConfigTimeClientStartTime and passing the buffer's + * timestamp. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_STARTTIME 0x00000002 + + + +/** Decode Only Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the DECODEONLY + * flag on any buffer that should shall be decoded but should not be + * displayed. This flag is used, for instance, when a source seeks to + * a target interframe that requires the decode of frames preceding the + * target to facilitate the target's reconstruction. In this case the + * source would emit the frames preceding the target downstream + * but mark them as decode only. + * + * The DECODEONLY is associated with buffer data and propagated in a + * manner identical to the buffer timestamp. + * + * A component that renders data should ignore all buffers with + * the DECODEONLY flag set. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 + + +/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 + +/* End of Frame: The buffer contains exactly one end of frame and no data + * occurs after the end of frame. This flag is an optional hint. The absence + * of this flag does not imply the absence of an end of frame within the buffer. + * @ingroup buf +*/ +#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 + +/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' + * a frame that has no dependency on any other frame information + * @ingroup buf + */ +#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 + +/* Extra data present flag: there is extra data appended to the data stream + * residing in the buffer + * @ingroup buf + */ +#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 + +/** Codec Config Buffer Flag: +* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an +* output port when all bytes in the buffer form part or all of a set of +* codec specific configuration data. Examples include SPS/PPS nal units +* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for +* OMX_AUDIO_CodingAAC. Any component that for a given stream sets +* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes +* with frame data in the same buffer, and shall send all buffers +* containing codec configuration bytes before any buffers containing +* frame data that those configurations bytes describe. +* If the stream format for a particular codec has a frame specific +* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or +* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as +* normal without setting OMX_BUFFERFLAG_CODECCONFIG. + * @ingroup buf + */ +#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 + + + +/** @ingroup buf */ +typedef struct OMX_BUFFERHEADERTYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8* pBuffer; /**< Pointer to actual block of memory + that is acting as the buffer */ + OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ + OMX_U32 nFilledLen; /**< number of bytes currently in the + buffer */ + OMX_U32 nOffset; /**< start offset of valid data in bytes from + the start of the buffer */ + OMX_PTR pAppPrivate; /**< pointer to any data the application + wants to associate with this buffer */ + OMX_PTR pPlatformPrivate; /**< pointer to any data the platform + wants to associate with this buffer */ + OMX_PTR pInputPortPrivate; /**< pointer to any data the input port + wants to associate with this buffer */ + OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port + wants to associate with this buffer */ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a + mark event upon processing this buffer. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ + OMX_U32 nTickCount; /**< Optional entry that the component and + application can update with a tick count + when they access the component. This + value should be in microseconds. Since + this is a value relative to an arbitrary + starting point, this value cannot be used + to determine absolute time. This is an + optional entry and not all components + will update it.*/ + OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample + starting at the first logical sample + boundary in the buffer. Timestamps of + successive samples within the buffer may + be inferred by adding the duration of the + of the preceding buffer to the timestamp + of the preceding buffer.*/ + OMX_U32 nFlags; /**< buffer specific flags */ + OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using + this buffer */ + OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using + this buffer */ +} OMX_BUFFERHEADERTYPE; + +/** The OMX_EXTRADATATYPE enumeration is used to define the + * possible extra data payload types. + * NB: this enum is binary backwards compatible with the previous + * OMX_EXTRADATA_QUANT define. This should be replaced with + * OMX_ExtraDataQuantization. + */ +typedef enum OMX_EXTRADATATYPE +{ + OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ + OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ + OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExtraDataMax = 0x7FFFFFFF +} OMX_EXTRADATATYPE; + + +typedef struct OMX_OTHER_EXTRADATATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXTRADATATYPE eType; /* Extra Data type */ + OMX_U32 nDataSize; /* Size of the supporting data to follow */ + OMX_U8 data[1]; /* Supporting data hint */ +} OMX_OTHER_EXTRADATATYPE; + +/** @ingroup comp */ +typedef struct OMX_PORT_PARAM_TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPorts; /**< The number of ports for this component */ + OMX_U32 nStartPortNumber; /** first port number for this type of port */ +} OMX_PORT_PARAM_TYPE; + +/** @ingroup comp */ +typedef enum OMX_EVENTTYPE +{ + OMX_EventCmdComplete, /**< component has sucessfully completed a command */ + OMX_EventError, /**< component has detected an error condition */ + OMX_EventMark, /**< component has detected a buffer mark */ + OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ + OMX_EventBufferFlag, /**< component has detected an EOS */ + OMX_EventResourcesAcquired, /**< component has been granted resources and is + automatically starting the state change from + OMX_StateWaitForResources to OMX_StateIdle. */ + OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ + OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ + OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ + OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EventMax = 0x7FFFFFFF +} OMX_EVENTTYPE; + +typedef struct OMX_CALLBACKTYPE +{ + /** The EventHandler method is used to notify the application when an + event of interest occurs. Events are defined in the OMX_EVENTTYPE + enumeration. Please see that enumeration for details of what will + be returned for each type of event. Callbacks should not return + an error to the component, so if an error occurs, the application + shall handle it internally. This is a blocking call. + + The application should return from this call within 5 msec to avoid + blocking the component for an excessively long period of time. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param eEvent + Event that the component wants to notify the application about. + @param nData1 + nData will be the OMX_ERRORTYPE for an error event and will be + an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. + @param nData2 + nData2 will hold further information related to the event. Can be OMX_STATETYPE for + a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. + Default value is 0 if not used. ) + @param pEventData + Pointer to additional event-specific data (see spec for meaning). + */ + + OMX_ERRORTYPE (*EventHandler)( + 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); + + /** The EmptyBufferDone method is used to return emptied buffers from an + input port back to the application for reuse. This is a blocking call + so the application should not attempt to refill the buffers during this + call, but should queue them and refill them in another thread. There + is no error return, so the application shall handle any errors generated + internally. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was emptied. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyBufferDone)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The FillBufferDone method is used to return filled buffers from an + output port back to the application for emptying and then reuse. + This is a blocking call so the application should not attempt to + empty the buffers during this call, but should queue the buffers + and empty them in another thread. There is no error return, so + the application shall handle any errors generated internally. The + application shall also update the buffer header to indicate the + number of bytes placed into the buffer. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was filled. + @ingroup buf + */ + OMX_ERRORTYPE (*FillBufferDone)( + OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); + +} OMX_CALLBACKTYPE; + +/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier + preference when tunneling between two ports. + @ingroup tun buf +*/ +typedef enum OMX_BUFFERSUPPLIERTYPE +{ + OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, + or don't care */ + OMX_BufferSupplyInput, /**< input port supplies the buffers */ + OMX_BufferSupplyOutput, /**< output port supplies the buffers */ + OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_BufferSupplyMax = 0x7FFFFFFF +} OMX_BUFFERSUPPLIERTYPE; + + +/** buffer supplier parameter + * @ingroup tun + */ +typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ +} OMX_PARAM_BUFFERSUPPLIERTYPE; + + +/**< indicates that buffers received by an input port of a tunnel + may not modify the data in the buffers + @ingroup tun + */ +#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 + + +/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output + port to an input port as part the two ComponentTunnelRequest calls + resulting from a OMX_SetupTunnel call from the IL Client. + @ingroup tun + */ +typedef struct OMX_TUNNELSETUPTYPE +{ + OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ + OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ +} OMX_TUNNELSETUPTYPE; + +/* OMX Component headers is included to enable the core to use + macros for functions into the component for OMX release 1.0. + Developers should not access any structures or data from within + the component header directly */ +/* TO BE REMOVED - #include */ + +/** GetComponentVersion will return information about the component. + This is a blocking call. This macro will go directly from the + application to the component (via a core macro). The + component will return from this call within 5 msec. + @param [in] hComponent + handle of component to execute the command + @param [out] pComponentName + pointer to an empty string of length 128 bytes. The component + will write its name into this string. The name will be + terminated by a single zero byte. The name of a component will + be 127 bytes or less to leave room for the trailing zero byte. + An example of a valid component name is "OMX.ABC.ChannelMixer\0". + @param [out] pComponentVersion + pointer to an OMX Version structure that the component will fill + in. The component will fill in a value that indicates the + component version. NOTE: the component version is NOT the same + as the OMX Specification version (found in all structures). The + component version is defined by the vendor of the component and + its value is entirely up to the component vendor. + @param [out] pSpecVersion + pointer to an OMX Version structure that the component will fill + in. The SpecVersion is the version of the specification that the + component was built against. Please note that this value may or + may not match the structure's version. For example, if the + component was built against the 2.0 specification, but the + application (which creates the structure is built against the + 1.0 specification the versions would be different. + @param [out] pComponentUUID + pointer to the UUID of the component which will be filled in by + the component. The UUID is a unique identifier that is set at + RUN time for the component and is unique to each instantion of + the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) /* Macro End */ + + +/** Send a command to the component. This call is a non-blocking call. + The component should check the parameters and then queue the command + to the component thread to be executed. The component thread shall + send the EventHandler() callback at the conclusion of the command. + This macro will go directly from the application to the component (via + a core macro). The component will return from this call within 5 msec. + + When the command is "OMX_CommandStateSet" the component will queue a + state transition to the new state idenfied in nParam. + + When the command is "OMX_CommandFlush", to flush a port's buffer queues, + the command will force the component to return all buffers NOT CURRENTLY + BEING PROCESSED to the application, in the order in which the buffers + were received. + + When the command is "OMX_CommandPortDisable" or + "OMX_CommandPortEnable", the component's port (given by the value of + nParam) will be stopped or restarted. + + When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the + pCmdData will point to a OMX_MARKTYPE structure containing the component + handle of the component to examine the buffer chain for the mark. nParam1 + contains the index of the port on which the buffer mark is applied. + + Specification text for more details. + + @param [in] hComponent + handle of component to execute the command + @param [in] Cmd + Command for the component to execute + @param [in] nParam + Parameter for the command to be executed. When Cmd has the value + OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has + the value OMX_CommandFlush, value of nParam indicates which port(s) + to flush. -1 is used to flush all ports a single port index will + only flush that port. When Cmd has the value "OMX_CommandPortDisable" + or "OMX_CommandPortEnable", the component's port is given by + the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" + the components pot is given by the value of nParam. + @param [in] pCmdData + Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value + "OMX_CommandMarkBuffer". + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) \ + ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) /* Macro End */ + + +/** The OMX_GetParameter macro will get one of the current parameter + settings from the component. This macro cannot only be invoked when + the component is in the OMX_StateInvalid state. The nParamIndex + parameter is used to indicate which structure is being requested from + the component. The application shall allocate the correct structure + and shall fill in the structure size and version information before + invoking this macro. When the parameter applies to a port, the + caller shall fill in the appropriate nPortIndex value indicating the + port on which the parameter applies. If the component has not had + any settings changed, then the component should return a set of + valid DEFAULT parameters for the component. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nParamIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentParameterStructure + Pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_SetParameter macro will send an initialization parameter + structure to a component. Each structure shall be sent one at a time, + in a separate invocation of the macro. This macro can only be + invoked when the component is in the OMX_StateLoaded state, or the + port is disabled (when the parameter applies to a port). The + nParamIndex parameter is used to indicate which structure is being + passed to the component. The application shall allocate the + correct structure and shall fill in the structure size and version + information (as well as the actual data) before invoking this macro. + The application is free to dispose of this structure after the call + as the component is required to copy any data it shall retain. This + is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration. + @param [in] pComponentParameterStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_GetConfig macro will get one of the configuration structures + from a component. This macro can be invoked anytime after the + component has been loaded. The nParamIndex call parameter is used to + indicate which structure is being requested from the component. The + application shall allocate the correct structure and shall fill in the + structure size and version information before invoking this macro. + If the component has not had this configuration parameter sent before, + then the component should return a set of valid DEFAULT values for the + component. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentConfigStructure + pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp +*/ +#define OMX_GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_SetConfig macro will send one of the configuration + structures to a component. Each structure shall be sent one at a time, + each in a separate invocation of the macro. This macro can be invoked + anytime after the component has been loaded. The application shall + allocate the correct structure and shall fill in the structure size + and version information (as well as the actual data) before invoking + this macro. The application is free to dispose of this structure after + the call as the component is required to copy any data it shall retain. + This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nConfigIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration above. + @param [in] pComponentConfigStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_GetExtensionIndex macro will invoke a component to translate + a vendor specific configuration or parameter string into an OMX + structure index. There is no requirement for the vendor to support + this command for the indexes already found in the OMX_INDEXTYPE + enumeration (this is done to save space in small components). The + component shall support all vendor supplied extension indexes not found + in the master OMX_INDEXTYPE enumeration. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] cParameterName + OMX_STRING that shall be less than 128 characters long including + the trailing null byte. This is the string that will get + translated by the component into a configuration index. + @param [out] pIndexType + a pointer to a OMX_INDEXTYPE to receive the index value. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) /* Macro End */ + + +/** The OMX_GetState macro will invoke the component to get the current + state of the component and place the state value into the location + pointed to by pState. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] pState + pointer to the location to receive the state. The value returned + is one of the OMX_STATETYPE members + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetState( \ + hComponent, \ + pState) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ + hComponent, \ + pState) /* Macro End */ + + +/** The OMX_UseBuffer macro will request that the component use + a buffer (and allocate its own buffer header) already allocated + by another component, or by the IL Client. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ + +#define OMX_UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) + + +/** The OMX_AllocateBuffer macro will request that the component allocate + a new buffer and buffer header. The component will allocate the + buffer and the buffer header and return a pointer to the buffer + header. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive + the pointer to the buffer header + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] nSizeBytes + size of the buffer to allocate. Used when bAllocateNew is true. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) \ + ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) /* Macro End */ + + +/** The OMX_FreeBuffer macro will release a buffer header from the component + which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If + the component allocated the buffer (see the OMX_UseBuffer macro) then + the component shall free the buffer and buffer header. This is a + blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) /* Macro End */ + + +/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an + input port of a component. The buffer will be emptied by the component + and returned to the application via the EmptyBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then empty the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_StateExecuting. If nPortIndex does not specify an input + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_EmptyThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + +/** The OMX_FillThisBuffer macro will send an empty buffer to an + output port of a component. The buffer will be filled by the component + and returned to the application via the FillBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then fill the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_ExecutingState. If nPortIndex does not specify an output + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FillThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + + +/** The OMX_UseEGLImage macro will request that the component use + a EGLImage provided by EGL (and allocate its own buffer header) + This is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header. Note that the memory location used + for this buffer is NOT visible to the IL Client. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] eglImage + eglImage contains the handle of the EGLImage to use as a buffer on the + specified port. The component is expected to validate properties of + the EGLImage against the configuration of the port to ensure the component + can use the EGLImage as a buffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) + +/** The OMX_Init method is used to initialize the OMX core. It shall be the + first call made into OMX and it should only be executed one time without + an interviening OMX_Deinit call. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); + + +/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be + the last call made into OMX. In the event that the core determines that + thare are components loaded when this call is made, the core may return + with an error rather than try to unload the components. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); + + +/** The OMX_ComponentNameEnum method will enumerate through all the names of + recognised valid components in the system. This function is provided + as a means to detect all the components in the system run-time. There is + no strict ordering to the enumeration order of component names, although + each name will only be enumerated once. If the OMX core supports run-time + installation of new components, it is only requried to detect newly + installed components when the first call to enumerate component names + is made (i.e. when nIndex is 0x0). + + The core should return from this call in 20 msec. + + @param [out] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] nNameLength + number of characters in the cComponentName string. With all + component name strings restricted to less than 128 characters + (including the trailing null) it is recomended that the caller + provide a input string for the cComponentName of 128 characters. + @param [in] nIndex + number containing the enumeration index for the component. + Multiple calls to OMX_ComponentNameEnum with increasing values + of nIndex will enumerate through the component names in the + system until OMX_ErrorNoMore is returned. The value of nIndex + is 0 to (N-1), where N is the number of valid installed components + in the system. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. When the value of nIndex exceeds the number of + components in the system minus 1, OMX_ErrorNoMore will be + returned. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); + + +/** The OMX_GetHandle method will locate the component specified by the + component name given, load that component into memory and then invoke + the component's methods to create an instance of the component. + + The core should return from this call within 20 msec. + + @param [out] pHandle + pointer to an OMX_HANDLETYPE pointer to be filled in by this method. + @param [in] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] pAppData + pointer to an application defined value that will be returned + during callbacks so that the application can identify the source + of the callback. + @param [in] pCallBacks + pointer to a OMX_CALLBACKTYPE structure that will be passed to the + component to initialize it with. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE* pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE* pCallBacks); + + +/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle + method. If the component reference count goes to zero, the component will + be unloaded from memory. + + The core should return from this call within 20 msec when the component is + in the OMX_StateLoaded state. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); + + + +/** The OMX_SetupTunnel method will handle the necessary calls to the components + to setup the specified tunnel the two components. NOTE: This is + an actual method (not a #define macro). This method will make calls into + the component ComponentTunnelRequest method to do the actual tunnel + connection. + + The ComponentTunnelRequest method on both components will be called. + This method shall not be called unless the component is in the + OMX_StateLoaded state except when the ports used for the tunnel are + disabled. In this case, the component may be in the OMX_StateExecuting, + OMX_StatePause, or OMX_StateIdle states. + + The core should return from this call within 20 msec. + + @param [in] hOutput + Handle of the component to be accessed. Also this is the handle + of the component whose port, specified in the nPortOutput parameter + will be used the source for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hOutput be the source for the data when + tunelling (i.e. nPortOutput is an output port). If 0x0, the component + specified in hInput will have it's port specified in nPortInput + setup for communication with the application / IL client. + @param [in] nPortOutput + nPortOutput is used to select the source port on component to be + used in the tunnel. + @param [in] hInput + This is the component to setup the tunnel with. This is the handle + of the component whose port, specified in the nPortInput parameter + will be used the destination for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hInput be the destination for the data when + tunelling (i.e. nPortInut is an input port). If 0x0, the component + specified in hOutput will have it's port specified in nPortPOutput + setup for communication with the application / IL client. + @param [in] nPortInput + nPortInput is used to select the destination port on component to be + used in the tunnel. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + When OMX_ErrorNotImplemented is returned, one or both components is + a non-interop component and does not support tunneling. + + On failure, the ports of both components are setup for communication + with the application / IL Client. + @ingroup core tun + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); + +/** @ingroup cp */ +OMX_API OMX_ERRORTYPE OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); + +/** The OMX_GetComponentsOfRole method will return the number of components that support the given + role and (if the compNames field is non-NULL) the names of those components. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the compNames field NULL to determine the number of component names + * second call this function with the compNames field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] role + This is generic standard component name consisting only of component class + name and the type within that class (e.g. 'audio_decoder.aac'). + @param [inout] pNumComps + This is used both as input and output. + + If compNames is NULL, the input is ignored and the output specifies how many components support + the given role. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of components string names listed within the compNames parameter. + @param [inout] compNames + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts + a list of the names of all physical components that implement the specified standard component name. + Each name is NULL terminated. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); + +/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given + component and (if the roles field is non-NULL) the names of those roles. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the roles field NULL to determine the number of role names + * second call this function with the roles field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] compName + This is the name of the component being queried about. + @param [inout] pNumRoles + This is used both as input and output. + + If roles is NULL, the input is ignored and the output specifies how many roles the component supports. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of roles string names listed within the roles parameter. + @param [out] roles + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings + which accepts a list of the names of all standard components roles implemented on the + specified component name. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/exynos/multimedia/openmax/include/khronos/OMX_IVCommon.h b/exynos/multimedia/openmax/include/khronos/OMX_IVCommon.h new file mode 100644 index 0000000..4c4995c --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_IVCommon.h @@ -0,0 +1,920 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** + * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 + * The structures needed by Video and Image components to exchange + * parameters and configuration data with the components. + */ +#ifndef OMX_IVCommon_h +#define OMX_IVCommon_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Each OMX header must include all required header files to allow the header + * to compile without errors. The includes below are required for this header + * file to compile successfully + */ + +#include + +/** @defgroup iv OpenMAX IL Imaging and Video Domain + * Common structures for OpenMAX IL Imaging and Video domains + * @{ + */ + + +/** + * Enumeration defining possible uncompressed image/video formats. + * + * ENUMS: + * Unused : Placeholder value when format is N/A + * Monochrome : black and white + * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 + * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 + * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 + * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 + * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 + * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 + * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 + * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 + * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 + * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 + * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 + * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 + * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 + * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally + * YUV411PackedPlanar : packed per payload in planar slices + * YUV420Planar : Three arrays Y,U,V. + * YUV420PackedPlanar : packed per payload in planar slices + * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V + * YUV422Planar : Three arrays Y,U,V. + * YUV422PackedPlanar : packed per payload in planar slices + * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V + * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) + * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) + * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) + * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) + * YUV444Interleaved : Each pixel contains equal parts YUV + * RawBayer8bit : SMIA camera output format + * RawBayer10bit : SMIA camera output format + * RawBayer8bitcompressed : SMIA camera output format + */ +typedef enum OMX_COLOR_FORMATTYPE { + OMX_COLOR_FormatUnused, + OMX_COLOR_FormatMonochrome, + OMX_COLOR_Format8bitRGB332, + OMX_COLOR_Format12bitRGB444, + OMX_COLOR_Format16bitARGB4444, + OMX_COLOR_Format16bitARGB1555, + OMX_COLOR_Format16bitRGB565, + OMX_COLOR_Format16bitBGR565, + OMX_COLOR_Format18bitRGB666, + OMX_COLOR_Format18bitARGB1665, + OMX_COLOR_Format19bitARGB1666, + OMX_COLOR_Format24bitRGB888, + OMX_COLOR_Format24bitBGR888, + OMX_COLOR_Format24bitARGB1887, + OMX_COLOR_Format25bitARGB1888, + OMX_COLOR_Format32bitBGRA8888, + OMX_COLOR_Format32bitARGB8888, + OMX_COLOR_FormatYUV411Planar, + OMX_COLOR_FormatYUV411PackedPlanar, + OMX_COLOR_FormatYUV420Planar, + OMX_COLOR_FormatYUV420PackedPlanar, + OMX_COLOR_FormatYUV420SemiPlanar, + OMX_COLOR_FormatYUV422Planar, + OMX_COLOR_FormatYUV422PackedPlanar, + OMX_COLOR_FormatYUV422SemiPlanar, + OMX_COLOR_FormatYCbYCr, + OMX_COLOR_FormatYCrYCb, + OMX_COLOR_FormatCbYCrY, + OMX_COLOR_FormatCrYCbY, + OMX_COLOR_FormatYUV444Interleaved, + OMX_COLOR_FormatRawBayer8bit, + OMX_COLOR_FormatRawBayer10bit, + OMX_COLOR_FormatRawBayer8bitcompressed, + OMX_COLOR_FormatL2, + OMX_COLOR_FormatL4, + OMX_COLOR_FormatL8, + OMX_COLOR_FormatL16, + OMX_COLOR_FormatL24, + OMX_COLOR_FormatL32, + OMX_COLOR_FormatYUV420PackedSemiPlanar, + OMX_COLOR_FormatYUV422PackedSemiPlanar, + OMX_COLOR_Format18BitBGR666, + OMX_COLOR_Format24BitARGB6666, + OMX_COLOR_Format24BitABGR6666, + OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_COLOR_FormatMax = 0x7FFFFFFF +} OMX_COLOR_FORMATTYPE; + + +/** + * Defines the matrix for conversion from RGB to YUV or vice versa. + * iColorMatrix should be initialized with the fixed point values + * used in converting between formats. + */ +typedef struct OMX_CONFIG_COLORCONVERSIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */ + OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */ +}OMX_CONFIG_COLORCONVERSIONTYPE; + + +/** + * Structure defining percent to scale each frame dimension. For example: + * To make the width 50% larger, use fWidth = 1.5 and to make the width + * 1/2 the original size, use fWidth = 0.5 + */ +typedef struct OMX_CONFIG_SCALEFACTORTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 xWidth; /**< Fixed point value stored as Q16 */ + OMX_S32 xHeight; /**< Fixed point value stored as Q16 */ +}OMX_CONFIG_SCALEFACTORTYPE; + + +/** + * Enumeration of possible image filter types + */ +typedef enum OMX_IMAGEFILTERTYPE { + OMX_ImageFilterNone, + OMX_ImageFilterNoise, + OMX_ImageFilterEmboss, + OMX_ImageFilterNegative, + OMX_ImageFilterSketch, + OMX_ImageFilterOilPaint, + OMX_ImageFilterHatch, + OMX_ImageFilterGpen, + OMX_ImageFilterAntialias, + OMX_ImageFilterDeRing, + OMX_ImageFilterSolarize, + OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ImageFilterMax = 0x7FFFFFFF +} OMX_IMAGEFILTERTYPE; + + +/** + * Image filter configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eImageFilter : Image filter type enumeration + */ +typedef struct OMX_CONFIG_IMAGEFILTERTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGEFILTERTYPE eImageFilter; +} OMX_CONFIG_IMAGEFILTERTYPE; + + +/** + * Customized U and V for color enhancement + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bColorEnhancement : Enable/disable color enhancement + * nCustomizedU : Practical values: 16-240, range: 0-255, value set for + * U component + * nCustomizedV : Practical values: 16-240, range: 0-255, value set for + * V component + */ +typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bColorEnhancement; + OMX_U8 nCustomizedU; + OMX_U8 nCustomizedV; +} OMX_CONFIG_COLORENHANCEMENTTYPE; + + +/** + * Define color key and color key mask + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nARGBColor : 32bit Alpha, Red, Green, Blue Color + * nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels + */ +typedef struct OMX_CONFIG_COLORKEYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nARGBColor; + OMX_U32 nARGBMask; +} OMX_CONFIG_COLORKEYTYPE; + + +/** + * List of color blend types for pre/post processing + * + * ENUMS: + * None : No color blending present + * AlphaConstant : Function is (alpha_constant * src) + + * (1 - alpha_constant) * dst) + * AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst) + * Alternate : Function is alternating pixels from src and dst + * And : Function is (src & dst) + * Or : Function is (src | dst) + * Invert : Function is ~src + */ +typedef enum OMX_COLORBLENDTYPE { + OMX_ColorBlendNone, + OMX_ColorBlendAlphaConstant, + OMX_ColorBlendAlphaPerPixel, + OMX_ColorBlendAlternate, + OMX_ColorBlendAnd, + OMX_ColorBlendOr, + OMX_ColorBlendInvert, + OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ColorBlendMax = 0x7FFFFFFF +} OMX_COLORBLENDTYPE; + + +/** + * Color blend configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nRGBAlphaConstant : Constant global alpha values when global alpha is used + * eColorBlend : Color blend type enumeration + */ +typedef struct OMX_CONFIG_COLORBLENDTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nRGBAlphaConstant; + OMX_COLORBLENDTYPE eColorBlend; +} OMX_CONFIG_COLORBLENDTYPE; + + +/** + * Hold frame dimension + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nWidth : Frame width in pixels + * nHeight : Frame height in pixels + */ +typedef struct OMX_FRAMESIZETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nWidth; + OMX_U32 nHeight; +} OMX_FRAMESIZETYPE; + + +/** + * Rotation configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nRotation : +/- integer rotation value + */ +typedef struct OMX_CONFIG_ROTATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nRotation; +} OMX_CONFIG_ROTATIONTYPE; + + +/** + * Possible mirroring directions for pre/post processing + * + * ENUMS: + * None : No mirroring + * Vertical : Vertical mirroring, flip on X axis + * Horizontal : Horizontal mirroring, flip on Y axis + * Both : Both vertical and horizontal mirroring + */ +typedef enum OMX_MIRRORTYPE { + OMX_MirrorNone = 0, + OMX_MirrorVertical, + OMX_MirrorHorizontal, + OMX_MirrorBoth, + OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MirrorMax = 0x7FFFFFFF +} OMX_MIRRORTYPE; + + +/** + * Mirroring configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eMirror : Mirror type enumeration + */ +typedef struct OMX_CONFIG_MIRRORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_MIRRORTYPE eMirror; +} OMX_CONFIG_MIRRORTYPE; + + +/** + * Position information only + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nX : X coordinate for the point + * nY : Y coordinate for the point + */ +typedef struct OMX_CONFIG_POINTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nX; + OMX_S32 nY; +} OMX_CONFIG_POINTTYPE; + + +/** + * Frame size plus position + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nLeft : X Coordinate of the top left corner of the rectangle + * nTop : Y Coordinate of the top left corner of the rectangle + * nWidth : Width of the rectangle + * nHeight : Height of the rectangle + */ +typedef struct OMX_CONFIG_RECTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nLeft; + OMX_S32 nTop; + OMX_U32 nWidth; + OMX_U32 nHeight; +} OMX_CONFIG_RECTTYPE; + + +/** + * Deblocking state; it is required to be set up before starting the codec + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bDeblocking : Enable/disable deblocking mode + */ +typedef struct OMX_PARAM_DEBLOCKINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bDeblocking; +} OMX_PARAM_DEBLOCKINGTYPE; + + +/** + * Stabilization state + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bStab : Enable/disable frame stabilization state + */ +typedef struct OMX_CONFIG_FRAMESTABTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bStab; +} OMX_CONFIG_FRAMESTABTYPE; + + +/** + * White Balance control type + * + * STRUCT MEMBERS: + * SunLight : Referenced in JSR-234 + * Flash : Optimal for device's integrated flash + */ +typedef enum OMX_WHITEBALCONTROLTYPE { + OMX_WhiteBalControlOff = 0, + OMX_WhiteBalControlAuto, + OMX_WhiteBalControlSunLight, + OMX_WhiteBalControlCloudy, + OMX_WhiteBalControlShade, + OMX_WhiteBalControlTungsten, + OMX_WhiteBalControlFluorescent, + OMX_WhiteBalControlIncandescent, + OMX_WhiteBalControlFlash, + OMX_WhiteBalControlHorizon, + OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_WhiteBalControlMax = 0x7FFFFFFF +} OMX_WHITEBALCONTROLTYPE; + + +/** + * White Balance control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eWhiteBalControl : White balance enumeration + */ +typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_WHITEBALCONTROLTYPE eWhiteBalControl; +} OMX_CONFIG_WHITEBALCONTROLTYPE; + + +/** + * Exposure control type + */ +typedef enum OMX_EXPOSURECONTROLTYPE { + OMX_ExposureControlOff = 0, + OMX_ExposureControlAuto, + OMX_ExposureControlNight, + OMX_ExposureControlBackLight, + OMX_ExposureControlSpotLight, + OMX_ExposureControlSports, + OMX_ExposureControlSnow, + OMX_ExposureControlBeach, + OMX_ExposureControlLargeAperture, + OMX_ExposureControlSmallApperture, + OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExposureControlMax = 0x7FFFFFFF +} OMX_EXPOSURECONTROLTYPE; + + +/** + * White Balance control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eExposureControl : Exposure control enumeration + */ +typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXPOSURECONTROLTYPE eExposureControl; +} OMX_CONFIG_EXPOSURECONTROLTYPE; + + +/** + * Defines sensor supported mode. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nFrameRate : Single shot mode is indicated by a 0 + * bOneShot : Enable for single shot, disable for streaming + * sFrameSize : Framesize + */ +typedef struct OMX_PARAM_SENSORMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nFrameRate; + OMX_BOOL bOneShot; + OMX_FRAMESIZETYPE sFrameSize; +} OMX_PARAM_SENSORMODETYPE; + + +/** + * Defines contrast level + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nContrast : Values allowed for contrast -100 to 100, zero means no change + */ +typedef struct OMX_CONFIG_CONTRASTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nContrast; +} OMX_CONFIG_CONTRASTTYPE; + + +/** + * Defines brightness level + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nBrightness : 0-100% + */ +typedef struct OMX_CONFIG_BRIGHTNESSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBrightness; +} OMX_CONFIG_BRIGHTNESSTYPE; + + +/** + * Defines backlight level configuration for a video sink, e.g. LCD panel + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nBacklight : Values allowed for backlight 0-100% + * nTimeout : Number of milliseconds before backlight automatically turns + * off. A value of 0x0 disables backight timeout + */ +typedef struct OMX_CONFIG_BACKLIGHTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBacklight; + OMX_U32 nTimeout; +} OMX_CONFIG_BACKLIGHTTYPE; + + +/** + * Defines setting for Gamma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nGamma : Values allowed for gamma -100 to 100, zero means no change + */ +typedef struct OMX_CONFIG_GAMMATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nGamma; +} OMX_CONFIG_GAMMATYPE; + + +/** + * Define for setting saturation + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSaturation : Values allowed for saturation -100 to 100, zero means + * no change + */ +typedef struct OMX_CONFIG_SATURATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nSaturation; +} OMX_CONFIG_SATURATIONTYPE; + + +/** + * Define for setting Lightness + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nLightness : Values allowed for lightness -100 to 100, zero means no + * change + */ +typedef struct OMX_CONFIG_LIGHTNESSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nLightness; +} OMX_CONFIG_LIGHTNESSTYPE; + + +/** + * Plane blend configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Index of input port associated with the plane. + * nDepth : Depth of the plane in relation to the screen. Higher + * numbered depths are "behind" lower number depths. + * This number defaults to the Port Index number. + * nAlpha : Transparency blending component for the entire plane. + * See blending modes for more detail. + */ +typedef struct OMX_CONFIG_PLANEBLENDTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nDepth; + OMX_U32 nAlpha; +} OMX_CONFIG_PLANEBLENDTYPE; + + +/** + * Define interlace type + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnable : Enable control variable for this functionality + * (see below) + * nInterleavePortIndex : Index of input or output port associated with + * the interleaved plane. + * pPlanarPortIndexes[4] : Index of input or output planar ports. + */ +typedef struct OMX_PARAM_INTERLEAVETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_U32 nInterleavePortIndex; +} OMX_PARAM_INTERLEAVETYPE; + + +/** + * Defines the picture effect used for an input picture + */ +typedef enum OMX_TRANSITIONEFFECTTYPE { + OMX_EffectNone, + OMX_EffectFadeFromBlack, + OMX_EffectFadeToBlack, + OMX_EffectUnspecifiedThroughConstantColor, + OMX_EffectDissolve, + OMX_EffectWipe, + OMX_EffectUnspecifiedMixOfTwoScenes, + OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EffectMax = 0x7FFFFFFF +} OMX_TRANSITIONEFFECTTYPE; + + +/** + * Structure used to configure current transition effect + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eEffect : Effect to enable + */ +typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_TRANSITIONEFFECTTYPE eEffect; +} OMX_CONFIG_TRANSITIONEFFECTTYPE; + + +/** + * Defines possible data unit types for encoded video data. The data unit + * types are used both for encoded video input for playback as well as + * encoded video output from recording. + */ +typedef enum OMX_DATAUNITTYPE { + OMX_DataUnitCodedPicture, + OMX_DataUnitVideoSegment, + OMX_DataUnitSeveralSegments, + OMX_DataUnitArbitraryStreamSection, + OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DataUnitMax = 0x7FFFFFFF +} OMX_DATAUNITTYPE; + + +/** + * Defines possible encapsulation types for coded video data unit. The + * encapsulation information is used both for encoded video input for + * playback as well as encoded video output from recording. + */ +typedef enum OMX_DATAUNITENCAPSULATIONTYPE { + OMX_DataEncapsulationElementaryStream, + OMX_DataEncapsulationGenericPayload, + OMX_DataEncapsulationRtpPayload, + OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DataEncapsulationMax = 0x7FFFFFFF +} OMX_DATAUNITENCAPSULATIONTYPE; + + +/** + * Structure used to configure the type of being decoded/encoded + */ +typedef struct OMX_PARAM_DATAUNITTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_DATAUNITTYPE eUnitType; + OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType; +} OMX_PARAM_DATAUNITTYPE; + + +/** + * Defines dither types + */ +typedef enum OMX_DITHERTYPE { + OMX_DitherNone, + OMX_DitherOrdered, + OMX_DitherErrorDiffusion, + OMX_DitherOther, + OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DitherMax = 0x7FFFFFFF +} OMX_DITHERTYPE; + + +/** + * Structure used to configure current type of dithering + */ +typedef struct OMX_CONFIG_DITHERTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_DITHERTYPE eDither; /**< Type of dithering to use */ +} OMX_CONFIG_DITHERTYPE; + +typedef struct OMX_CONFIG_CAPTUREMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture + * data as fast as possible (otherwise obey port's frame rate). */ + OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the + * specified number of frames (otherwise the port does not + * terminate the capture until instructed to do so by the client). + * Even if set, the client may manually terminate the capture prior + * to reaching the limit. */ + OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only + * valid if bFrameLimited is set). */ +} OMX_CONFIG_CAPTUREMODETYPE; + +typedef enum OMX_METERINGTYPE { + + OMX_MeteringModeAverage, /**< Center-weighted average metering. */ + OMX_MeteringModeSpot, /**< Spot (partial) metering. */ + OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */ + + OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EVModeMax = 0x7fffffff +} OMX_METERINGTYPE; + +typedef struct OMX_CONFIG_EXPOSUREVALUETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_METERINGTYPE eMetering; + OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */ + OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */ + OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */ + OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */ + OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */ + OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */ + OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */ +} OMX_CONFIG_EXPOSUREVALUETYPE; + +/** + * Focus region configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bCenter : Use center region as focus region of interest + * bLeft : Use left region as focus region of interest + * bRight : Use right region as focus region of interest + * bTop : Use top region as focus region of interest + * bBottom : Use bottom region as focus region of interest + * bTopLeft : Use top left region as focus region of interest + * bTopRight : Use top right region as focus region of interest + * bBottomLeft : Use bottom left region as focus region of interest + * bBottomRight : Use bottom right region as focus region of interest + */ +typedef struct OMX_CONFIG_FOCUSREGIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bCenter; + OMX_BOOL bLeft; + OMX_BOOL bRight; + OMX_BOOL bTop; + OMX_BOOL bBottom; + OMX_BOOL bTopLeft; + OMX_BOOL bTopRight; + OMX_BOOL bBottomLeft; + OMX_BOOL bBottomRight; +} OMX_CONFIG_FOCUSREGIONTYPE; + +/** + * Focus Status type + */ +typedef enum OMX_FOCUSSTATUSTYPE { + OMX_FocusStatusOff = 0, + OMX_FocusStatusRequest, + OMX_FocusStatusReached, + OMX_FocusStatusUnableToReach, + OMX_FocusStatusLost, + OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_FocusStatusMax = 0x7FFFFFFF +} OMX_FOCUSSTATUSTYPE; + +/** + * Focus status configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusStatus : Specifies the focus status + * bCenterStatus : Use center region as focus region of interest + * bLeftStatus : Use left region as focus region of interest + * bRightStatus : Use right region as focus region of interest + * bTopStatus : Use top region as focus region of interest + * bBottomStatus : Use bottom region as focus region of interest + * bTopLeftStatus : Use top left region as focus region of interest + * bTopRightStatus : Use top right region as focus region of interest + * bBottomLeftStatus : Use bottom left region as focus region of interest + * bBottomRightStatus : Use bottom right region as focus region of interest + */ +typedef struct OMX_PARAM_FOCUSSTATUSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_FOCUSSTATUSTYPE eFocusStatus; + OMX_BOOL bCenterStatus; + OMX_BOOL bLeftStatus; + OMX_BOOL bRightStatus; + OMX_BOOL bTopStatus; + OMX_BOOL bBottomStatus; + OMX_BOOL bTopLeftStatus; + OMX_BOOL bTopRightStatus; + OMX_BOOL bBottomLeftStatus; + OMX_BOOL bBottomRightStatus; +} OMX_PARAM_FOCUSSTATUSTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Image.h b/exynos/multimedia/openmax/include/khronos/OMX_Image.h new file mode 100644 index 0000000..a6d4666 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Image.h @@ -0,0 +1,328 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file OMX_Image.h - OpenMax IL version 1.1.2 + * The structures needed by Image components to exchange parameters and + * configuration data with the components. + */ +#ifndef OMX_Image_h +#define OMX_Image_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup imaging OpenMAX IL Imaging Domain + * @ingroup iv + * Structures for OpenMAX IL Imaging domain + * @{ + */ + +/** + * Enumeration used to define the possible image compression coding. + */ +typedef enum OMX_IMAGE_CODINGTYPE { + OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ + OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ + OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ + OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ + OMX_IMAGE_CodingEXIF, /**< EXIF image format */ + OMX_IMAGE_CodingTIFF, /**< TIFF image format */ + OMX_IMAGE_CodingGIF, /**< Graphics image format */ + OMX_IMAGE_CodingPNG, /**< PNG image format */ + OMX_IMAGE_CodingLZW, /**< LZW image format */ + OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ + OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_CodingMax = 0x7FFFFFFF +} OMX_IMAGE_CODINGTYPE; + + +/** + * Data structure used to define an image path. The number of image paths + * for input and output will vary by type of the image component. + * + * Input (aka Source) : Zero Inputs, one Output, + * Splitter : One Input, 2 or more Outputs, + * Processing Element : One Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : One Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output + * image path. If additional vendor specific data is required, it should + * be transmitted to the component using the CustomCommand function. + * Compliant components will prepopulate this structure with optimal + * values during the OMX_GetParameter() command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nFrameHeight : Height of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nStride : Number of bytes per span of an image (i.e. + * indicates the number of bytes to get from + * span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of + * the component. When OMX_IMAGE_CodingUnused is + * specified, eColorFormat is valid + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_BOOL bFlagErrorConcealment; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_IMAGE_PORTDEFINITIONTYPE; + + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_IMAGE_CodingUnused is specified, + * eColorFormat is valid + * eColorFormat : Decompressed format used by this component + */ +typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; +} OMX_IMAGE_PARAM_PORTFORMATTYPE; + + +/** + * Flash control type + * + * ENUMS + * Torch : Flash forced constantly on + */ +typedef enum OMX_IMAGE_FLASHCONTROLTYPE { + OMX_IMAGE_FlashControlOn = 0, + OMX_IMAGE_FlashControlOff, + OMX_IMAGE_FlashControlAuto, + OMX_IMAGE_FlashControlRedEyeReduction, + OMX_IMAGE_FlashControlFillin, + OMX_IMAGE_FlashControlTorch, + OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FlashControlMax = 0x7FFFFFFF +} OMX_IMAGE_FLASHCONTROLTYPE; + + +/** + * Flash control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFlashControl : Flash control type + */ +typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; +} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; + + +/** + * Focus control type + */ +typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { + OMX_IMAGE_FocusControlOn = 0, + OMX_IMAGE_FocusControlOff, + OMX_IMAGE_FocusControlAuto, + OMX_IMAGE_FocusControlAutoLock, + OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FocusControlMax = 0x7FFFFFFF +} OMX_IMAGE_FOCUSCONTROLTYPE; + + +/** + * Focus control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusControl : Focus control + * nFocusSteps : Focus can take on values from 0 mm to infinity. + * Interest is only in number of steps over this range. + * nFocusStepIndex : Current focus step index + */ +typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; + OMX_U32 nFocusSteps; + OMX_U32 nFocusStepIndex; +} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; + + +/** + * Q Factor for JPEG compression, which controls the tradeoff between image + * quality and size. Q Factor provides a more simple means of controlling + * JPEG compression quality, without directly programming Quantization + * tables for chroma and luma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 + * produces the smallest, worst quality images, and a factor + * of 100 produces the largest, best quality images. A + * typical default is 75 for small good quality images + */ +typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQFactor; +} OMX_IMAGE_PARAM_QFACTORTYPE; + +/** + * Quantization table type + */ + +typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { + OMX_IMAGE_QuantizationTableLuma = 0, + OMX_IMAGE_QuantizationTableChroma, + OMX_IMAGE_QuantizationTableChromaCb, + OMX_IMAGE_QuantizationTableChromaCr, + OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF +} OMX_IMAGE_QUANTIZATIONTABLETYPE; + +/** + * JPEG quantization tables are used to determine DCT compression for + * YUV data, as an alternative to specifying Q factor, providing exact + * control of compression + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eQuantizationTable : Quantization table type + * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored + * in increasing columns then by rows of data (i.e. + * row 1, ... row 8). Quantization values are in + * the range 0-255 and stored in linear order + * (i.e. the component will zig-zag the + * quantization table data if required internally) + */ +typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; + OMX_U8 nQuantizationMatrix[64]; +} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; + + +/** + * Huffman table type, the same Huffman table is applied for chroma and + * luma component + */ +typedef enum OMX_IMAGE_HUFFMANTABLETYPE { + OMX_IMAGE_HuffmanTableAC = 0, + OMX_IMAGE_HuffmanTableDC, + OMX_IMAGE_HuffmanTableACLuma, + OMX_IMAGE_HuffmanTableACChroma, + OMX_IMAGE_HuffmanTableDCLuma, + OMX_IMAGE_HuffmanTableDCChroma, + OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF +} OMX_IMAGE_HUFFMANTABLETYPE; + +/** + * JPEG Huffman table + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eHuffmanTable : Huffman table type + * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each + * possible length + * nHuffmanTable[256] : 0-255, the size used for AC and DC + * HuffmanTable are 16 and 162 + */ +typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; + OMX_U8 nNumberOfHuffmanCodeOfLength[16]; + OMX_U8 nHuffmanTable[256]; +}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Index.h b/exynos/multimedia/openmax/include/khronos/OMX_Index.h new file mode 100644 index 0000000..44d4ea7 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Index.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** @file OMX_Index.h - OpenMax IL version 1.1.2 + * The OMX_Index header file contains the definitions for both applications + * and components . + */ + + +#ifndef OMX_Index_h +#define OMX_Index_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + + +/** The OMX_INDEXTYPE enumeration is used to select a structure when either + * getting or setting parameters and/or configuration data. Each entry in + * this enumeration maps to an OMX specified structure. When the + * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods + * are used, the second parameter will always be an entry from this enumeration + * and the third entry will be the structure shown in the comments for the entry. + * For example, if the application is initializing a cropping function, the + * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter + * and would send a pointer to an initialized OMX_RECTTYPE structure as the + * third parameter. + * + * The enumeration entries named with the OMX_Config prefix are sent using + * the OMX_SetConfig command and the enumeration entries named with the + * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. + */ +typedef enum OMX_INDEXTYPE { + + OMX_IndexComponentStartUnused = 0x01000000, + OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ + OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ + OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ + OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ + OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ + OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ + OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ + OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ + OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ + OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ + OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ + + OMX_IndexPortStartUnused = 0x02000000, + OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ + OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ + OMX_IndexReservedStartUnused = 0x03000000, + + /* Audio parameters and configurations */ + OMX_IndexAudioStartUnused = 0x04000000, + OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ + OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ + OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ + OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ + OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ + OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ + OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ + OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ + OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ + OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ + OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ + OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ + OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ + OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ + OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ + OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ + OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ + OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ + OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ + OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ + OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ + OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ + OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ + OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ + OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ + + OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ + OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ + OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ + OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ + OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ + OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ + OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ + OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ + OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ + OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ + OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ + OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ + OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ + OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ + OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ + OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ + OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ + OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ + OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ + OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ + + /* Image specific parameters and configurations */ + OMX_IndexImageStartUnused = 0x05000000, + OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ + OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ + OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ + OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ + OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ + OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + + /* Video specific parameters and configurations */ + OMX_IndexVideoStartUnused = 0x06000000, + OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ + OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ + OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ + OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ + OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ + OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ + OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ + OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ + OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ + OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ + OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ + OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ + OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ + OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ + OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ + OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ + OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ + OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ + OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ + OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ + OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ + + /* Image & Video common Configurations */ + OMX_IndexCommonStartUnused = 0x07000000, + OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ + OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ + OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ + OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ + OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ + OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ + OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ + OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ + OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ + OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ + OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ + OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ + OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ + OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ + OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ + OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ + OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ + OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ + OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ + OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ + OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ + OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ + OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ + OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ + OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ + OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ + OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ + OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ + OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ + + /* Reserved Configuration range */ + OMX_IndexOtherStartUnused = 0x08000000, + OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ + OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ + OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ + + + /* Reserved Time range */ + OMX_IndexTimeStartUnused = 0x09000000, + OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ + OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ + OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ + OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ + OMX_IndexConfigTimeClientStartTime, /** + + +/** + * Enumeration of possible data types which match to multiple domains or no + * domain at all. For types which are vendor specific, a value above + * OMX_OTHER_VENDORTSTART should be used. + */ +typedef enum OMX_OTHER_FORMATTYPE { + OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, + time deltas, etc */ + OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power + management, setting clocks? */ + OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames + dropped, etc */ + OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ + OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific + formats */ + + OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_OTHER_FormatMax = 0x7FFFFFFF +} OMX_OTHER_FORMATTYPE; + +/** + * Enumeration of seek modes. + */ +typedef enum OMX_TIME_SEEKMODETYPE { + OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation + * of the requested seek position over + * the actual seek position if it + * results in a faster seek. */ + OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek + * position over an approximation + * of the requested seek position even + * if it results in a slower seek. */ + OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_SeekModeMax = 0x7FFFFFFF +} OMX_TIME_SEEKMODETYPE; + +/* Structure representing the seekmode of the component */ +typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ +} OMX_TIME_CONFIG_SEEKMODETYPE; + +/** Structure representing a time stamp used with the following configs + * on the Clock Component (CC): + * + * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall + * time + * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media + * time + * OMX_IndexConfigTimeCurrentAudioReference and + * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference + * clock sending SC its reference time + * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends + * this structure to the Clock Component via a SetConfig on its + * client port when it receives a buffer with + * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp + * specified by that buffer for nStartTimestamp. + * + * It’s also used with the following config on components in general: + * + * OMX_IndexConfigTimePosition: IL client querying component position + * (GetConfig) or commanding a component to seek to the given location + * (SetConfig) + */ +typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_TICKS nTimestamp; /**< timestamp .*/ +} OMX_TIME_CONFIG_TIMESTAMPTYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_UPDATETYPE { + OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ + OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ + OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ + OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_UpdateMax = 0x7FFFFFFF +} OMX_TIME_UPDATETYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_REFCLOCKTYPE { + OMX_TIME_RefClockNone, /**< Use no references. */ + OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ + OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ + OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_RefClockMax = 0x7FFFFFFF +} OMX_TIME_REFCLOCKTYPE; + +/** Enumeration of clock states. */ +typedef enum OMX_TIME_CLOCKSTATE { + OMX_TIME_ClockStateRunning, /**< Clock running. */ + OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the + * prescribed clients emit their + * start time. */ + OMX_TIME_ClockStateStopped, /**< Clock stopped. */ + OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_ClockStateMax = 0x7FFFFFFF +} OMX_TIME_CLOCKSTATE; + +/** Structure representing a media time request to the clock component. + * + * A client component sends this structure to the Clock Component via a SetConfig + * on its client port to specify a media timestamp the Clock Component + * should emit. The Clock Component should fulfill the request by sending a + * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested + * timestamp. + * + * The client may require a media time request be fulfilled slightly + * earlier than the media time specified. In this case the client specifies + * an offset which is equal to the difference between wall time corresponding + * to the requested media time and the wall time when it will be + * fulfilled. + * + * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to + * time events according to timestamps. If a client must perform an operation O at + * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a + * media time request at T (perhaps specifying an offset to ensure the request fulfillment + * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE + * structure back to the client component, the client may perform operation O (perhaps having + * to wait a slight amount more time itself as specified by the return values). + */ + +typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time + * from others (e.g. the number of the frame to deliver). + * Duplicated in the media time structure that fulfills + * this request. A value of zero is reserved for time scale + * updates. */ + OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request should be fulfilled early */ +} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; + +/**< Structure sent from the clock component client either when fulfilling + * a media time request or when the time scale has changed. + * + * In the former case the Clock Component fills this structure and times its emission + * to a client component (via the client port) according to the corresponding media + * time request sent by the client. The Clock Component should time the emission to occur + * when the requested timestamp matches the Clock Component's media time but also the + * prescribed offset early. + * + * Upon scale changes the clock component clears the nClientPrivate data, sends the current + * media time and sets the nScale to the new scale via the client port. It emits a + * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to + * alter processing to accomodate scaling. For instance a video component might skip inter-frames + * in the case of extreme fastforward. Likewise an audio component might add or remove samples + * from an audio frame to scale audio data. + * + * It is expected that some clock components may not be able to fulfill requests + * at exactly the prescribed time. This is acceptable so long as the request is + * fulfilled at least as early as described and not later. This structure provides + * fields the client may use to wait for the remaining time. + * + * The client may use either the nOffset or nWallTimeAtMedia fields to determine the + * wall time until the nMediaTimestamp actually occurs. In the latter case the + * client can get a more accurate value for offset by getting the current wall + * from the cloc component and subtracting it from nWallTimeAtMedia. + */ + +typedef struct OMX_TIME_MEDIATIMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time + * from others. Copied from the media time request. + * A value of zero is reserved for time scale updates. */ + OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ + OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was + * requested then this is the current media time. */ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request was actually fulfilled early */ + + OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. + * A client may compare this value to current + * media time obtained from the Clock Component to determine + * the wall time until the media timestamp is really + * current. */ + OMX_S32 xScale; /**< Current media time scale in Q16 format. */ + OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ + /**< State of the media time. */ +} OMX_TIME_MEDIATIMETYPE; + +/** Structure representing the current media time scale factor. Applicable only to clock + * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via + * the clock component client ports. Upon recieving this config the clock component changes + * the rate by which the media time increases or decreases effectively implementing trick modes. + */ +typedef struct OMX_TIME_CONFIG_SCALETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 xScale; /**< This is a value in Q16 format which is used for + * scaling the media time */ +} OMX_TIME_CONFIG_SCALETYPE; + +/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */ +#define OMX_CLOCKPORT0 0x00000001 +#define OMX_CLOCKPORT1 0x00000002 +#define OMX_CLOCKPORT2 0x00000004 +#define OMX_CLOCKPORT3 0x00000008 +#define OMX_CLOCKPORT4 0x00000010 +#define OMX_CLOCKPORT5 0x00000020 +#define OMX_CLOCKPORT6 0x00000040 +#define OMX_CLOCKPORT7 0x00000080 + +/** Structure representing the current mode of the media clock. + * IL Client uses this config to change or query the mode of the + * media clock of the clock component. Applicable only to clock + * component. + * + * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time + * starts immediately at the prescribed start time. If + * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores + * the given nStartTime and waits for all clients specified in the + * nWaitMask to send starttimes (via + * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts + * the media clock using the earliest start time supplied. */ +typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ + OMX_TICKS nStartTime; /**< Start time of the media time. */ + OMX_TICKS nOffset; /**< Time to offset the media time by + * (e.g. preroll). Media time will be + * reported to be nOffset ticks earlier. + */ + OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ +} OMX_TIME_CONFIG_CLOCKSTATETYPE; + +/** Structure representing the reference clock currently being used to + * compute media time. IL client uses this config to change or query the + * clock component's active reference clock */ +typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ +} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; + +/** Descriptor for setting specifics of power type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_POWERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ +} OMX_OTHER_CONFIG_POWERTYPE; + + +/** Descriptor for setting specifics of stats type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_STATSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + /* what goes here */ +} OMX_OTHER_CONFIG_STATSTYPE; + + +/** + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output other + * path. + */ +typedef struct OMX_OTHER_PORTDEFINITIONTYPE { + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PORTDEFINITIONTYPE; + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PARAM_PORTFORMATTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Types.h b/exynos/multimedia/openmax/include/khronos/OMX_Types.h new file mode 100644 index 0000000..31be916 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Types.h @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** OMX_Types.h - OpenMax IL version 1.1.2 + * The OMX_Types header file contains the primitive type definitions used by + * the core, the application and the component. This file may need to be + * modified to be used on systems that do not have "char" set to 8 bits, + * "short" set to 16 bits and "long" set to 32 bits. + */ + +#ifndef OMX_Types_h +#define OMX_Types_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** The OMX_API and OMX_APIENTRY are platform specific definitions used + * to declare OMX function prototypes. They are modified to meet the + * requirements for a particular platform */ +#ifdef __SYMBIAN32__ +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# ifdef _WIN32 +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# endif +#else +# ifdef _WIN32 +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# else +# ifdef __OMX_EXPORTS +# define OMX_API +# else +# define OMX_API extern +# endif +# endif +#endif + +#ifndef OMX_APIENTRY +#define OMX_APIENTRY +#endif + +/** OMX_IN is used to identify inputs to an OMX function. This designation + will also be used in the case of a pointer that points to a parameter + that is used as an output. */ +#ifndef OMX_IN +#define OMX_IN +#endif + +/** OMX_OUT is used to identify outputs from an OMX function. This + designation will also be used in the case of a pointer that points + to a parameter that is used as an input. */ +#ifndef OMX_OUT +#define OMX_OUT +#endif + + +/** OMX_INOUT is used to identify parameters that may be either inputs or + outputs from an OMX function at the same time. This designation will + also be used in the case of a pointer that points to a parameter that + is used both as an input and an output. */ +#ifndef OMX_INOUT +#define OMX_INOUT +#endif + +/** OMX_ALL is used to as a wildcard to select all entities of the same type + * when specifying the index, or referring to a object by an index. (i.e. + * use OMX_ALL to indicate all N channels). When used as a port index + * for a config or parameter this OMX_ALL denotes that the config or + * parameter applies to the entire component not just one port. */ +#define OMX_ALL 0xFFFFFFFF + +/** In the following we define groups that help building doxygen documentation */ + +/** @defgroup core OpenMAX IL core + * Functions and structure related to the OMX IL core + */ + + /** @defgroup comp OpenMAX IL component + * Functions and structure related to the OMX IL component + */ + +/** @defgroup rpm Resource and Policy Management + * Structures for resource and policy management of components + */ + +/** @defgroup buf Buffer Management + * Buffer handling functions and structures + */ + +/** @defgroup tun Tunneling + * @ingroup core comp + * Structures and functions to manage tunnels among component ports + */ + +/** @defgroup cp Content Pipes + * @ingroup core + */ + + /** @defgroup metadata Metadata handling + * + */ + +/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ +typedef unsigned char OMX_U8; + +/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ +typedef signed char OMX_S8; + +/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ +typedef unsigned short OMX_U16; + +/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ +typedef signed short OMX_S16; + +/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ +typedef unsigned long OMX_U32; + +/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ +typedef signed long OMX_S32; + + +/* Users with compilers that cannot accept the "long long" designation should + define the OMX_SKIP64BIT macro. It should be noted that this may cause + some components to fail to compile if the component was written to require + 64 bit integral types. However, these components would NOT compile anyway + since the compiler does not support the way the component was written. +*/ +#ifndef OMX_SKIP64BIT +#ifdef __SYMBIAN32__ +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#elif defined(WIN32) + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned __int64 OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed __int64 OMX_S64; + +#else /* WIN32 */ + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#endif /* WIN32 */ +#endif + + +/** The OMX_BOOL type is intended to be used to represent a true or a false + value when passing parameters to and from the OMX core and components. The + OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. + */ +typedef enum OMX_BOOL { + OMX_FALSE = 0, + OMX_TRUE = !OMX_FALSE, + OMX_BOOL_MAX = 0x7FFFFFFF +} OMX_BOOL; + +/** The OMX_PTR type is intended to be used to pass pointers between the OMX + applications and the OMX Core and components. This is a 32 bit pointer and + is aligned on a 32 bit boundary. + */ +typedef void* OMX_PTR; + +/** The OMX_STRING type is intended to be used to pass "C" type strings between + the application and the core and component. The OMX_STRING type is a 32 + bit pointer to a zero terminated string. The pointer is word aligned and + the string is byte aligned. + */ +typedef char* OMX_STRING; + +/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as + buffers between the application and the component and core. The OMX_BYTE + type is a 32 bit pointer to a zero terminated string. The pointer is word + aligned and the string is byte aligned. + */ +typedef unsigned char* OMX_BYTE; + +/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify + at runtime. This identifier should be generated by a component in a way + that guarantees that every instance of the identifier running on the system + is unique. */ +typedef unsigned char OMX_UUIDTYPE[128]; + +/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or + an output port. This enumeration is common across all component types. + */ +typedef enum OMX_DIRTYPE +{ + OMX_DirInput, /**< Port is an input port */ + OMX_DirOutput, /**< Port is an output port */ + OMX_DirMax = 0x7FFFFFFF +} OMX_DIRTYPE; + +/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering + for numerical data (i.e. big endian, or little endian). + */ +typedef enum OMX_ENDIANTYPE +{ + OMX_EndianBig, /**< big endian */ + OMX_EndianLittle, /**< little endian */ + OMX_EndianMax = 0x7FFFFFFF +} OMX_ENDIANTYPE; + + +/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data + is signed or unsigned + */ +typedef enum OMX_NUMERICALDATATYPE +{ + OMX_NumericalDataSigned, /**< signed data */ + OMX_NumericalDataUnsigned, /**< unsigned data */ + OMX_NumercialDataMax = 0x7FFFFFFF +} OMX_NUMERICALDATATYPE; + + +/** Unsigned bounded value type */ +typedef struct OMX_BU32 { + OMX_U32 nValue; /**< actual value */ + OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BU32; + + +/** Signed bounded value type */ +typedef struct OMX_BS32 { + OMX_S32 nValue; /**< actual value */ + OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BS32; + + +/** Structure representing some time or duration in microseconds. This structure + * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate + * negative deltas and preroll scenarios. The quantity is represented in microseconds + * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based + * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. + * individual audio samples delivered at 192 kHz). The quantity is 64 bit to + * accommodate a large dynamic range (signed 32 bit values would allow only for plus + * or minus 35 minutes). + * + * Implementations with limited precision may convert the signed 64 bit value to + * a signed 32 bit value internally but risk loss of precision. + */ +#ifndef OMX_SKIP64BIT +typedef OMX_S64 OMX_TICKS; +#else +typedef struct OMX_TICKS +{ + OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ + OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ +} OMX_TICKS; +#endif +#define OMX_TICKS_PER_SECOND 1000000 + +/** Define the public interface for the OMX Handle. The core will not use + this value internally, but the application should only use this value. + */ +typedef void* OMX_HANDLETYPE; + +typedef struct OMX_MARKTYPE +{ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will + generate a mark event upon + processing the mark. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ +} OMX_MARKTYPE; + + +/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the display + * or can be used by a audio port for native audio rendering */ +typedef void* OMX_NATIVE_DEVICETYPE; + +/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the window */ +typedef void* OMX_NATIVE_WINDOWTYPE; + +/** The OMX_VERSIONTYPE union is used to specify the version for + a structure or component. For a component, the version is entirely + specified by the component vendor. Components doing the same function + from different vendors may or may not have the same version. For + structures, the version shall be set by the entity that allocates the + structure. For structures specified in the OMX 1.1 specification, the + value of the version shall be set to 1.1.0.0 in all cases. Access to the + OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or + by accessing one of the structure elements to, for example, check only + the Major revision. + */ +typedef union OMX_VERSIONTYPE +{ + struct + { + OMX_U8 nVersionMajor; /**< Major version accessor element */ + OMX_U8 nVersionMinor; /**< Minor version accessor element */ + OMX_U8 nRevision; /**< Revision version accessor element */ + OMX_U8 nStep; /**< Step version accessor element */ + } s; + OMX_U32 nVersion; /**< 32 bit value to make accessing the + version easily done in a single word + size copy/compare operation */ +} OMX_VERSIONTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/exynos/multimedia/openmax/include/khronos/OMX_Video.h b/exynos/multimedia/openmax/include/khronos/OMX_Video.h new file mode 100644 index 0000000..163e450 --- /dev/null +++ b/exynos/multimedia/openmax/include/khronos/OMX_Video.h @@ -0,0 +1,1060 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** + * @file OMX_Video.h - OpenMax IL version 1.1.2 + * The structures is needed by Video components to exchange parameters + * and configuration data with OMX components. + */ +#ifndef OMX_Video_h +#define OMX_Video_h + +/** @defgroup video OpenMAX IL Video Domain + * @ingroup iv + * Structures for OpenMAX IL Video domain + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +typedef enum OMX_VIDEO_CODINGTYPE { + OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_VIDEO_CodingH263, /**< H.263 */ + OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ + OMX_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_VIDEO_CODINGTYPE; + + +/** + * Data structure used to define a video path. The number of Video paths for + * input and output will vary by type of the Video component. + * + * Input (aka Source) : zero Inputs, one Output, + * Splitter : one Input, 2 or more Outputs, + * Processing Element : one Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : one Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output video + * path. If additional vendor specific data is required, it should be + * transmitted to the component using the CustomCommand function. Compliant + * components will prepopulate this structure with optimal values during the + * GetDefaultInitParams command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nFrameHeight : Height of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nStride : Number of bytes per span of an image + * (i.e. indicates the number of bytes to get + * from span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * nBitrate : Bit rate of frame to be used on channel if + * compressed format is used. Use 0 for unknown, + * don't care or variable + * xFramerate : Frame rate to be used on channel if uncompressed + * format is used. Use 0 for unknown, don't care or + * variable. Units are Q16 frames per second. + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is + * specified, eColorFormat is used + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_U32 nBitrate; + OMX_U32 xFramerate; + OMX_BOOL bFlagErrorConcealment; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_VIDEO_PORTDEFINITIONTYPE; + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is specified, + * eColorFormat is used + * eColorFormat : Decompressed format used by this component + * xFrameRate : Indicates the video frame rate in Q16 format + */ +typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 xFramerate; +} OMX_VIDEO_PARAM_PORTFORMATTYPE; + + +/** + * This is a structure for configuring video compression quantization + * parameter values. Codecs may support different QP values for different + * frame types. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nQpI : QP value to use for index frames + * nQpP : QP value to use for P frames + * nQpB : QP values to use for bidirectional frames + */ +typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQpI; + OMX_U32 nQpP; + OMX_U32 nQpB; +} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; + + +/** + * Structure for configuration of video fast update parameters. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * bEnableVFU : Enable/Disable video fast update + * nFirstGOB : Specifies the number of the first macroblock row + * nFirstMB : specifies the first MB relative to the specified first GOB + * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB + * and nFirstMB + */ +typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableVFU; + OMX_U32 nFirstGOB; + OMX_U32 nFirstMB; + OMX_U32 nNumMBs; +} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; + + +/** + * Enumeration of possible bitrate control types + */ +typedef enum OMX_VIDEO_CONTROLRATETYPE { + OMX_Video_ControlRateDisable, + OMX_Video_ControlRateVariable, + OMX_Video_ControlRateConstant, + OMX_Video_ControlRateVariableSkipFrames, + OMX_Video_ControlRateConstantSkipFrames, + OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_ControlRateMax = 0x7FFFFFFF +} OMX_VIDEO_CONTROLRATETYPE; + + +/** + * Structure for configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * eControlRate : Control rate type enum + * nTargetBitrate : Target bitrate to encode with + */ +typedef struct OMX_VIDEO_PARAM_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_CONTROLRATETYPE eControlRate; + OMX_U32 nTargetBitrate; +} OMX_VIDEO_PARAM_BITRATETYPE; + + +/** + * Enumeration of possible motion vector (MV) types + */ +typedef enum OMX_VIDEO_MOTIONVECTORTYPE { + OMX_Video_MotionVectorPixel, + OMX_Video_MotionVectorHalfPel, + OMX_Video_MotionVectorQuarterPel, + OMX_Video_MotionVectorEighthPel, + OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_MotionVectorMax = 0x7FFFFFFF +} OMX_VIDEO_MOTIONVECTORTYPE; + + +/** + * Structure for configuring the number of motion vectors used as well + * as their accuracy. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : port that this structure applies to + * eAccuracy : Enumerated MV accuracy + * bUnrestrictedMVs : Allow unrestricted MVs + * bFourMV : Allow use of 4 MVs + * sXSearchRange : Search range in horizontal direction for MVs + * sYSearchRange : Search range in vertical direction for MVs + */ +typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; + OMX_BOOL bUnrestrictedMVs; + OMX_BOOL bFourMV; + OMX_S32 sXSearchRange; + OMX_S32 sYSearchRange; +} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; + + +/** + * Enumeration of possible methods to use for Intra Refresh + */ +typedef enum OMX_VIDEO_INTRAREFRESHTYPE { + OMX_VIDEO_IntraRefreshCyclic, + OMX_VIDEO_IntraRefreshAdaptive, + OMX_VIDEO_IntraRefreshBoth, + OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF +} OMX_VIDEO_INTRAREFRESHTYPE; + + +/** + * Structure for configuring intra refresh mode + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eRefreshMode : Cyclic, Adaptive, or Both + * nAirMBs : Number of intra macroblocks to refresh in a frame when + * AIR is enabled + * nAirRef : Number of times a motion marked macroblock has to be + * intra coded + * nCirMBs : Number of consecutive macroblocks to be coded as "intra" + * when CIR is enabled + */ +typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; + OMX_U32 nAirMBs; + OMX_U32 nAirRef; + OMX_U32 nCirMBs; +} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; + + +/** + * Structure for enabling various error correction methods for video + * compression. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnableHEC : Enable/disable header extension codes (HEC) + * bEnableResync : Enable/disable resynchronization markers + * nResynchMarkerSpacing : Resynch markers interval (in bits) to be + * applied in the stream + * bEnableDataPartitioning : Enable/disable data partitioning + * bEnableRVLC : Enable/disable reversible variable length + * coding + */ +typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableHEC; + OMX_BOOL bEnableResync; + OMX_U32 nResynchMarkerSpacing; + OMX_BOOL bEnableDataPartitioning; + OMX_BOOL bEnableRVLC; +} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; + + +/** + * Configuration of variable block-size motion compensation (VBSMC) + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * b16x16 : Enable inter block search 16x16 + * b16x8 : Enable inter block search 16x8 + * b8x16 : Enable inter block search 8x16 + * b8x8 : Enable inter block search 8x8 + * b8x4 : Enable inter block search 8x4 + * b4x8 : Enable inter block search 4x8 + * b4x4 : Enable inter block search 4x4 + */ +typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL b16x16; + OMX_BOOL b16x8; + OMX_BOOL b8x16; + OMX_BOOL b8x8; + OMX_BOOL b8x4; + OMX_BOOL b4x8; + OMX_BOOL b4x4; +} OMX_VIDEO_PARAM_VBSMCTYPE; + + +/** + * H.263 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * Baseline : Baseline Profile: H.263 (V1), no optional modes + * H320 Coding : H.320 Coding Efficiency Backward Compatibility + * Profile: H.263+ (V2), includes annexes I, J, L.4 + * and T + * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), + * includes annex F + * ISWV2 : Interactive Streaming Wireless Profile: H.263+ + * (V2), includes annexes I, J, K and T + * ISWV3 : Interactive Streaming Wireless Profile: H.263++ + * (V3), includes profile 3 and annexes V and W.6.3.8 + * HighCompression : Conversational High Compression Profile: H.263++ + * (V3), includes profiles 1 & 2 and annexes D and U + * Internet : Conversational Internet Profile: H.263++ (V3), + * includes profile 5 and annex K + * Interlace : Conversational Interlace Profile: H.263++ (V3), + * includes profile 5 and annex W.6.3.11 + * HighLatency : High Latency Profile: H.263++ (V3), includes + * profile 6 and annexes O.1 and P.5 + */ +typedef enum OMX_VIDEO_H263PROFILETYPE { + OMX_VIDEO_H263ProfileBaseline = 0x01, + OMX_VIDEO_H263ProfileH320Coding = 0x02, + OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, + OMX_VIDEO_H263ProfileISWV2 = 0x08, + OMX_VIDEO_H263ProfileISWV3 = 0x10, + OMX_VIDEO_H263ProfileHighCompression = 0x20, + OMX_VIDEO_H263ProfileInternet = 0x40, + OMX_VIDEO_H263ProfileInterlace = 0x80, + OMX_VIDEO_H263ProfileHighLatency = 0x100, + OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_H263PROFILETYPE; + + +/** + * H.263 level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. + */ +typedef enum OMX_VIDEO_H263LEVELTYPE { + OMX_VIDEO_H263Level10 = 0x01, + OMX_VIDEO_H263Level20 = 0x02, + OMX_VIDEO_H263Level30 = 0x04, + OMX_VIDEO_H263Level40 = 0x08, + OMX_VIDEO_H263Level45 = 0x10, + OMX_VIDEO_H263Level50 = 0x20, + OMX_VIDEO_H263Level60 = 0x40, + OMX_VIDEO_H263Level70 = 0x80, + OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263LevelMax = 0x7FFFFFFF +} OMX_VIDEO_H263LEVELTYPE; + + +/** + * Specifies the picture type. These values should be OR'd to signal all + * pictures types which are allowed. + * + * ENUMS: + * Generic Picture Types: I, P and B + * H.263 Specific Picture Types: SI and SP + * H.264 Specific Picture Types: EI and EP + * MPEG-4 Specific Picture Types: S + */ +typedef enum OMX_VIDEO_PICTURETYPE { + OMX_VIDEO_PictureTypeI = 0x01, + OMX_VIDEO_PictureTypeP = 0x02, + OMX_VIDEO_PictureTypeB = 0x04, + OMX_VIDEO_PictureTypeSI = 0x08, + OMX_VIDEO_PictureTypeSP = 0x10, + OMX_VIDEO_PictureTypeEI = 0x11, + OMX_VIDEO_PictureTypeEP = 0x12, + OMX_VIDEO_PictureTypeS = 0x14, + OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF +} OMX_VIDEO_PICTURETYPE; + + +/** + * H.263 Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : H.263 profile(s) to use + * eLevel : H.263 level(s) to use + * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE + * (specified in the 1998 version of H.263) to + * indicate custom picture sizes or clock + * frequencies + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is + * not constrained. It is recommended to change + * the value of the RTYPE bit for each reference + * picture in error-free communication + * nPictureHeaderRepetition : Specifies the frequency of picture header + * repetition + * nGOBHeaderInterval : Specifies the interval of non-empty GOB + * headers in units of GOBs + */ +typedef struct OMX_VIDEO_PARAM_H263TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_H263PROFILETYPE eProfile; + OMX_VIDEO_H263LEVELTYPE eLevel; + OMX_BOOL bPLUSPTYPEAllowed; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bForceRoundingTypeToZero; + OMX_U32 nPictureHeaderRepetition; + OMX_U32 nGOBHeaderInterval; +} OMX_VIDEO_PARAM_H263TYPE; + + +/** + * MPEG-2 profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_MPEG2PROFILETYPE { + OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ + OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ + OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ + OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ + OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ + OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ + OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2PROFILETYPE; + + +/** + * MPEG-2 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG2LEVELTYPE { + OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ + OMX_VIDEO_MPEG2LevelML, /**< Main Level */ + OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ + OMX_VIDEO_MPEG2LevelHL, /**< High Level */ + OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2LEVELTYPE; + + +/** + * MPEG-2 params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : MPEG-2 profile(s) to use + * eLevel : MPEG-2 levels(s) to use + */ +typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_MPEG2PROFILETYPE eProfile; + OMX_VIDEO_MPEG2LEVELTYPE eLevel; +} OMX_VIDEO_PARAM_MPEG2TYPE; + + +/** + * MPEG-4 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * - Simple Profile, Levels 1-3 + * - Simple Scalable Profile, Levels 1-2 + * - Core Profile, Levels 1-2 + * - Main Profile, Levels 2-4 + * - N-bit Profile, Level 2 + * - Scalable Texture Profile, Level 1 + * - Simple Face Animation Profile, Levels 1-2 + * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 + * - Basic Animated Texture Profile, Levels 1-2 + * - Hybrid Profile, Levels 1-2 + * - Advanced Real Time Simple Profiles, Levels 1-4 + * - Core Scalable Profile, Levels 1-3 + * - Advanced Coding Efficiency Profile, Levels 1-4 + * - Advanced Core Profile, Levels 1-2 + * - Advanced Scalable Texture, Levels 2-3 + */ +typedef enum OMX_VIDEO_MPEG4PROFILETYPE { + OMX_VIDEO_MPEG4ProfileSimple = 0x01, + OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, + OMX_VIDEO_MPEG4ProfileCore = 0x04, + OMX_VIDEO_MPEG4ProfileMain = 0x08, + OMX_VIDEO_MPEG4ProfileNbit = 0x10, + OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, + OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, + OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, + OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, + OMX_VIDEO_MPEG4ProfileHybrid = 0x200, + OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, + OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, + OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, + OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, + OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, + OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, + OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4PROFILETYPE; + + +/** + * MPEG-4 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG4LEVELTYPE { + OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ + OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ + OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ + OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ + OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ + OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ + OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ + OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ + OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4LEVELTYPE; + + +/** + * MPEG-4 configuration. This structure handles configuration options + * which are specific to MPEG4 algorithms + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ + * Annex K). Put zero if not used + * bSVH : Enable Short Video Header mode + * bGov : Flag to enable GOV + * nPFrames : Number of P frames between each I frame (also called + * GOV period) + * nBFrames : Number of B frames between each I frame + * nIDCVLCThreshold : Value of intra DC VLC threshold + * bACPred : Flag to use ac prediction + * nMaxPacketSize : Maximum size of packet in bytes. + * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. + * Interpreted as described in MPEG4 standard. + * eProfile : MPEG-4 profile(s) to use. + * eLevel : MPEG-4 level(s) to use. + * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream + * nHeaderExtension : Specifies the number of consecutive video packet + * headers within a VOP + * bReversibleVLC : Specifies whether reversible variable length coding + * is in use + */ +typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_BOOL bSVH; + OMX_BOOL bGov; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_U32 nIDCVLCThreshold; + OMX_BOOL bACPred; + OMX_U32 nMaxPacketSize; + OMX_U32 nTimeIncRes; + OMX_VIDEO_MPEG4PROFILETYPE eProfile; + OMX_VIDEO_MPEG4LEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_U32 nHeaderExtension; + OMX_BOOL bReversibleVLC; +} OMX_VIDEO_PARAM_MPEG4TYPE; + + +/** + * WMV Versions + */ +typedef enum OMX_VIDEO_WMVFORMATTYPE { + OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ + OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ + OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ + OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ + OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_WMVFORMATTYPE; + + +/** + * WMV Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of WMV stream / data + */ +typedef struct OMX_VIDEO_PARAM_WMVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_WMVFORMATTYPE eFormat; +} OMX_VIDEO_PARAM_WMVTYPE; + + +/** + * Real Video Version + */ +typedef enum OMX_VIDEO_RVFORMATTYPE { + OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ + OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ + OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ + OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ + OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_RVFORMATTYPE; + + +/** + * Real Video Params + * + * STUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of RV stream / data + * nBitsPerPixel : Bits per pixel coded in the frame + * nPaddedWidth : Padded width in pixel of a video frame + * nPaddedHeight : Padded Height in pixels of a video frame + * nFrameRate : Rate of video in frames per second + * nBitstreamFlags : Flags which internal information about the bitstream + * nBitstreamVersion : Bitstream version + * nMaxEncodeFrameSize: Max encoded frame size + * bEnablePostFilter : Turn on/off post filter + * bEnableTemporalInterpolation : Turn on/off temporal interpolation + * bEnableLatencyMode : When enabled, the decoder does not display a decoded + * frame until it has detected that no enhancement layer + * frames or dependent B frames will be coming. This + * detection usually occurs when a subsequent non-B + * frame is encountered + */ +typedef struct OMX_VIDEO_PARAM_RVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_RVFORMATTYPE eFormat; + OMX_U16 nBitsPerPixel; + OMX_U16 nPaddedWidth; + OMX_U16 nPaddedHeight; + OMX_U32 nFrameRate; + OMX_U32 nBitstreamFlags; + OMX_U32 nBitstreamVersion; + OMX_U32 nMaxEncodeFrameSize; + OMX_BOOL bEnablePostFilter; + OMX_BOOL bEnableTemporalInterpolation; + OMX_BOOL bEnableLatencyMode; +} OMX_VIDEO_PARAM_RVTYPE; + + +/** + * AVC profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_AVCPROFILETYPE { + OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ + OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ + OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ + OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ + OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ + OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ + OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ + OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_AVCPROFILETYPE; + + +/** + * AVC level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_AVCLEVELTYPE { + OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ + OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ + OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ + OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ + OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ + OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ + OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ + OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ + OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ + OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ + OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ + OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ + OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ + OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ + OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ + OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ + OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLEVELTYPE; + + +/** + * AVC loop filter modes + * + * OMX_VIDEO_AVCLoopFilterEnable : Enable + * OMX_VIDEO_AVCLoopFilterDisable : Disable + * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries + */ +typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { + OMX_VIDEO_AVCLoopFilterEnable = 0, + OMX_VIDEO_AVCLoopFilterDisable, + OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, + OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLOOPFILTERTYPE; + + +/** + * AVC params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header, put + * zero if not used + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * bUseHadamard : Enable/disable Hadamard transform + * nRefFrames : Max number of reference frames to use for inter + * motion search (1-16) + * nRefIdxTrailing : Pic param set ref frame index (index into ref + * frame buffer of trailing frames list), B frame + * support + * nRefIdxForward : Pic param set ref frame index (index into ref + * frame buffer of forward frames list), B frame + * support + * bEnableUEP : Enable/disable unequal error protection. This + * is only valid of data partitioning is enabled. + * bEnableFMO : Enable/disable flexible macroblock ordering + * bEnableASO : Enable/disable arbitrary slice ordering + * bEnableRS : Enable/disable sending of redundant slices + * eProfile : AVC profile(s) to use + * eLevel : AVC level(s) to use + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bFrameMBsOnly : specifies that every coded picture of the + * coded video sequence is a coded frame + * containing only frame macroblocks + * bMBAFF : Enable/disable switching between frame and + * field macroblocks within a picture + * bEntropyCodingCABAC : Entropy decoding method to be applied for the + * syntax elements for which two descriptors appear + * in the syntax tables + * bWeightedPPrediction : Enable/disable weighted prediction shall not + * be applied to P and SP slices + * nWeightedBipredicitonMode : Default weighted prediction is applied to B + * slices + * bconstIpred : Enable/disable intra prediction + * bDirect8x8Inference : Specifies the method used in the derivation + * process for luma motion vectors for B_Skip, + * B_Direct_16x16 and B_Direct_8x8 as specified + * in subclause 8.4.1.2 of the AVC spec + * bDirectSpatialTemporal : Flag indicating spatial or temporal direct + * mode used in B slice coding (related to + * bDirect8x8Inference) . Spatial direct mode is + * more common and should be the default. + * nCabacInitIdx : Index used to init CABAC contexts + * eLoopFilterMode : Enable/disable loop filter + */ +typedef struct OMX_VIDEO_PARAM_AVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_BOOL bUseHadamard; + OMX_U32 nRefFrames; + OMX_U32 nRefIdx10ActiveMinus1; + OMX_U32 nRefIdx11ActiveMinus1; + OMX_BOOL bEnableUEP; + OMX_BOOL bEnableFMO; + OMX_BOOL bEnableASO; + OMX_BOOL bEnableRS; + OMX_VIDEO_AVCPROFILETYPE eProfile; + OMX_VIDEO_AVCLEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bFrameMBsOnly; + OMX_BOOL bMBAFF; + OMX_BOOL bEntropyCodingCABAC; + OMX_BOOL bWeightedPPrediction; + OMX_U32 nWeightedBipredicitonMode; + OMX_BOOL bconstIpred ; + OMX_BOOL bDirect8x8Inference; + OMX_BOOL bDirectSpatialTemporal; + OMX_U32 nCabacInitIdc; + OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; +} OMX_VIDEO_PARAM_AVCTYPE; + +typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, + This parameter is valid only for + OMX_IndexParamVideoProfileLevelQuerySupported index, + For all other indices this parameter is to be ignored. */ +} OMX_VIDEO_PARAM_PROFILELEVELTYPE; + +/** + * Structure for dynamically configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * nEncodeBitrate : Target average bitrate to be generated in bps + */ +typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nEncodeBitrate; +} OMX_VIDEO_CONFIG_BITRATETYPE; + +/** + * Defines Encoder Frame Rate setting + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * xEncodeFramerate : Encoding framerate represented in Q16 format + */ +typedef struct OMX_CONFIG_FRAMERATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 xEncodeFramerate; /* Q16 format */ +} OMX_CONFIG_FRAMERATETYPE; + +typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL IntraRefreshVOP; +} OMX_CONFIG_INTRAREFRESHVOPTYPE; + +typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ + OMX_U8 ErrMap[1]; /* Error map hint */ +} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; + +typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnabled; +} OMX_CONFIG_MBERRORREPORTINGTYPE; + +typedef struct OMX_PARAM_MACROBLOCKSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nMacroblocks; +} OMX_PARAM_MACROBLOCKSTYPE; + +/** + * AVC Slice Mode modes + * + * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame + * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame + * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame + */ +typedef enum OMX_VIDEO_AVCSLICEMODETYPE { + OMX_VIDEO_SLICEMODE_AVCDefault = 0, + OMX_VIDEO_SLICEMODE_AVCMBSlice, + OMX_VIDEO_SLICEMODE_AVCByteSlice, + OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCSLICEMODETYPE; + +/** + * AVC FMO Slice Mode Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNumSliceGroups : Specifies the number of slice groups + * nSliceGroupMapType : Specifies the type of slice groups + * eSliceMode : Specifies the type of slice + */ +typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U8 nNumSliceGroups; + OMX_U8 nSliceGroupMapType; + OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; +} OMX_VIDEO_PARAM_AVCSLICEFMO; + +/** + * AVC IDR Period Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nIDRPeriod : Specifies periodicity of IDR frames + * nPFrames : Specifies internal of coding Intra frames + */ +typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIDRPeriod; + OMX_U32 nPFrames; +} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; + +/** + * AVC NAL Size Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNaluBytes : Specifies the NAL unit size + */ +typedef struct OMX_VIDEO_CONFIG_NALSIZE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNaluBytes; +} OMX_VIDEO_CONFIG_NALSIZE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/exynos/multimedia/openmax/include/sec/SEC_OMX_Def.h b/exynos/multimedia/openmax/include/sec/SEC_OMX_Def.h new file mode 100644 index 0000000..bf5fe52 --- /dev/null +++ b/exynos/multimedia/openmax/include/sec/SEC_OMX_Def.h @@ -0,0 +1,177 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Def.h + * @brief SEC_OMX specific define + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_DEF +#define SEC_OMX_DEF + +#include "OMX_Types.h" +#include "OMX_IVCommon.h" + +#define VERSIONMAJOR_NUMBER 1 +#define VERSIONMINOR_NUMBER 0 +#define REVISION_NUMBER 0 +#define STEP_NUMBER 0 + + +#define MAX_OMX_COMPONENT_NUM 20 +#define MAX_OMX_COMPONENT_ROLE_NUM 10 +#define MAX_OMX_COMPONENT_NAME_SIZE OMX_MAX_STRINGNAME_SIZE +#define MAX_OMX_COMPONENT_ROLE_SIZE OMX_MAX_STRINGNAME_SIZE +#define MAX_OMX_COMPONENT_LIBNAME_SIZE OMX_MAX_STRINGNAME_SIZE * 2 +#define MAX_OMX_MIMETYPE_SIZE OMX_MAX_STRINGNAME_SIZE + +#define MAX_TIMESTAMP 17 +#define MAX_FLAGS 17 + +#define SEC_OMX_INSTALL_PATH "/system/lib/omx/" + +typedef enum _SEC_CODEC_TYPE +{ + SW_CODEC, + HW_VIDEO_DEC_CODEC, + HW_VIDEO_ENC_CODEC, + HW_AUDIO_DEC_CODEC, + HW_AUDIO_ENC_CODEC +} SEC_CODEC_TYPE; + +typedef struct _SEC_OMX_PRIORITYMGMTTYPE +{ + OMX_U32 nGroupPriority; /* the value 0 represents the highest priority */ + /* for a group of components */ + OMX_U32 nGroupID; +} SEC_OMX_PRIORITYMGMTTYPE; + +typedef enum _SEC_OMX_INDEXTYPE +{ +#define SEC_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.ThumbnailMode" + OMX_IndexVendorThumbnailMode = 0x7F000001, +#define SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD "OMX.SEC.index.VideoIntraPeriod" + OMX_IndexConfigVideoIntraPeriod = 0x7F000002, + + /* for Android Native Window */ +#define SEC_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers" + OMX_IndexParamEnableAndroidBuffers = 0x7F000011, +#define SEC_INDEX_PARAM_GET_ANB "OMX.google.android.index.getAndroidNativeBufferUsage" + OMX_IndexParamGetAndroidNativeBuffer = 0x7F000012, +#define SEC_INDEX_PARAM_USE_ANB "OMX.google.android.index.useAndroidNativeBuffer" + OMX_IndexParamUseAndroidNativeBuffer = 0x7F000013, + /* for Android Store Metadata Inbuffer */ +#define SEC_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.google.android.index.storeMetaDataInBuffers" + OMX_IndexParamStoreMetaDataBuffer = 0x7F000014, + + /* for Android PV OpenCore*/ + OMX_COMPONENT_CAPABILITY_TYPE_INDEX = 0xFF7A347 +} SEC_OMX_INDEXTYPE; + +typedef enum _SEC_OMX_ERRORTYPE +{ + OMX_ErrorNoEOF = (OMX_S32) 0x90000001, + OMX_ErrorInputDataDecodeYet = (OMX_S32) 0x90000002, + OMX_ErrorInputDataEncodeYet = (OMX_S32) 0x90000003, + OMX_ErrorMFCInit = (OMX_S32) 0x90000004 +} SEC_OMX_ERRORTYPE; + +typedef enum _SEC_OMX_COMMANDTYPE +{ + SEC_OMX_CommandComponentDeInit = 0x7F000001, + SEC_OMX_CommandEmptyBuffer, + SEC_OMX_CommandFillBuffer +} SEC_OMX_COMMANDTYPE; + +typedef enum _SEC_OMX_TRANS_STATETYPE { + SEC_OMX_TransStateInvalid, + SEC_OMX_TransStateLoadedToIdle, + SEC_OMX_TransStateIdleToExecuting, + SEC_OMX_TransStateExecutingToIdle, + SEC_OMX_TransStateIdleToLoaded, + SEC_OMX_TransStateMax = 0X7FFFFFFF +} SEC_OMX_TRANS_STATETYPE; + +typedef enum _SEC_OMX_COLOR_FORMATTYPE { + OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */ + OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002, + OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003, + OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, /* 0x7FC00002 */ +#ifdef S3D_SUPPORT + OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR = 0x7FC00003, /* 0x7FC00003 */ + OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL = 0x7FC00004, /* 0x7FC00004 */ + OMX_SEC_COLOR_FormatNV12Tiled_TB_LR = 0x7FC00005, /* 0x7FC00005 */ + OMX_SEC_COLOR_FormatNV12Tiled_TB_RL = 0x7FC00006, /* 0x7FC00006 */ + OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR = 0x7FC00007, /* 0x7FC00007 */ + OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL = 0x7FC00008, /* 0x7FC00008 */ + OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR = 0x7FC00009, /* 0x7FC00009 */ + OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL = 0x7FC0000A, /* 0x7FC0000A */ + OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR = 0x7FC0000B, /* 0x7FC0000B */ + OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL = 0x7FC0000C, /* 0x7FC0000C */ + OMX_SEC_COLOR_FormatYUV420Planar_TB_LR = 0x7FC0000D, /* 0x7FC0000D */ + OMX_SEC_COLOR_FormatYUV420Planar_TB_RL = 0x7FC0000E, /* 0x7FC0000E */ +#endif + /* for Android Native Window */ + OMX_SEC_COLOR_FormatANBYUV420SemiPlanar = 0x100, + /* for Android SurfaceMediaSource*/ + OMX_COLOR_FormatAndroidOpaque = 0x7F000789 +}SEC_OMX_COLOR_FORMATTYPE; + +typedef enum _SEC_OMX_SUPPORTFORMAT_TYPE +{ + supportFormat_0 = 0x00, + supportFormat_1, + supportFormat_2, + supportFormat_3, + supportFormat_4, + supportFormat_5, + supportFormat_6, +} SEC_OMX_SUPPORTFORMAT_TYPE; + +/* for Android PV OpenCore*/ +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; + +typedef struct _SEC_OMX_VIDEO_PROFILELEVEL +{ + OMX_S32 profile; + OMX_S32 level; +} SEC_OMX_VIDEO_PROFILELEVEL; + +#define OMX_VIDEO_CodingVPX 0x09 /**< Google VPX, formerly known as On2 VP8 */ + +#ifndef __OMX_EXPORTS +#define __OMX_EXPORTS +#define SEC_EXPORT_REF __attribute__((visibility("default"))) +#define SEC_IMPORT_REF __attribute__((visibility("default"))) +#endif + +#endif diff --git a/exynos/multimedia/openmax/include/sec/SEC_OMX_Macros.h b/exynos/multimedia/openmax/include/sec/SEC_OMX_Macros.h new file mode 100644 index 0000000..853d0ac --- /dev/null +++ b/exynos/multimedia/openmax/include/sec/SEC_OMX_Macros.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Macros.h + * @brief Macros + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MACROS +#define SEC_OMX_MACROS + +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Memory.h" + + +/* + * MACROS + */ +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4) +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) + +#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \ + do { \ + SEC_OSAL_Memset((_struct_), 0, sizeof(_structType_)); \ + (_struct_)->nSize = sizeof(_structType_); \ + (_struct_)->nVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; \ + (_struct_)->nVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; \ + (_struct_)->nVersion.s.nRevision = REVISION_NUMBER; \ + (_struct_)->nVersion.s.nStep = STEP_NUMBER; \ + } while (0) + +/* + * Port Specific + */ +#define SEC_TUNNEL_ESTABLISHED 0x0001 +#define SEC_TUNNEL_IS_SUPPLIER 0x0002 + +#define CHECK_PORT_BEING_FLUSHED(port) (port->bIsPortFlushed == OMX_TRUE) +#define CHECK_PORT_BEING_DISABLED(port) (port->bIsPortDisabled == OMX_TRUE) +#define CHECK_PORT_ENABLED(port) (port->portDefinition.bEnabled == OMX_TRUE) +#define CHECK_PORT_POPULATED(port) (port->portDefinition.bPopulated == OMX_TRUE) +#define CHECK_PORT_TUNNELED(port) (port->tunnelFlags & SEC_TUNNEL_ESTABLISHED) +#define CHECK_PORT_BUFFER_SUPPLIER(port) (port->tunnelFlags & SEC_TUNNEL_IS_SUPPLIER) + +#endif diff --git a/exynos/multimedia/openmax/osal/Android.mk b/exynos/multimedia/openmax/osal/Android.mk new file mode 100644 index 0000000..e4ceba0 --- /dev/null +++ b/exynos/multimedia/openmax/osal/Android.mk @@ -0,0 +1,44 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OSAL_Android.cpp \ + SEC_OSAL_Event.c \ + SEC_OSAL_Queue.c \ + SEC_OSAL_ETC.c \ + SEC_OSAL_Mutex.c \ + SEC_OSAL_Thread.c \ + SEC_OSAL_Memory.c \ + SEC_OSAL_Semaphore.c \ + SEC_OSAL_Library.c \ + SEC_OSAL_Log.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libsecosal + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_V4L2), false) +ifeq ($(BOARD_USE_S3D_SUPPORT), true) +LOCAL_CFLAGS += -DS3D_SUPPORT +endif +endif + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := libcutils libutils \ + libui \ + libhardware \ + libandroid_runtime \ + libsurfaceflinger_client \ + libbinder \ + libmedia + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/osal \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Android.cpp b/exynos/multimedia/openmax/osal/SEC_OSAL_Android.cpp new file mode 100644 index 0000000..bb41720 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Android.cpp @@ -0,0 +1,579 @@ +/* + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Android.cpp + * @brief + * @author Seungbeom Kim (sbcrux.kim@samsung.com) + * @author Hyeyeon Chung (hyeon.chung@samsung.com) + * @author Yunji Kim (yunji.kim@samsung.com) + * @author Jinsung Yang (jsgood.yang@samsung.com) + * @version 1.1.0 + * @history + * 2011.7.15 : Create + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Vdec.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_OSAL_Android" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +using namespace android; + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE useAndroidNativeBuffer( + SEC_OMX_BASEPORT *pSECPort, + OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_U32 nPortIndex, + OMX_PTR pAppPrivate, + OMX_U32 nSizeBytes, + OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + unsigned int i = 0; + + FunctionIn(); + + if (pSECPort == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + goto EXIT; + } + } + + SEC_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_LockANBHandle( + OMX_IN OMX_U32 handle, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_PTR *vaddr) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + buffer_handle_t bufferHandle = (buffer_handle_t) handle; + Rect bounds(width, height); + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); + + int usage = 0; + + switch (format) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: +#ifdef S3D_SUPPORT + case OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR: + case OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL: + case OMX_SEC_COLOR_FormatNV12Tiled_TB_LR: + case OMX_SEC_COLOR_FormatNV12Tiled_TB_RL: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR: + case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL: + case OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR: + case OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL: + case OMX_SEC_COLOR_FormatYUV420Planar_TB_LR: + case OMX_SEC_COLOR_FormatYUV420Planar_TB_RL: +#endif + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR; + break; + default: + usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; + break; + } + + if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.lock() fail", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_UnlockANBHandle(OMX_IN OMX_U32 handle) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + buffer_handle_t bufferHandle = (buffer_handle_t) handle; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); + + if (mapper.unlock(bufferHandle) != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.unlock() fail", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_GetPhysANBHandle( + OMX_IN OMX_U32 handle, + OMX_OUT OMX_PTR *paddr) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + buffer_handle_t bufferHandle = (buffer_handle_t) handle; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); + + if (mapper.getphys(bufferHandle, paddr) != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.getphys() fail", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_LockANB( + OMX_IN OMX_PTR pBuffer, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_U32 *pStride, + OMX_OUT OMX_PTR *vaddr) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; + + ret = SEC_OSAL_LockANBHandle((OMX_U32)pANB->handle, width, height, format, vaddr); + *pStride = pANB->stride; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_UnlockANB(OMX_IN OMX_PTR pBuffer) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; + + ret = SEC_OSAL_UnlockANBHandle((OMX_U32)pANB->handle); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_GetPhysANB( + OMX_IN OMX_PTR pBuffer, + OMX_OUT OMX_PTR *paddr) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; + + ret = SEC_OSAL_GetPhysANBHandle((OMX_U32)pANB->handle, paddr); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_GetANBParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamGetAndroidNativeBuffer: + { + GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__); + + ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + /* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any + * modifications since currently not defined what the 'nUsage' is for. + */ + pANBParams->nUsage |= 0; + } + break; + + default: + { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SetANBParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; + + switch (nIndex) { + case OMX_IndexParamEnableAndroidBuffers: + { + EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__); + + ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort->bIsANBEnabled = pANBParams->enable; + } + break; + + case OMX_IndexParamUseAndroidNativeBuffer: + { + UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + android_native_buffer_t *pANB; + OMX_U32 nSizeBytes; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex); + + ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (pSECPort->portState != OMX_StateIdle) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Port state should be IDLE", __func__); + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pANB = pANBParams->nativeBuffer.get(); + + /* MALI alignment restriction */ + nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16); + nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2; + + ret = useAndroidNativeBuffer(pSECPort, + pANBParams->bufferHeader, + pANBParams->nPortIndex, + pANBParams->pAppPrivate, + nSizeBytes, + (OMX_U8 *) pANB); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: useAndroidNativeBuffer is failed", __func__); + goto EXIT; + } + } + break; + + case OMX_IndexParamStoreMetaDataBuffer: + { + StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + + SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__); + + ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(StoreMetaDataInBuffersParams)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pSECPort->bStoreMetaData = pANBParams->bStoreMetaData; + } + break; + + default: + { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_GetInfoFromMetaData(OMX_IN SEC_OMX_DATA *pBuffer, + OMX_OUT OMX_PTR *ppBuf) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + MetadataBufferType type; + buffer_handle_t pBufHandle; + + FunctionIn(); + +/* + * meta data contains the following data format. + * payload depends on the MetadataBufferType + * -------------------------------------------------------------- + * | MetadataBufferType | payload | + * -------------------------------------------------------------- + * + * If MetadataBufferType is kMetadataBufferTypeCameraSource, then + * -------------------------------------------------------------- + * | kMetadataBufferTypeCameraSource | physical addr. of Y |physical addr. of CbCr | + * -------------------------------------------------------------- + * + * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then + * -------------------------------------------------------------- + * | kMetadataBufferTypeGrallocSource | buffer_handle_t | + * -------------------------------------------------------------- + */ + + /* MetadataBufferType */ + memcpy(&type, (MetadataBufferType *)(pBuffer->dataBuffer), sizeof(type)); + + if (type == kMetadataBufferTypeCameraSource) { + /* physical addr. of Y */ + ppBuf[0] = (OMX_PTR)(pBuffer->dataBuffer + sizeof(type)); + /* physical addr. of CbCr */ + ppBuf[1] = (OMX_PTR)(pBuffer->dataBuffer + sizeof(type) + sizeof(pBuffer->dataBuffer)); + } else if (type == kMetadataBufferTypeGrallocSource) { + /* buffer_handle_t */ + memcpy(&pBufHandle, pBuffer->dataBuffer + sizeof(type), sizeof(buffer_handle_t)); + ppBuf[0] = (OMX_PTR)pBufHandle; + } + +EXIT: + FunctionOut(); + + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Android.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Android.h new file mode 100644 index 0000000..67029f5 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Android.h @@ -0,0 +1,81 @@ +/* + * Copyright 2011 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Android.h + * @brief + * @author Seungbeom Kim (sbcrux.kim@samsung.com) + * @author Hyeyeon Chung (hyeon.chung@samsung.com) + * @author Yunji Kim (yunji.kim@samsung.com) + * @author Jinsung Yang (jsgood.yang@samsung.com) + * @version 1.1.0 + * @history + * 2011.7.15 : Create + */ + +#ifndef SEC_OSAL_ANDROID +#define SEC_OSAL_ANDROID + +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_Index.h" + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_GetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE SEC_OSAL_SetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE SEC_OSAL_LockANB(OMX_IN OMX_PTR pBuffer, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_U32 *pStride, + OMX_OUT OMX_PTR *vaddr); + +OMX_ERRORTYPE SEC_OSAL_GetPhysANB(OMX_IN OMX_PTR pBuffer, + OMX_OUT OMX_PTR *paddr); + +OMX_ERRORTYPE SEC_OSAL_UnlockANB(OMX_IN OMX_PTR pBuffer); + +OMX_ERRORTYPE SEC_OSAL_LockANBHandle(OMX_IN OMX_U32 pBuffer, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_PTR *vaddr); + +OMX_ERRORTYPE SEC_OSAL_UnlockANBHandle(OMX_IN OMX_U32 pBuffer); + +OMX_ERRORTYPE SEC_OSAL_GetPhysANBHandle(OMX_IN OMX_U32 pBuffer, + OMX_OUT OMX_PTR *paddr); + +OMX_ERRORTYPE SEC_OSAL_GetInfoFromMetaData(OMX_IN SEC_OMX_DATA *pBuffer, + OMX_OUT OMX_PTR *pOutBuffer); + +OMX_ERRORTYPE SEC_OSAL_CheckANB(OMX_IN SEC_OMX_DATA *pBuffer, + OMX_OUT OMX_BOOL *bIsANBEnabled); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.c b/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.c new file mode 100644 index 0000000..1bce154 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.c @@ -0,0 +1,154 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_ETC.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" + + +#ifndef HAVE_GETLINE +ssize_t getline(char **ppLine, size_t *pLen, FILE *pStream) +{ + char *pCurrentPointer = NULL; + size_t const chunk = 512; + + size_t defaultBufferSize = chunk + 1; + size_t retSize = 0; + + if (*ppLine == NULL) { + *ppLine = (char *)malloc(defaultBufferSize); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = defaultBufferSize; + } + else { + if (*pLen < defaultBufferSize) { + *ppLine = (char *)realloc(*ppLine, defaultBufferSize); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = defaultBufferSize; + } + } + + while (1) { + size_t i; + size_t j = 0; + size_t readByte = 0; + + pCurrentPointer = *ppLine + readByte; + + i = fread(pCurrentPointer, 1, chunk, pStream); + if (i < chunk && ferror(pStream)) { + retSize = -1; + goto EXIT; + } + while (j < i) { + ++j; + if (*pCurrentPointer++ == (char)'\n') { + *pCurrentPointer = '\0'; + if (j != i) { + if (fseek(pStream, j - i, SEEK_CUR)) { + retSize = -1; + goto EXIT; + } + if (feof(pStream)) + clearerr(pStream); + } + readByte += j; + retSize = readByte; + goto EXIT; + } + } + + readByte += j; + if (feof(pStream)) { + if (readByte) { + retSize = readByte; + goto EXIT; + } + if (!i) { + retSize = -1; + goto EXIT; + } + } + + i = ((readByte + (chunk * 2)) / chunk) * chunk; + if (i != *pLen) { + *ppLine = (char *)realloc(*ppLine, i); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = i; + } + } + +EXIT: + return retSize; +} +#endif /* HAVE_GETLINE */ + +OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src) +{ + return strcpy(dest, src); +} + +OMX_PTR SEC_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num) +{ + return strncpy(dest, src, num); +} + +OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2) +{ + return strcmp(str1, str2); +} + +OMX_S32 SEC_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num) +{ + return strncmp(str1, str2, num); +} + +OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src) +{ + return strcat(dest, src); +} + +OMX_PTR SEC_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num) +{ + return strncat(dest, src, num); +} + +size_t SEC_OSAL_Strlen(const char *str) +{ + return strlen(str); +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.h b/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.h new file mode 100644 index 0000000..f311f26 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_ETC.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_ETC.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_ETC +#define SEC_OSAL_ETC + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src); +OMX_S32 SEC_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num); +OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2); +OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src); +size_t SEC_OSAL_Strlen(const char *str); +ssize_t getline(char **ppLine, size_t *len, FILE *stream); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Event.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Event.c new file mode 100644 index 0000000..383b62c --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Event.c @@ -0,0 +1,217 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* + * @file SEC_OSAL_Event.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_Event.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_OSAL_EVENT" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle) +{ + SEC_OSAL_THREADEVENT *event; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + event = (SEC_OSAL_THREADEVENT *)SEC_OSAL_Malloc(sizeof(SEC_OSAL_THREADEVENT)); + if (!event) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + SEC_OSAL_Memset(event, 0, sizeof(SEC_OSAL_THREADEVENT)); + event->signal = OMX_FALSE; + + ret = SEC_OSAL_MutexCreate(&event->mutex); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(event); + goto EXIT; + } + + if (pthread_cond_init(&event->condition, NULL)) { + SEC_OSAL_MutexTerminate(event->mutex); + SEC_OSAL_Free(event); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + *eventHandle = (OMX_HANDLETYPE)event; + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pthread_cond_destroy(&event->condition)) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = SEC_OSAL_MutexUnlock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = SEC_OSAL_MutexTerminate(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Free(event); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_FALSE; + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_TRUE; + pthread_cond_signal(&event->condition); + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct timespec timeout; + struct timeval now; + int funcret = 0; + OMX_U32 tv_us; + + FunctionIn(); + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + gettimeofday(&now, NULL); + + tv_us = now.tv_usec + ms * 1000; + timeout.tv_sec = now.tv_sec + tv_us / 1000000; + timeout.tv_nsec = (tv_us % 1000000) * 1000; + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (ms == 0) { + if (!event->signal) + ret = OMX_ErrorTimeout; + } else if (ms == DEF_MAX_WAIT_TIME) { + while (!event->signal) + pthread_cond_wait(&event->condition, (pthread_mutex_t *)(event->mutex)); + ret = OMX_ErrorNone; + } else { + while (!event->signal) { + funcret = pthread_cond_timedwait(&event->condition, (pthread_mutex_t *)(event->mutex), &timeout); + if ((!event->signal) && (funcret == ETIMEDOUT)) { + ret = OMX_ErrorTimeout; + break; + } + } + } + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Event.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Event.h new file mode 100644 index 0000000..8ae2eb5 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Event.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Event.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_EVENT +#define SEC_OSAL_EVENT + +#include +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#define DEF_MAX_WAIT_TIME 0xFFFFFFFF + +typedef struct _SEC_OSAL_THREADEVENT +{ + OMX_BOOL signal; + OMX_HANDLETYPE mutex; + pthread_cond_t condition; +} SEC_OSAL_THREADEVENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Library.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Library.c new file mode 100644 index 0000000..f400794 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Library.c @@ -0,0 +1,54 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Library.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include + +#include "SEC_OSAL_Library.h" + + +void *SEC_OSAL_dlopen(const char *filename, int flag) +{ + return dlopen(filename, flag); +} + +void *SEC_OSAL_dlsym(void *handle, const char *symbol) +{ + return dlsym(handle, symbol); +} + +int SEC_OSAL_dlclose(void *handle) +{ + return dlclose(handle); +} + +const char *SEC_OSAL_dlerror(void) +{ + return dlerror(); +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Library.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Library.h new file mode 100644 index 0000000..27ac42e --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Library.h @@ -0,0 +1,46 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Library.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_LIBRARY +#define SEC_OSAL_LIBRARY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void *SEC_OSAL_dlopen(const char *filename, int flag); +void *SEC_OSAL_dlsym(void *handle, const char *symbol); +int SEC_OSAL_dlclose(void *handle); +const char *SEC_OSAL_dlerror(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Log.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Log.c new file mode 100644 index 0000000..ea95174 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Log.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Log.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include + +#include "SEC_OSAL_Log.h" + + +void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) +{ + va_list argptr; + + va_start(argptr, msg); + + switch (logLevel) { + case SEC_LOG_TRACE: + __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); + break; + case SEC_LOG_WARNING: + __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); + break; + case SEC_LOG_ERROR: + __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr); + break; + default: + __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr); + } + + va_end(argptr); +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Log.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Log.h new file mode 100644 index 0000000..b993b90 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Log.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Log.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + * 2010.8.27 : Add trace function + */ + +#ifndef SEC_OSAL_LOG +#define SEC_OSAL_LOG + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SEC_LOG_OFF +#define SEC_LOG +#endif + +#ifndef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG" +#endif + +#ifdef SEC_TRACE_ON +#define SEC_TRACE +#endif + +typedef enum _LOG_LEVEL +{ + SEC_LOG_TRACE, + SEC_LOG_WARNING, + SEC_LOG_ERROR +} SEC_LOG_LEVEL; + +#ifdef SEC_LOG +#define SEC_OSAL_Log(a, ...) ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)) +#else +#define SEC_OSAL_Log(a, ...) \ + do { \ + if (a == SEC_LOG_ERROR) \ + ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)); \ + } while (0) +#endif + +#ifdef SEC_TRACE +#define FunctionIn() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) +#define FunctionOut() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) +#else +#define FunctionIn() ((void *)0) +#define FunctionOut() ((void *)0) +#endif + +extern void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.c new file mode 100644 index 0000000..bf5224d --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.c @@ -0,0 +1,71 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Memory.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" + +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +static int mem_cnt = 0; + +OMX_PTR SEC_OSAL_Malloc(OMX_U32 size) +{ + mem_cnt++; + SEC_OSAL_Log(SEC_LOG_TRACE, "alloc count: %d", mem_cnt); + + return (OMX_PTR)malloc(size); +} + +void SEC_OSAL_Free(OMX_PTR addr) +{ + mem_cnt--; + SEC_OSAL_Log(SEC_LOG_TRACE, "free count: %d", mem_cnt); + + if (addr) + free(addr); + + return; +} + +OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n) +{ + return memset(dest, c, n); +} + +OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memcpy(dest, src, n); +} + +OMX_PTR SEC_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memmove(dest, src, n); +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.h new file mode 100644 index 0000000..fed5cac --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Memory.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Memory.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_MEMORY +#define SEC_OSAL_MEMORY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR SEC_OSAL_Malloc(OMX_U32 size); +void SEC_OSAL_Free(OMX_PTR addr); +OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n); +OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n); +OMX_PTR SEC_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.c new file mode 100644 index 0000000..b8f7b79 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.c @@ -0,0 +1,93 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Mutex.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" + + +OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle) +{ + pthread_mutex_t *mutex; + + mutex = (pthread_mutex_t *)SEC_OSAL_Malloc(sizeof(pthread_mutex_t)); + if (!mutex) + return OMX_ErrorInsufficientResources; + + if (pthread_mutex_init(mutex, NULL) != 0) { + SEC_OSAL_Free(mutex); + return OMX_ErrorUndefined; + } + + *mutexHandle = (OMX_HANDLETYPE)mutex; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_destroy(mutex) != 0) + return OMX_ErrorUndefined; + + SEC_OSAL_Free(mutex); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + int result; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_lock(mutex) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + int result; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_unlock(mutex) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.h new file mode 100644 index 0000000..2dd63bc --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Mutex.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Mutex.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create +*/ + +#ifndef SEC_OSAL_MUTEX +#define SEC_OSAL_MUTEX + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.c new file mode 100644 index 0000000..4ecd8dc --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.c @@ -0,0 +1,174 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Queue.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_Queue.h" + + +OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle) +{ + int i = 0; + SEC_QElem *newqelem = NULL; + SEC_QElem *currentqelem = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + ret = SEC_OSAL_MutexCreate(&queue->qMutex); + if (ret != OMX_ErrorNone) + return ret; + + queue->first = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); + if (queue->first == NULL) + return OMX_ErrorInsufficientResources; + + SEC_OSAL_Memset(queue->first, 0, sizeof(SEC_QElem)); + currentqelem = queue->last = queue->first; + queue->numElem = 0; + + for (i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { + newqelem = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); + if (newqelem == NULL) { + while (queue->first != NULL) { + currentqelem = queue->first->qNext; + SEC_OSAL_Free((OMX_PTR)queue->first); + queue->first = currentqelem; + } + return OMX_ErrorInsufficientResources; + } else { + SEC_OSAL_Memset(newqelem, 0, sizeof(SEC_QElem)); + currentqelem->qNext = newqelem; + currentqelem = newqelem; + } + } + + currentqelem->qNext = queue->first; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle) +{ + int i = 0; + SEC_QElem *currentqelem = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + for ( i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { + currentqelem = queue->first->qNext; + SEC_OSAL_Free(queue->first); + queue->first = currentqelem; + } + + if(queue->first) { + SEC_OSAL_Free(queue->first); + queue->first = NULL; + } + + ret = SEC_OSAL_MutexTerminate(queue->qMutex); + + return ret; +} + +int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data) +{ + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + + if ((queue->last->data != NULL) || (queue->numElem >= MAX_QUEUE_ELEMENTS)) { + SEC_OSAL_MutexUnlock(queue->qMutex); + return -1; + } + queue->last->data = data; + queue->last = queue->last->qNext; + queue->numElem++; + + SEC_OSAL_MutexUnlock(queue->qMutex); + return 0; +} + +void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle) +{ + void *data = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return NULL; + + SEC_OSAL_MutexLock(queue->qMutex); + + if ((queue->first->data == NULL) || (queue->numElem <= 0)) { + SEC_OSAL_MutexUnlock(queue->qMutex); + return NULL; + } + data = queue->first->data; + queue->first->data = NULL; + queue->first = queue->first->qNext; + queue->numElem--; + + SEC_OSAL_MutexUnlock(queue->qMutex); + return data; +} + +int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle) +{ + int ElemNum = 0; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + ElemNum = queue->numElem; + SEC_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + +int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum) +{ + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + queue->numElem = ElemNum; + SEC_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.h new file mode 100644 index 0000000..d1dee11 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Queue.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Queue.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_QUEUE +#define SEC_OSAL_QUEUE + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#define MAX_QUEUE_ELEMENTS 10 + +typedef struct _SEC_QElem +{ + void *data; + struct _SEC_QElem *qNext; +} SEC_QElem; + +typedef struct _SEC_QUEUE +{ + SEC_QElem *first; + SEC_QElem *last; + int numElem; + OMX_HANDLETYPE qMutex; +} SEC_QUEUE; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle); +OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle); +int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data); +void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle); +int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle); +int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.c new file mode 100644 index 0000000..be9b9cb --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.c @@ -0,0 +1,134 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Semaphore.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Semaphore.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG_SEMA" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle) +{ + sem_t *sema; + + sema = (sem_t *)SEC_OSAL_Malloc(sizeof(sem_t)); + if (!sema) + return OMX_ErrorInsufficientResources; + + if (sem_init(sema, 0, 0) != 0) { + SEC_OSAL_Free(sema); + return OMX_ErrorUndefined; + } + + *semaphoreHandle = (OMX_HANDLETYPE)sema; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_destroy(sema) != 0) + return OMX_ErrorUndefined; + + SEC_OSAL_Free(sema); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + FunctionIn(); + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_wait(sema) != 0) + return OMX_ErrorUndefined; + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + FunctionIn(); + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_post(sema) != 0) + return OMX_ErrorUndefined; + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_init(sema, 0, val) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + int semaVal = 0; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_getvalue(sema, &semaVal) != 0) + return OMX_ErrorUndefined; + + *val = (OMX_S32)semaVal; + + return OMX_ErrorNone; +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.h new file mode 100644 index 0000000..431cba4 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Semaphore.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Semaphore.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_SEMAPHORE +#define SEC_OSAL_SEMAPHORE + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val); +OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.c b/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.c new file mode 100644 index 0000000..730b4a9 --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.c @@ -0,0 +1,158 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Thread.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Thread.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG_THREAD" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +typedef struct _SEC_THREAD_HANDLE_TYPE +{ + pthread_t pthread; + pthread_attr_t attr; + struct sched_param schedparam; + int stack_size; +} SEC_THREAD_HANDLE_TYPE; + + +OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument) +{ + FunctionIn(); + + int result = 0; + int detach_ret = 0; + SEC_THREAD_HANDLE_TYPE *thread; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + thread = SEC_OSAL_Malloc(sizeof(SEC_THREAD_HANDLE_TYPE)); + SEC_OSAL_Memset(thread, 0, sizeof(SEC_THREAD_HANDLE_TYPE)); + + pthread_attr_init(&thread->attr); + if (thread->stack_size != 0) + pthread_attr_setstacksize(&thread->attr, thread->stack_size); + + /* set priority */ + if (thread->schedparam.sched_priority != 0) + pthread_attr_setschedparam(&thread->attr, &thread->schedparam); + + detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE); + if (detach_ret != 0) { + SEC_OSAL_Free(thread); + *threadHandle = NULL; + ret = OMX_ErrorUndefined; + goto EXIT; + } + + result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument); + /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */ + + switch (result) { + case 0: + *threadHandle = (OMX_HANDLETYPE)thread; + ret = OMX_ErrorNone; + break; + case EAGAIN: + SEC_OSAL_Free(thread); + *threadHandle = NULL; + ret = OMX_ErrorInsufficientResources; + break; + default: + SEC_OSAL_Free(thread); + *threadHandle = NULL; + ret = OMX_ErrorUndefined; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pthread_join(thread->pthread, NULL) != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Free(thread); + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle) +{ + SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) + return OMX_ErrorBadParameter; + + /* thread_cancel(thread->pthread); */ + pthread_exit(&thread->pthread); + pthread_join(thread->pthread, NULL); + + SEC_OSAL_Free(thread); + return OMX_ErrorNone; +} + +void SEC_OSAL_ThreadExit(void *value_ptr) +{ + pthread_exit(value_ptr); + return; +} + +void SEC_OSAL_SleepMillisec(OMX_U32 ms) +{ + usleep(ms * 1000); + return; +} diff --git a/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.h b/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.h new file mode 100644 index 0000000..ce1262d --- /dev/null +++ b/exynos/multimedia/openmax/osal/SEC_OSAL_Thread.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Thread.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_THREAD +#define SEC_OSAL_THREAD + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument); +OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle); +OMX_ERRORTYPE SEC_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle); +void SEC_OSAL_ThreadExit(void *value_ptr); +void SEC_OSAL_SleepMillisec(OMX_U32 ms); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/utils/Android.mk b/exynos/multimedia/utils/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/exynos/multimedia/utils/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/exynos/multimedia/utils/csc/Android.mk b/exynos/multimedia/utils/csc/Android.mk new file mode 100644 index 0000000..3bc3577 --- /dev/null +++ b/exynos/multimedia/utils/csc/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos4/Android.mk +endif + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(LOCAL_PATH)/exynos5/Android.mk +endif diff --git a/exynos/multimedia/utils/csc/exynos4/Android.mk b/exynos/multimedia/utils/csc/exynos4/Android.mk new file mode 100644 index 0000000..e7ed4e2 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/Android.mk @@ -0,0 +1,42 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_COPY_HEADERS_TO := libsecmm +LOCAL_COPY_HEADERS := \ + color_space_convertor.h \ + csc_fimc.h + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + color_space_convertor.c \ + csc_linear_to_tiled_crop_neon.s \ + csc_linear_to_tiled_interleave_crop_neon.s \ + csc_tiled_to_linear_crop_neon.s \ + csc_tiled_to_linear_deinterleave_crop_neon.s \ + csc_interleave_memcpy_neon.s \ + csc_fimc.cpp + +LOCAL_C_INCLUDES := \ + $(TOP)/$(TARGET_OMX_PATH)/include/khronos \ + $(TOP)/$(TARGET_OMX_PATH)/include/sec \ + $(TOP)/$(TARGET_HAL_PATH)/include \ + $(TOP)/$(TARGET_HAL_PATH)/libhwconverter + +ifeq ($(BOARD_USE_SAMSUNG_COLORFORMAT), true) +LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT +endif + +LOCAL_MODULE := libseccscapi + +LOCAL_PRELINK_MODULE := false + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := liblog libfimc libhwconverter + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c new file mode 100644 index 0000000..7a4c559 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c @@ -0,0 +1,1732 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file color_space_convertor.c + * + * @brief SEC_OMX specific define + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.7.01 : Create + */ + +#include "stdio.h" +#include "stdlib.h" +#include "color_space_convertor.h" + +/* + * Get tiled address of position(x,y) + * + * @param x_size + * width of tiled[in] + * + * @param y_size + * height of tiled[in] + * + * @param x_pos + * x position of tield[in] + * + * @param src_size + * y position of tield[in] + * + * @return + * address of tiled data + */ +static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) +{ + int pixel_x_m1, pixel_y_m1; + int roundup_x, roundup_y; + int linear_addr0, linear_addr1, bank_addr ; + int x_addr; + int trans_addr; + + pixel_x_m1 = x_size -1; + pixel_y_m1 = y_size -1; + + roundup_x = ((pixel_x_m1 >> 7) + 1); + roundup_y = ((pixel_x_m1 >> 6) + 1); + + x_addr = x_pos >> 2; + + if ((y_size <= y_pos+32) && ( y_pos < y_size) && + (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) { + linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } else { + linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } + + linear_addr0 = linear_addr0 << 2; + trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; + + return trans_addr; +} + +/* + * De-interleaves src to dest1, dest2 + * + * @param dest1 + * Address of de-interleaved data[out] + * + * @param dest2 + * Address of de-interleaved data[out] + * + * @param src + * Address of interleaved data[in] + * + * @param src_size + * Size of interleaved data[in] + */ +static void csc_deinterleave_memcpy( + unsigned char *dest1, + unsigned char *dest2, + unsigned char *src, + unsigned int src_size) +{ + unsigned int i = 0; + for(i=0; i= 256) { + for (i=top; i>8)<<8; + temp3 = temp3>>6; + temp4 = i>>5; + if (temp4 & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = temp4-1; + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+temp3; + tiled_offset = tiled_offset+2; + temp1 = (temp3>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*2; + temp4 = 8; + } else { + temp2 = ((yuv420_height+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = temp3+2; + temp1 = (temp1>>2)<<2; + tiled_offset = temp3+temp1; + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = tiled_offset+temp4*(temp1>>6); + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*6; + temp4 = 8; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = temp4*(temp1>>6); + tiled_offset = tiled_offset+temp3; + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*2; + temp4 = 4; + } + } + + temp1 = i&0x1F; + tiled_offset = tiled_offset+64*(temp1); + tiled_offset1 = tiled_offset1+64*(temp1); + temp2 = yuv420_width-left-right; + linear_offset = temp2*(i-top); + temp3 = ((j+256)>>8)<<8; + temp3 = temp3-j; + temp1 = left&0x3F; + if (temp3 > 192) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1); + temp2 = ((left+63)>>6)<<6; + temp3 = ((yuv420_width-right)>>6)<<6; + if (temp2 == temp3) { + temp2 = yuv420_width-right-(64-temp1); + } + memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64); + memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64); + memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+256-temp1; + } else if (temp3 > 128) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1); + memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64); + memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+192-temp1; + } else if (temp3 > 64) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1); + memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+128-temp1; + } else if (temp3 > 0) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1); + linear_offset = linear_offset+64-temp1; + } + + tiled_offset = tiled_offset+temp4*2048; + j = (left>>8)<<8; + j = j + 256; + temp2 = yuv420_width-right-256; + for (; j<=temp2; j=j+256) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + tiled_offset1 = tiled_offset1+temp4*2048; + memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); + memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64); + tiled_offset = tiled_offset+temp4*2048; + memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+256; + } + + tiled_offset1 = tiled_offset1+temp4*2048; + temp2 = yuv420_width-right-j; + if (temp2 > 192) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); + memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64); + memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192); + } else if (temp2 > 128) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64); + memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128); + } else if (temp2 > 64) { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64); + } else { + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); + } + } + } else if (temp1 >= 64) { + for (i=top; i<(yuv420_height-buttom); i=i+1) { + j = left; + tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i); + temp2 = ((j+64)>>6)<<6; + temp2 = temp2-j; + linear_offset = temp1*(i-top); + temp4 = j&0x3; + tiled_offset = tiled_offset+temp4; + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); + linear_offset = linear_offset+temp2; + j = j+temp2; + if ((j+64) <= temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i); + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + linear_offset = linear_offset+64; + j = j+64; + } + if ((j+64) <= temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i); + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64); + linear_offset = linear_offset+64; + j = j+64; + } + if (j < temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i); + temp2 = temp3-j; + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2); + } + } + } else { + for (i=top; i<(yuv420_height-buttom); i=i+1) { + linear_offset = temp1*(i-top); + for (j=left; j<(yuv420_width-right); j=j+2) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i); + temp4 = j&0x3; + tiled_offset = tiled_offset+temp4; + memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2); + linear_offset = linear_offset+2; + } + } + } +} + +/* + * Converts and Deinterleaves tiled data to linear + * Crops left, top, right, buttom + * 1. UV of NV12T to UV of YUV420P + * + * @param yuv420_u_dest + * U plane address of YUV420P[out] + * + * @param yuv420_v_dest + * V plane address of YUV420P[out] + * + * @param nv12t_src + * UV plane address of NV12T[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_uv_height + * Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +static void csc_tiled_to_linear_deinterleave_crop( + unsigned char *yuv420_u_dest, + unsigned char *yuv420_v_dest, + unsigned char *nv12t_uv_src, + unsigned int yuv420_width, + unsigned int yuv420_uv_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom) +{ + unsigned int i, j; + unsigned int tiled_offset = 0, tiled_offset1 = 0; + unsigned int linear_offset = 0; + unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0; + + temp3 = yuv420_width-right; + temp1 = temp3-left; + /* real width is greater than or equal 256 */ + if (temp1 >= 256) { + for (i=top; i>8)<<8; + temp3 = temp3>>6; + temp4 = i>>5; + if (temp4 & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = temp4-1; + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+temp3; + tiled_offset = tiled_offset+2; + temp1 = (temp3>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*2; + temp4 = 8; + } else { + temp2 = ((yuv420_uv_height+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = temp3+2; + temp1 = (temp1>>2)<<2; + tiled_offset = temp3+temp1; + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = tiled_offset+temp4*(temp1>>6); + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*6; + temp4 = 8; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = ((yuv420_width+127)>>7)<<7; + tiled_offset = temp4*(temp1>>6); + tiled_offset = tiled_offset+temp3; + tiled_offset = tiled_offset<<11; + tiled_offset1 = tiled_offset+2048*2; + temp4 = 4; + } + } + + temp1 = i&0x1F; + tiled_offset = tiled_offset+64*(temp1); + tiled_offset1 = tiled_offset1+64*(temp1); + temp2 = yuv420_width-left-right; + linear_offset = temp2*(i-top)/2; + temp3 = ((j+256)>>8)<<8; + temp3 = temp3-j; + temp1 = left&0x3F; + if (temp3 > 192) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, yuv420_v_dest+linear_offset, nv12t_uv_src+tiled_offset+temp1, 64-temp1); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2), + yuv420_v_dest+linear_offset+(32-temp1/2), + nv12t_uv_src+tiled_offset+2048, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2), + yuv420_v_dest+linear_offset+(64-temp1/2), + nv12t_uv_src+tiled_offset1, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(96-temp1/2), + yuv420_v_dest+linear_offset+(96-temp1/2), + nv12t_uv_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+128-temp1/2; + } else if (temp3 > 128) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset+2048+temp1, 64-temp1); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2), + yuv420_v_dest+linear_offset+(32-temp1/2), + nv12t_uv_src+tiled_offset1, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2), + yuv420_v_dest+linear_offset+(64-temp1/2), + nv12t_uv_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+96-temp1/2; + } else if (temp3 > 64) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset1+temp1, 64-temp1); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2), + yuv420_v_dest+linear_offset+(32-temp1/2), + nv12t_uv_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+64-temp1/2; + } else if (temp3 > 0) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset1+2048+temp1, 64-temp1); + linear_offset = linear_offset+32-temp1/2; + } + + tiled_offset = tiled_offset+temp4*2048; + j = (left>>8)<<8; + j = j + 256; + temp2 = yuv420_width-right-256; + for (; j<=temp2; j=j+256) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + tiled_offset1 = tiled_offset1+temp4*2048; + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32, + yuv420_v_dest+linear_offset+32, + nv12t_uv_src+tiled_offset+2048, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64, + yuv420_v_dest+linear_offset+64, + nv12t_uv_src+tiled_offset1, 64); + tiled_offset = tiled_offset+temp4*2048; + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96, + yuv420_v_dest+linear_offset+96, + nv12t_uv_src+tiled_offset1+2048, 64); + linear_offset = linear_offset+128; + } + + tiled_offset1 = tiled_offset1+temp4*2048; + temp2 = yuv420_width-right-j; + if (temp2 > 192) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32, + yuv420_v_dest+linear_offset+32, + nv12t_uv_src+tiled_offset+2048, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64, + yuv420_v_dest+linear_offset+64, + nv12t_uv_src+tiled_offset1, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96, + yuv420_v_dest+linear_offset+96, + nv12t_uv_src+tiled_offset1+2048, temp2-192); + } else if (temp2 > 128) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32, + yuv420_v_dest+linear_offset+32, + nv12t_uv_src+tiled_offset+2048, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64, + yuv420_v_dest+linear_offset+64, + nv12t_uv_src+tiled_offset1, temp2-128); + } else if (temp2 > 64) { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32, + yuv420_v_dest+linear_offset+32, + nv12t_uv_src+tiled_offset+2048, temp2-64); + } else { + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, temp2); + } + } + } else if (temp1 >= 64) { + for (i=top; i<(yuv420_uv_height-buttom); i=i+1) { + j = left; + tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i); + temp2 = ((j+64)>>6)<<6; + temp2 = temp2-j; + temp3 = yuv420_width-right; + temp4 = temp3-left; + linear_offset = temp4*(i-top)/2; + temp4 = j&0x3; + tiled_offset = tiled_offset+temp4; + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, temp2); + linear_offset = linear_offset+temp2/2; + j = j+temp2; + if ((j+64) <= temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + linear_offset = linear_offset+32; + j = j+64; + } + if ((j+64) <= temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i); + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 64); + linear_offset = linear_offset+32; + j = j+64; + } + if (j < temp3) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i); + temp1 = temp3-j; + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, temp1); + } + } + } else { + for (i=top; i<(yuv420_uv_height-buttom); i=i+1) { + temp3 = yuv420_width-right; + temp4 = temp3-left; + linear_offset = temp4*(i-top)/2; + for (j=left; j<(yuv420_width-right); j=j+2) { + tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i); + temp3 = j&0x3; + tiled_offset = tiled_offset+temp3; + csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, + yuv420_v_dest+linear_offset, + nv12t_uv_src+tiled_offset, 2); + linear_offset = linear_offset+1; + } + } + } +} + +/* + * Converts linear data to tiled + * Crops left, top, right, buttom + * 1. Y of YUV420P to Y of NV12T + * 2. Y of YUV420S to Y of NV12T + * 3. UV of YUV420S to UV of NV12T + * + * @param nv12t_dest + * Y or UV plane address of NV12T[out] + * + * @param yuv420_src + * Y or UV plane address of YUV420P(S)[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +static void csc_linear_to_tiled_crop( + unsigned char *nv12t_dest, + unsigned char *yuv420_src, + unsigned int yuv420_width, + unsigned int yuv420_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom) +{ + unsigned int i, j; + unsigned int tiled_x_index = 0, tiled_y_index = 0; + unsigned int aligned_x_size = 0, aligned_y_size = 0; + unsigned int tiled_offset = 0; + unsigned int temp1 = 0, temp2 = 0; + + aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5; + aligned_x_size = ((yuv420_width-left-right)>>6)<<6; + + for (i=0; i>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + + memcpy(nv12t_dest+tiled_offset, yuv420_src+left+j+yuv420_width*(i+top), 64); + memcpy(nv12t_dest+tiled_offset+64*1, yuv420_src+left+j+yuv420_width*(i+top+1), 64); + memcpy(nv12t_dest+tiled_offset+64*2, yuv420_src+left+j+yuv420_width*(i+top+2), 64); + memcpy(nv12t_dest+tiled_offset+64*3, yuv420_src+left+j+yuv420_width*(i+top+3), 64); + memcpy(nv12t_dest+tiled_offset+64*4, yuv420_src+left+j+yuv420_width*(i+top+4), 64); + memcpy(nv12t_dest+tiled_offset+64*5, yuv420_src+left+j+yuv420_width*(i+top+5), 64); + memcpy(nv12t_dest+tiled_offset+64*6, yuv420_src+left+j+yuv420_width*(i+top+6), 64); + memcpy(nv12t_dest+tiled_offset+64*7, yuv420_src+left+j+yuv420_width*(i+top+7), 64); + memcpy(nv12t_dest+tiled_offset+64*8, yuv420_src+left+j+yuv420_width*(i+top+8), 64); + memcpy(nv12t_dest+tiled_offset+64*9, yuv420_src+left+j+yuv420_width*(i+top+9), 64); + memcpy(nv12t_dest+tiled_offset+64*10, yuv420_src+left+j+yuv420_width*(i+top+10), 64); + memcpy(nv12t_dest+tiled_offset+64*11, yuv420_src+left+j+yuv420_width*(i+top+11), 64); + memcpy(nv12t_dest+tiled_offset+64*12, yuv420_src+left+j+yuv420_width*(i+top+12), 64); + memcpy(nv12t_dest+tiled_offset+64*13, yuv420_src+left+j+yuv420_width*(i+top+13), 64); + memcpy(nv12t_dest+tiled_offset+64*14, yuv420_src+left+j+yuv420_width*(i+top+14), 64); + memcpy(nv12t_dest+tiled_offset+64*15, yuv420_src+left+j+yuv420_width*(i+top+15), 64); + memcpy(nv12t_dest+tiled_offset+64*16, yuv420_src+left+j+yuv420_width*(i+top+16), 64); + memcpy(nv12t_dest+tiled_offset+64*17, yuv420_src+left+j+yuv420_width*(i+top+17), 64); + memcpy(nv12t_dest+tiled_offset+64*18, yuv420_src+left+j+yuv420_width*(i+top+18), 64); + memcpy(nv12t_dest+tiled_offset+64*19, yuv420_src+left+j+yuv420_width*(i+top+19), 64); + memcpy(nv12t_dest+tiled_offset+64*20, yuv420_src+left+j+yuv420_width*(i+top+20), 64); + memcpy(nv12t_dest+tiled_offset+64*21, yuv420_src+left+j+yuv420_width*(i+top+21), 64); + memcpy(nv12t_dest+tiled_offset+64*22, yuv420_src+left+j+yuv420_width*(i+top+22), 64); + memcpy(nv12t_dest+tiled_offset+64*23, yuv420_src+left+j+yuv420_width*(i+top+23), 64); + memcpy(nv12t_dest+tiled_offset+64*24, yuv420_src+left+j+yuv420_width*(i+top+24), 64); + memcpy(nv12t_dest+tiled_offset+64*25, yuv420_src+left+j+yuv420_width*(i+top+25), 64); + memcpy(nv12t_dest+tiled_offset+64*26, yuv420_src+left+j+yuv420_width*(i+top+26), 64); + memcpy(nv12t_dest+tiled_offset+64*27, yuv420_src+left+j+yuv420_width*(i+top+27), 64); + memcpy(nv12t_dest+tiled_offset+64*28, yuv420_src+left+j+yuv420_width*(i+top+28), 64); + memcpy(nv12t_dest+tiled_offset+64*29, yuv420_src+left+j+yuv420_width*(i+top+29), 64); + memcpy(nv12t_dest+tiled_offset+64*30, yuv420_src+left+j+yuv420_width*(i+top+30), 64); + memcpy(nv12t_dest+tiled_offset+64*31, yuv420_src+left+j+yuv420_width*(i+top+31), 64); + } + } + + for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+2) { + for (j=0; j>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + + temp1 = i&0x1F; + memcpy(nv12t_dest+tiled_offset+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 64); + memcpy(nv12t_dest+tiled_offset+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 64); + } + } + + for (i=0; i<(yuv420_height-top-buttom); i=i+2) { + for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) { + tiled_offset = 0; + tiled_x_index = j>>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + + temp1 = i&0x1F; + temp2 = j&0x3F; + memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 2); + memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 2); + } + } + +} + +/* + * Converts and Interleaves linear to tiled + * Crops left, top, right, buttom + * 1. UV of YUV420P to UV of NV12T + * + * @param nv12t_uv_dest + * UV plane address of NV12T[out] + * + * @param yuv420p_u_src + * U plane address of YUV420P[in] + * + * @param yuv420p_v_src + * V plane address of YUV420P[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_uv_height + * Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +static void csc_linear_to_tiled_interleave_crop( + unsigned char *nv12t_uv_dest, + unsigned char *yuv420_u_src, + unsigned char *yuv420_v_src, + unsigned int yuv420_width, + unsigned int yuv420_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom) +{ + unsigned int i, j; + unsigned int tiled_x_index = 0, tiled_y_index = 0; + unsigned int aligned_x_size = 0, aligned_y_size = 0; + unsigned int tiled_offset = 0; + unsigned int temp1 = 0, temp2 = 0; + + aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5; + aligned_x_size = ((yuv420_width-left-right)>>6)<<6; + + for (i=0; i>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*1, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+1), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+1), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*2, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+2), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+2), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*3, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+3), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+3), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*4, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+4), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+4), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*5, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+5), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+5), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*6, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+6), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+6), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*7, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+7), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+7), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*8, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+8), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+8), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*9, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+9), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+9), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*10, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+10), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+10), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*11, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+11), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+11), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*12, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+12), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+12), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*13, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+13), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+13), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*14, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+14), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+14), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*15, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+15), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+15), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*16, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+16), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+16), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*17, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+17), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+17), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*18, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+18), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+18), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*19, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+19), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+19), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*20, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+20), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+20), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*21, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+21), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+21), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*22, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+22), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+22), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*23, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+23), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+23), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*24, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+24), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+24), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*25, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+25), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+25), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*26, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+26), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+26), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*27, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+27), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+27), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*28, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+28), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+28), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*29, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+29), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+29), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*30, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+30), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+30), 32); + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*31, + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+31), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+31), 32); + + } + } + + for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+1) { + for (j=0; j>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + temp1 = i&0x1F; + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1), + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32); + } + } + + for (i=0; i<(yuv420_height-top-buttom); i=i+1) { + for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) { + tiled_offset = 0; + tiled_x_index = j>>6; + tiled_y_index = i>>5; + if (tiled_y_index & 0x1) { + /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ + tiled_offset = tiled_y_index-1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset+2; + temp1 = (tiled_x_index>>2)<<2; + tiled_offset = tiled_offset+temp1; + tiled_offset = tiled_offset<<11; + } else { + temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5; + if ((i+32)>2)<<2+x_block_num*y */ + temp1 = tiled_x_index+2; + temp1 = (temp1>>2)<<2; + tiled_offset = tiled_x_index+temp1; + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset<<11; + } else { + /* even2 fomula: x+x_block_num*y */ + temp1 = (((yuv420_width-left-right)+127)>>7)<<7; + tiled_offset = tiled_y_index*(temp1>>6); + tiled_offset = tiled_offset+tiled_x_index; + tiled_offset = tiled_offset<<11; + } + } + temp1 = i&0x1F; + temp2 = j&0x3F; + csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1), + yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top), + yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 1); + } + } + +} + + +/* + * Converts tiled data to linear + * Crops left, top, right, buttom + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * 3. UV of NV12T to UV of YUV420S + * + * @param yuv420_dest + * Y or UV plane address of YUV420[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +void csc_tiled_to_linear_crop_neon( + unsigned char *yuv420_dest, + unsigned char *nv12t_src, + unsigned int yuv420_width, + unsigned int yuv420_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom); + +/* + * Converts and Deinterleaves tiled data to linear + * Crops left, top, right, buttom + * 1. UV of NV12T to UV of YUV420P + * + * @param yuv420_u_dest + * U plane address of YUV420P[out] + * + * @param yuv420_v_dest + * V plane address of YUV420P[out] + * + * @param nv12t_src + * UV plane address of NV12T[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_uv_height + * Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +void csc_tiled_to_linear_deinterleave_crop_neon( + unsigned char *yuv420_u_dest, + unsigned char *yuv420_v_dest, + unsigned char *nv12t_uv_src, + unsigned int yuv420_width, + unsigned int yuv420_uv_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom); + +/* + * Converts linear data to tiled + * Crops left, top, right, buttom + * 1. Y of YUV420P to Y of NV12T + * 2. Y of YUV420S to Y of NV12T + * 3. UV of YUV420S to UV of NV12T + * + * @param nv12t_dest + * Y or UV plane address of NV12T[out] + * + * @param yuv420_src + * Y or UV plane address of YUV420P(S)[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +void csc_linear_to_tiled_crop_neon( + unsigned char *nv12t_dest, + unsigned char *yuv420_src, + unsigned int yuv420_width, + unsigned int yuv420_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom); + +/* + * Converts and Interleaves linear to tiled + * Crops left, top, right, buttom + * 1. UV of YUV420P to UV of NV12T + * + * @param nv12t_uv_dest + * UV plane address of NV12T[out] + * + * @param yuv420p_u_src + * U plane address of YUV420P[in] + * + * @param yuv420p_v_src + * V plane address of YUV420P[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_uv_height + * Height/2 of YUV420[in] + * + * @param left + * Crop size of left + * + * @param top + * Crop size of top + * + * @param right + * Crop size of right + * + * @param buttom + * Crop size of buttom + */ +void csc_linear_to_tiled_interleave_crop_neon( + unsigned char *nv12t_uv_dest, + unsigned char *yuv420_u_src, + unsigned char *yuv420_v_src, + unsigned int yuv420_width, + unsigned int yuv420_height, + unsigned int left, + unsigned int top, + unsigned int right, + unsigned int buttom); + +/* + * Converts tiled data to linear. + * 1. y of nv12t to y of yuv420p + * 2. y of nv12t to y of yuv420s + * + * @param dst + * y address of yuv420[out] + * + * @param src + * y address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_tiled_to_linear_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_crop(y_dst, y_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts tiled data to linear + * 1. uv of nv12t to y of yuv420s + * + * @param dst + * uv address of yuv420s[out] + * + * @param src + * uv address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420s[in] + * + * @param yuv420_height + * real height of yuv420s[in] + * + */ +void csc_tiled_to_linear_uv( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_crop(uv_dst, uv_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts tiled data to linear + * 1. uv of nt12t to uv of yuv420p + * + * @param u_dst + * u address of yuv420p[out] + * + * @param v_dst + * v address of yuv420p[out] + * + * @param uv_src + * uv address of nt12t[in] + * + * @param yuv420_width + * real width of yuv420p[in] + * + * @param yuv420_height + * real height of yuv420p[in] + */ +void csc_tiled_to_linear_uv_deinterleave( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_deinterleave_crop(u_dst, v_dst, uv_src, width, height, + 0, 0, 0, 0); +} + +/* + * Converts linear data to tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height) +{ + csc_linear_to_tiled_crop(y_dst, y_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts and interleaves linear data to tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height) +{ + csc_linear_to_tiled_interleave_crop(uv_dst, u_src, v_src, width, height, + 0, 0, 0, 0); +} + +/* + * Converts tiled data to linear for mfc 6.x + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * + * @param dst + * Y address of YUV420[out] + * + * @param src + * Y address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * Y: real height of YUV420[in] + * + */ +void csc_tiled_to_linear_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts tiled data to linear for mfc 6.x + * 1. UV of NV12T to Y of YUV420S + * + * @param u_dst + * UV plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_neon( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_crop_neon(uv_dst, uv_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts tiled data to linear for mfc 6.x + * Deinterleave src to u_dst, v_dst + * 1. UV of NV12T to Y of YUV420P + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_deinterleave_neon( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height) +{ + csc_tiled_to_linear_deinterleave_crop_neon(u_dst, v_dst, uv_src, width, height, + 0, 0, 0, 0); +} + +/* + * Converts linear data to tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height) +{ + csc_linear_to_tiled_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0); +} + +/* + * Converts and interleaves linear data to tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv_neon( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height) +{ + csc_linear_to_tiled_interleave_crop_neon(uv_dst, u_src, v_src, + width, height, 0, 0, 0, 0); +} + +/* + * Converts RGB565 to YUV420P + * + * @param y_dst + * Y plane address of YUV420P[out] + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420P( + unsigned char *y_dst, + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height) +{ + unsigned int i, j; + unsigned int tmp; + + unsigned int R, G, B; + unsigned int Y, U, V; + + unsigned int offset1 = width * height; + unsigned int offset2 = width/2 * height/2; + + unsigned short int *pSrc = (unsigned short int *)rgb_src; + + unsigned char *pDstY = (unsigned char *)y_dst; + unsigned char *pDstU = (unsigned char *)u_dst; + unsigned char *pDstV = (unsigned char *)v_dst; + + unsigned int yIndex = 0; + unsigned int uIndex = 0; + unsigned int vIndex = 0; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + tmp = pSrc[j * width + i]; + + R = (tmp & 0x0000F800) >> 8; + G = (tmp & 0x000007E0) >> 3; + B = (tmp & 0x0000001F); + B = B << 3; + + Y = ((66 * R) + (129 * G) + (25 * B) + 128); + Y = Y >> 8; + Y += 16; + + pDstY[yIndex++] = (unsigned char)Y; + + if ((j % 2) == 0 && (i % 2) == 0) { + U = ((-38 * R) - (74 * G) + (112 * B) + 128); + U = U >> 8; + U += 128; + V = ((112 * R) - (94 * G) - (18 * B) + 128); + V = V >> 8; + V += 128; + + pDstU[uIndex++] = (unsigned char)U; + pDstV[vIndex++] = (unsigned char)V; + } + } + } +} + +/* + * Converts RGB565 to YUV420SP + * + * @param y_dst + * Y plane address of YUV420SP[out] + * + * @param uv_dst + * UV plane address of YUV420SP[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height) +{ + unsigned int i, j; + unsigned int tmp; + + unsigned int R, G, B; + unsigned int Y, U, V; + + unsigned int offset = width * height; + + unsigned short int *pSrc = (unsigned short int *)rgb_src; + + unsigned char *pDstY = (unsigned char *)y_dst; + unsigned char *pDstUV = (unsigned char *)uv_dst; + + unsigned int yIndex = 0; + unsigned int uvIndex = 0; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + tmp = pSrc[j * width + i]; + + R = (tmp & 0x0000F800) >> 11; + R = R * 8; + G = (tmp & 0x000007E0) >> 5; + G = G * 4; + B = (tmp & 0x0000001F); + B = B * 8; + + Y = ((66 * R) + (129 * G) + (25 * B) + 128); + Y = Y >> 8; + Y += 16; + + pDstY[yIndex++] = (unsigned char)Y; + + if ((j % 2) == 0 && (i % 2) == 0) { + U = ((-38 * R) - (74 * G) + (112 * B) + 128); + U = U >> 8; + U += 128; + V = ((112 * R) - (94 * G) - (18 * B) + 128); + V = V >> 8; + V += 128; + + pDstUV[uvIndex++] = (unsigned char)U; + pDstUV[uvIndex++] = (unsigned char)V; + } + } + } +} + +void csc_ARGB8888_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height) +{ + unsigned int i, j; + unsigned int tmp; + + unsigned int R, G, B; + unsigned int Y, U, V; + + unsigned int offset = width * height; + + unsigned int *pSrc = (unsigned int *)rgb_src; + + unsigned char *pDstY = (unsigned char *)y_dst; + unsigned char *pDstUV = (unsigned char *)uv_dst; + + unsigned int yIndex = 0; + unsigned int uvIndex = 0; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + tmp = pSrc[j * width + i]; + + R = (tmp & 0x00FF0000) >> 16; + G = (tmp & 0x0000FF00) >> 8; + B = (tmp & 0x000000FF); + + Y = ((66 * R) + (129 * G) + (25 * B) + 128); + Y = Y >> 8; + Y += 16; + + pDstY[yIndex++] = (unsigned char)Y; + + if ((j % 2) == 0 && (i % 2) == 0) { + U = ((-38 * R) - (74 * G) + (112 * B) + 128); + U = U >> 8; + U += 128; + V = ((112 * R) - (94 * G) - (18 * B) + 128); + V = V >> 8; + V += 128; + + pDstUV[uvIndex++] = (unsigned char)U; + pDstUV[uvIndex++] = (unsigned char)V; + } + } + } +} \ No newline at end of file diff --git a/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h new file mode 100644 index 0000000..92c0a6d --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h @@ -0,0 +1,414 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file color_space_convertor.h + * @brief SEC_OMX specific define. It support MFC 5.x tiled. + * NV12T(tiled) layout: + * Each element is not pixel. It is 64x32 pixel block. + * uv pixel block is interleaved as u v u v u v ... + * y1 y2 y7 y8 y9 y10 y15 y16 + * y3 y4 y5 y6 y11 y12 y13 y14 + * y17 y18 y23 y24 y25 y26 y31 y32 + * y19 y20 y21 y22 y27 y28 y29 y30 + * uv1 uv2 uv7 uv8 uv9 uv10 uv15 uv16 + * uv3 uv4 uv5 uv6 uv11 uv12 uv13 uv14 + * YUV420Planar(linear) layout: + * Each element is not pixel. It is 64x32 pixel block. + * y1 y2 y3 y4 y5 y6 y7 y8 + * y9 y10 y11 y12 y13 y14 y15 y16 + * y17 y18 y19 y20 y21 y22 y23 y24 + * y25 y26 y27 y28 y29 y30 y31 y32 + * u1 u2 u3 u4 u5 u6 u7 u8 + * v1 v2 v3 v4 v5 v6 v7 v8 + * YUV420Semiplanar(linear) layout: + * Each element is not pixel. It is 64x32 pixel block. + * uv pixel block is interleaved as u v u v u v ... + * y1 y2 y3 y4 y5 y6 y7 y8 + * y9 y10 y11 y12 y13 y14 y15 y16 + * y17 y18 y19 y20 y21 y22 y23 y24 + * y25 y26 y27 y28 y29 y30 y31 y32 + * uv1 uv2 uv3 uv4 uv5 uv6 uv7 uv8 + * uv9 uv10 uv11 uv12 uv13 uv14 uv15 uv16 + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.07.01 : Create + * 2011.12.01 : Added csc functions + */ + +#ifndef COLOR_SPACE_CONVERTOR_H_ +#define COLOR_SPACE_CONVERTOR_H_ + +/*--------------------------------------------------------------------------------*/ +/* Format Conversion API */ +/*--------------------------------------------------------------------------------*/ +/* + * Interleaves src1, src2 to dest + * + * @param dest + * Address of interleaved data[out] + * + * @param src1 + * Address of de-interleaved data[in] + * + * @param src2 + * Address of de-interleaved data[in] + * + * @param src_size + * Size of de-interleaved data[in] + */ +/* +void csc_interleave_memcpy( + unsigned char *dest, + unsigned char *src1, + unsigned char *src2, + unsigned int src_size); +*/ +/* C Code */ +/* + * Converts tiled data to linear + * 1. y of nv12t to y of yuv420p + * 2. y of nv12t to y of yuv420s + * + * @param dst + * y address of yuv420[out] + * + * @param src + * y address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_tiled_to_linear_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear + * 1. uv of nv12t to y of yuv420s + * + * @param dst + * uv address of yuv420s[out] + * + * @param src + * uv address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420s[in] + * + * @param yuv420_height + * real height of yuv420s[in] + * + */ +void csc_tiled_to_linear_uv( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear + * 1. uv of nt12t to uv of yuv420p + * + * @param u_dst + * u address of yuv420p[out] + * + * @param v_dst + * v address of yuv420p[out] + * + * @param uv_src + * uv address of nt12t[in] + * + * @param yuv420_width + * real width of yuv420p[in] + * + * @param yuv420_height + * real height of yuv420p[in] + */ +void csc_tiled_to_linear_uv_deinterleave( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts linear data to tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts and interleaves linear data to tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear for mfc 6.x + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * + * @param dst + * Y address of YUV420[out] + * + * @param src + * Y address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * Y: real height of YUV420[in] + * + */ +void csc_tiled_to_linear_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear for mfc 6.x + * 1. UV of NV12T to Y of YUV420S + * + * @param u_dst + * UV plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_neon( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear for mfc 6.x + * Deinterleave src to u_dst, v_dst + * 1. UV of NV12T to Y of YUV420P + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_deinterleave_neon( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts linear data to tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts and interleaves linear data to tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv_neon( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height); + +/* + * Converts RGB565 to YUV420P + * + * @param y_dst + * Y plane address of YUV420P[out] + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420P( + unsigned char *y_dst, + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height); + +/* + * Converts RGB565 to YUV420S + * + * @param y_dst + * Y plane address of YUV420S[out] + * + * @param uv_dst + * UV plane address of YUV420S[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height); + +/* + * Converts ARGB888 to YUV420SP + * + * @param y_dst + * Y plane address of YUV420SP[out] + * + * @param uv_dst + * UV plane address of YUV420SP[out] + * + * @param rgb_src + * Address of ARGB888[in] + * + * @param width + * Width of ARGB888[in] + * + * @param height + * Height of ARGB888[in] + */ +void csc_ARGB8888_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + unsigned int width, + unsigned int height); + +#endif /*COLOR_SPACE_CONVERTOR_H_*/ diff --git a/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp b/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp new file mode 100644 index 0000000..7c458b2 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_fimc.cpp + * + * @brief csc_fimc use fimc1 to color space convertion + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.11.01 : Create + */ + +#include +#include + +#include "SEC_OMX_Def.h" +#include "csc_fimc.h" +#include "HardwareConverter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * create and open fimc handle + * + * @return + * fimc handle + */ +void *csc_fimc_open() +{ + HardwareConverter *hw_converter = NULL; + + hw_converter = new HardwareConverter; + if (hw_converter->bHWconvert_flag == 0) { + delete hw_converter; + hw_converter = NULL; + LOGE("%s LINE = %d HardwareConverter failed", __func__, __LINE__); + } + + return (void *)hw_converter; +} + +/* + * close and destroy fimc handle + * + * @param handle + * fimc handle[in] + * + * @return + * pass or fail + */ +CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle) +{ + HardwareConverter *hw_converter = (HardwareConverter *)handle; + + if (hw_converter != NULL) + delete hw_converter; + + return CSC_FIMC_RET_OK; +} + +/* + * convert color space nv12t to omxformat + * + * @param handle + * fimc handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * pass or fail + */ +CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat) +{ + CSC_FIMC_ERROR_CODE ret = CSC_FIMC_RET_OK; + HardwareConverter *hw_converter = (HardwareConverter *)handle; + + if (hw_converter == NULL) { + ret = CSC_FIMC_RET_FAIL; + goto EXIT; + } + + hw_converter->convert( + (void *)src_addr, (void *)dst_addr, + (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress, + width, height, omxformat); + + ret = CSC_FIMC_RET_OK; + +EXIT: + + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/exynos/multimedia/utils/csc/exynos4/csc_fimc.h b/exynos/multimedia/utils/csc/exynos4/csc_fimc.h new file mode 100644 index 0000000..3ae24ac --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_fimc.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_fimc.h + * + * @brief csc_fimc use fimc1 to color space convertion + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.11.01 : Create + */ + +#ifndef CSC_FIMC_H + +#define CSC_FIMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + CSC_FIMC_RET_OK = 0, + CSC_FIMC_RET_FAIL = -1 +} CSC_FIMC_ERROR_CODE; + +/*--------------------------------------------------------------------------------*/ +/* CSC FIMC APIs */ +/*--------------------------------------------------------------------------------*/ +/* + * create and open fimc handle + * + * @return + * fimc handle + */ +void *csc_fimc_open(); + +/* + * close and destroy fimc handle + * + * @param handle + * fimc handle[in] + * + * @return + * error code + */ +CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle); + +/* + * convert color space nv12t to omxformat + * + * @param handle + * fimc handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * error code + */ +CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s new file mode 100644 index 0000000..3d2b41f --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s @@ -0,0 +1,120 @@ +/* + * + * Copyright 2012 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_linear_to_tiled_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2012.01.04 : Create + */ + +/* + * Interleave src1, src2 to dst + * + * @param dest + * dst address[out] + * + * @param src1 + * src1 address[in] + * + * @param src2 + * src2 address[in] + * + * @param src_size + * src_size or src1 + */ + + .arch armv7-a + .text + .global csc_interleave_memcpy_neon + .type csc_interleave_memcpy_neon, %function +csc_interleave_memcpy_neon: + .fnstart + + @r0 dest + @r1 src1 + @r2 src2 + @r3 src_size + @r4 + @r5 + @r6 + @r7 + @r8 temp1 + @r9 temp2 + @r10 dest_addr + @r11 src1_addr + @r12 src2_addr + @r14 i + + stmfd sp!, {r8-r12,r14} @ backup registers + + mov r10, r0 + mov r11, r1 + mov r12, r2 + mov r14, r3 + + cmp r14, #128 + blt LESS_THAN_128 + +LOOP_128: + vld1.8 {q0}, [r11]! + vld1.8 {q2}, [r11]! + vld1.8 {q4}, [r11]! + vld1.8 {q6}, [r11]! + vld1.8 {q8}, [r11]! + vld1.8 {q10}, [r11]! + vld1.8 {q12}, [r11]! + vld1.8 {q14}, [r11]! + vld1.8 {q1}, [r12]! + vld1.8 {q3}, [r12]! + vld1.8 {q5}, [r12]! + vld1.8 {q7}, [r12]! + vld1.8 {q9}, [r12]! + vld1.8 {q11}, [r12]! + vld1.8 {q13}, [r12]! + vld1.8 {q15}, [r12]! + + vst2.8 {q0, q1}, [r10]! + vst2.8 {q2, q3}, [r10]! + vst2.8 {q4, q5}, [r10]! + vst2.8 {q6, q7}, [r10]! + vst2.8 {q8, q9}, [r10]! + vst2.8 {q10, q11}, [r10]! + vst2.8 {q12, q13}, [r10]! + vst2.8 {q14, q15}, [r10]! + + sub r14, #128 + cmp r14, #128 + bgt LOOP_128 + +LESS_THAN_128: + cmp r14, #0 + beq RESTORE_REG + +LOOP_1: + ldrb r8, [r11], #1 + ldrb r9, [r12], #1 + strb r8, [r10], #1 + strb r9, [r10], #1 + subs r14, #1 + bne LOOP_1 + +RESTORE_REG: + ldmfd sp!, {r8-r12,r15} @ restore registers + .fnend diff --git a/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s new file mode 100644 index 0000000..745d495 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s @@ -0,0 +1,492 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_linear_to_tiled_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.8.04 : Create + */ + +/* + * Converts linear data to tiled + * Crops left, top, right, buttom + * 1. Y of YUV420P to Y of NV12T + * 2. Y of YUV420S to Y of NV12T + * 3. UV of YUV420S to UV of NV12T + * + * @param nv12t_dest + * Y or UV plane address of NV12T[out] + * + * @param yuv420_src + * Y or UV plane address of YUV420P(S)[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left. It should be even. + * + * @param top + * Crop size of top. It should be even. + * + * @param right + * Crop size of right. It should be even. + * + * @param buttom + * Crop size of buttom. It should be even. + */ + + .arch armv7-a + .text + .global csc_linear_to_tiled_crop_neon + .type csc_linear_to_tiled_crop_neon, %function +csc_linear_to_tiled_crop_neon: + .fnstart + + @r0 tiled_dest + @r1 linear_src + @r2 yuv420_width + @r3 yuv420_height + @r4 j + @r5 i + @r6 nn(tiled_addr) + @r7 mm(linear_addr) + @r8 aligned_x_size + @r9 aligned_y_size + @r10 temp1 + @r11 temp2 + @r12 temp3 + @r14 temp4 + + stmfd sp!, {r4-r12,r14} @ backup registers + + ldr r11, [sp, #44] @ top + ldr r14, [sp, #52] @ buttom + ldr r10, [sp, #40] @ left + ldr r12, [sp, #48] @ right + + sub r9, r3, r11 @ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5 + sub r9, r9, r14 + bic r9, r9, #0x1F + + sub r8, r2, r10 @ aligned_x_size = ((yuv420_width-left-right)>>6)<<6 + sub r8, r8, r12 + bic r8, r8, #0x3F + + mov r5, #0 @ i = 0 +LOOP_ALIGNED_Y_SIZE: + + mov r4, #0 @ j = 0 +LOOP_ALIGNED_X_SIZE: + + bl GET_TILED_OFFSET + + ldr r10, [sp, #44] @ r10 = top + ldr r14, [sp, #40] @ r14 = left + add r10, r5, r10 @ temp1 = linear_x_size*(i+top) + mul r10, r2, r10 + add r7, r1, r4 @ linear_addr = linear_src+j + add r7, r7, r10 @ linear_addr = linear_addr+temp1 + add r7, r7, r14 @ linear_addr = linear_addr+left + sub r10, r2, #32 + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*1, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*2, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*3, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + add r6, r0, r6 @ tiled_addr = tiled_dest+tiled_addr + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*1} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*2} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*3} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*4, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*5, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*6, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*7, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*4} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*5} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*6} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*7} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*8, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*9, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*10, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*11, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*8} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*9} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*10} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*11} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*12, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*13, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*14, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*15, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*12} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*13} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*14} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*15} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*16, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*17, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*18, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*19, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*16} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*17} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*18} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*19} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*20, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*21, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*22, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*23, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*20} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*21} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*22} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*23} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*24, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*25, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*26, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + pld [r7, r2] + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*27, 64} + pld [r7, r2] + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*24} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*25} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*26} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*27} + vst1.8 {q14, q15}, [r6]! + + pld [r7, r2] + vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*28, 64} + pld [r7, r2] + vld1.8 {q2, q3}, [r7], r10 + pld [r7, r2] + vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*29, 64} + pld [r7, r2] + vld1.8 {q6, q7}, [r7], r10 + pld [r7, r2] + vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*30, 64} + pld [r7, r2] + vld1.8 {q10, q11}, [r7], r10 + vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*31, 64} + vld1.8 {q14, q15}, [r7], r10 + vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*28} + vst1.8 {q2, q3}, [r6]! + vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*29} + vst1.8 {q6, q7}, [r6]! + vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*30} + vst1.8 {q10, q11}, [r6]! + vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*31} + vst1.8 {q14, q15}, [r6]! + + add r4, r4, #64 @ j = j+64 + cmp r4, r8 @ j>5 + mov r10, r4, asr #6 @ temp1 = j>>6 + + and r12, r11, #0x1 @ if (temp2 & 0x1) + cmp r12, #0x1 + bne GET_TILED_OFFSET_EVEN_FORMULA_1 + +GET_TILED_OFFSET_ODD_FORMULA: + sub r6, r11, #1 @ tiled_addr = temp2-1 + + ldr r7, [sp, #40] @ left + add r12, r2, #127 @ temp3 = linear_x_size+127 + sub r12, r12, r7 + ldr r7, [sp, #48] @ right + sub r12, r12, r7 + bic r12, r12, #0x7F @ temp3 = (temp3 >>7)<<7 + mov r12, r12, asr #6 @ temp3 = temp3>>6 + mul r6, r6, r12 @ tiled_addr = tiled_addr*temp3 + add r6, r6, r10 @ tiled_addr = tiled_addr+temp1 + add r6, r6, #2 @ tiled_addr = tiled_addr+2 + bic r12, r10, #0x3 @ temp3 = (temp1>>2)<<2 + add r6, r6, r12 @ tiled_addr = tiled_addr+temp3 + mov r6, r6, lsl #11 @ tiled_addr = tiled_addr<<11 + b GET_TILED_OFFSET_RETURN + +GET_TILED_OFFSET_EVEN_FORMULA_1: + ldr r7, [sp, #44] @ top + add r12, r3, #31 @ temp3 = linear_y_size+31 + sub r12, r12, r7 + ldr r7, [sp, #52] @ buttom + sub r12, r12, r7 + bic r12, r12, #0x1F @ temp3 = (temp3>>5)<<5 + sub r12, r12, #32 @ temp3 = temp3 - 32 + cmp r5, r12 @ if (i<(temp3-32)) { + bge GET_TILED_OFFSET_EVEN_FORMULA_2 + add r12, r10, #2 @ temp3 = temp1+2 + bic r12, r12, #3 @ temp3 = (temp3>>2)<<2 + add r6, r10, r12 @ tiled_addr = temp1+temp3 + ldr r7, [sp, #40] @ left + add r12, r2, #127 @ temp3 = linear_x_size+127 + sub r12, r12, r7 + ldr r7, [sp, #48] @ right + sub r12, r12, r7 + bic r12, r12, #0x7F @ temp3 = (temp3>>7)<<7 + mov r12, r12, asr #6 @ temp3 = temp3>>6 + mul r11, r11, r12 @ tiled_y_index = tiled_y_index*temp3 + add r6, r6, r11 @ tiled_addr = tiled_addr+tiled_y_index + mov r6, r6, lsl #11 @ + b GET_TILED_OFFSET_RETURN + +GET_TILED_OFFSET_EVEN_FORMULA_2: + ldr r7, [sp, #40] @ left + add r12, r2, #127 @ temp3 = linear_x_size+127 + sub r12, r12, r7 + ldr r7, [sp, #48] @ right + sub r12, r12, r7 + bic r12, r12, #0x7F @ temp3 = (temp3>>7)<<7 + mov r12, r12, asr #6 @ temp3 = temp3>>6 + mul r6, r11, r12 @ tiled_addr = temp2*temp3 + add r6, r6, r10 @ tiled_addr = tiled_addr+temp3 + mov r6, r6, lsl #11 @ tiled_addr = tiled_addr<<11@ + +GET_TILED_OFFSET_RETURN: + mov pc, lr + + .fnend diff --git a/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s new file mode 100644 index 0000000..6a054fa --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s @@ -0,0 +1,563 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_linear_to_tiled_interleave_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.8.04 : Create + */ + +/* + * Converts tiled data to linear + * Crops left, top, right, buttom + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * 3. UV of NV12T to UV of YUV420S + * + * @param yuv420_dest + * Y or UV plane address of YUV420[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left. It should be even. + * + * @param top + * Crop size of top. It should be even. + * + * @param right + * Crop size of right. It should be even. + * + * @param buttom + * Crop size of buttom. It should be even. + */ + + .arch armv7-a + .text + .global csc_linear_to_tiled_interleave_crop_neon + .type csc_linear_to_tiled_interleave_crop_neon, %function +csc_linear_to_tiled_interleave_crop_neon: + .fnstart + + @r0 tiled_dest + @r1 linear_src_u + @r2 linear_src_v + @r3 yuv420_width + @r4 yuv420_height + @r5 j + @r6 i + @r7 tiled_addr + @r8 linear_addr + @r9 aligned_x_size + @r10 aligned_y_size + @r11 temp1 + @r12 temp2 + @r14 temp3 + + stmfd sp!, {r4-r12,r14} @ backup registers + + ldr r4, [sp, #40] @ load linear_y_size to r4 + + ldr r10, [sp, #48] @ r10 = top + ldr r14, [sp, #56] @ r14 = buttom + ldr r11, [sp, #44] @ r11 = left + ldr r12, [sp, #52] @ r12 = right + + sub r10, r4, r10 @ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5 + sub r10, r10, r14 + bic r10, r10, #0x1F + sub r11, r3, r11 @ aligned_x_size = ((yuv420_width-left-right)>>6)<<6 + sub r11, r11, r12 + bic r9, r11, #0x3F + + mov r6, #0 @ i = 0 +LOOP_ALIGNED_Y_SIZE: + + mov r5, #0 @ j = 0 +LOOP_ALIGNED_X_SIZE: + + bl GET_TILED_OFFSET + + ldr r12, [sp, #48] @ r12 = top + ldr r8, [sp, #44] @ r8 = left + + mov r11, r3, asr #1 @ temp1 = (yuv420_width/2)*(i+top) + add r12, r6, r12 + mul r11, r11, r12 + add r11, r11, r5, asr #1 @ temp1 = temp1+j/2 + add r11, r11, r8, asr #1 @ temp1 = temp1+left/2 + + mov r12, r3, asr #1 @ temp2 = yuv420_width/2 + sub r12, r12, #16 @ temp2 = yuv420_width-16 + + add r8, r1, r11 @ linear_addr = linear_src_u+temp1 + add r11, r2, r11 @ temp1 = linear_src_v+temp1 + add r7, r0, r7 @ tiled_addr = tiled_dest+tiled_addr + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*1, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*2, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*3, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*1, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*2, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*3, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*1} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*2} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*3} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*4, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*5, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*6, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*7, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*4, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*5, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*6, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*7, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*4} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*5} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*6} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*7} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*8, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*9, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*10, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*11, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*8, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*9, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*10, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*11, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*8} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*9} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*10} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*11} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*12, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*13, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*14, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*15, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*12, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*13, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*14, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*15, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*12} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*13} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*14} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*15} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*16, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*17, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*18, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*19, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*16, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*17, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*18, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*19, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*16} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*17} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*18} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*19} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*20, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*21, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*22, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*23, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*20, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*21, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*22, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*23, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*20} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*21} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*22} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*23} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*24, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*25, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*26, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*27, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*24, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*25, 32} + vld1.8 {q7}, [r11], r12 + pld [r8] + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*26, 32} + vld1.8 {q11}, [r11], r12 + pld [r8, r3, asr #1] + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*27, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*24} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*25} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*26} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*27} + vst2.8 {q14, q15}, [r7]! + + pld [r8, r3] + vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*28, 32} + vld1.8 {q2}, [r8], r12 + pld [r8, r3] + vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*29, 32} + vld1.8 {q6}, [r8], r12 + pld [r11] + vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*30, 32} + vld1.8 {q10}, [r8], r12 + pld [r11, r3, asr #1] + vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*31, 32} + vld1.8 {q14}, [r8], r12 + pld [r11, r3] + vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*28, 32} + vld1.8 {q3}, [r11], r12 + pld [r11, r3] + vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*29, 32} + vld1.8 {q7}, [r11], r12 + vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*30, 32} + vld1.8 {q11}, [r11], r12 + vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*31, 32} + vld1.8 {q15}, [r11], r12 + vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*28} + vst2.8 {q2, q3}, [r7]! + vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*29} + vst2.8 {q6, q7}, [r7]! + vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*30} + vst2.8 {q10, q11}, [r7]! + vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*31} + vst2.8 {q14, q15}, [r7]! + + add r5, r5, #64 @ j = j+64 + cmp r5, r9 @ j>5 + mov r11, r5, asr #6 @ temp1 = j>>6 + + and r14, r12, #0x1 @ if (temp2 & 0x1) + cmp r14, #0x1 + bne GET_TILED_OFFSET_EVEN_FORMULA_1 + +GET_TILED_OFFSET_ODD_FORMULA: + + ldr r7, [sp, #48] @ r7 = left , (r14 was pushed to stack) + ldr r8, [sp, #56] @ r8 = right , (r14 was pushed to stack) + sub r14, r3, r7 + sub r14, r14, r8 + add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7 + bic r14, r14, #0x7F @ temp3 = (temp3 >>7)<<7 + mov r14, r14, asr #6 @ temp3 = temp3>>6 + sub r7, r12, #1 @ tiled_addr = temp2-1 + mul r7, r7, r14 @ tiled_addr = tiled_addr*temp3 + add r7, r7, r11 @ tiled_addr = tiled_addr+temp1 + add r7, r7, #2 @ tiled_addr = tiled_addr+2 + bic r14, r11, #0x3 @ temp3 = (temp1>>2)<<2 + add r7, r7, r14 @ tiled_addr = tiled_addr+temp3 + mov r7, r7, lsl #11 @ tiled_addr = tiled_addr<<11 + b GET_TILED_OFFSET_RETURN + +GET_TILED_OFFSET_EVEN_FORMULA_1: + ldr r7, [sp, #52] @ r7 = top, (r14 was pushed to stack) + ldr r8, [sp, #60] @ r8 = buttom, (r14 was pushed to stack) + sub r14, r4, r7 + sub r14, r14, r8 + add r14, r14, #31 @ temp3 = (((yuv420_height-top-buttom)+31)>>5)<<5 + bic r14, r14, #0x1F @ temp3 = (temp3>>5)<<5 + sub r14, r14, #32 @ temp3 = temp3 - 32 + cmp r6, r14 @ if (i<(temp3-32)) { + bge GET_TILED_OFFSET_EVEN_FORMULA_2 + add r14, r11, #2 @ temp3 = temp1+2 + bic r14, r14, #3 @ temp3 = (temp3>>2)<<2 + add r7, r11, r14 @ tiled_addr = temp1+temp3 + ldr r8, [sp, #48] @ r8 = left, (r14 was pushed to stack) + sub r14, r3, r8 + ldr r8, [sp, #56] @ r8 = right, (r14 was pushed to stack) + sub r14, r14, r8 + add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7 + bic r14, r14, #0x7F @ temp3 = (temp3>>7)<<7 + mov r14, r14, asr #6 @ temp3 = temp3>>6 + mul r12, r12, r14 @ tiled_y_index = tiled_y_index*temp3 + add r7, r7, r12 @ tiled_addr = tiled_addr+tiled_y_index + mov r7, r7, lsl #11 @ + b GET_TILED_OFFSET_RETURN + +GET_TILED_OFFSET_EVEN_FORMULA_2: + ldr r8, [sp, #48] @ r8 = left, (r14 was pushed to stack) + sub r14, r3, r8 + ldr r8, [sp, #56] @ r8 = right, (r14 was pushed to stack) + sub r14, r14, r8 + add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7 + bic r14, r14, #0x7F @ temp3 = (temp3>>7)<<7 + mov r14, r14, asr #6 @ temp3 = temp3>>6 + mul r7, r12, r14 @ tiled_addr = temp2*temp3 + add r7, r7, r11 @ tiled_addr = tiled_addr+temp3 + mov r7, r7, lsl #11 @ tiled_addr = tiled_addr<<11@ + +GET_TILED_OFFSET_RETURN: + ldmfd sp!, {r15} @ restore registers + + .fnend + diff --git a/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s new file mode 100644 index 0000000..da86ac6 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s @@ -0,0 +1,701 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_tiled_to_linear_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.8.04 : Create + */ + +/* + * Converts tiled data to linear + * Crops left, top, right, buttom + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * 3. UV of NV12T to UV of YUV420S + * + * @param yuv420_dest + * Y or UV plane address of YUV420[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * Width of YUV420[in] + * + * @param yuv420_height + * Y: Height of YUV420, UV: Height/2 of YUV420[in] + * + * @param left + * Crop size of left. It should be even. + * + * @param top + * Crop size of top. It should be even. + * + * @param right + * Crop size of right. It should be even. + * + * @param buttom + * Crop size of buttom. It should be even. + */ + + .arch armv7-a + .text + .global csc_tiled_to_linear_crop_neon + .type csc_tiled_to_linear_crop_neon, %function +csc_tiled_to_linear_crop_neon: + .fnstart + + @r0 yuv420_dest + @r1 nv12t_src + @r2 yuv420_width + @r3 yuv420_height + @r4 + @r5 i + @r6 j + @r7 tiled_offset + @r8 tiled_offset1 + @r9 linear_offset + @r10 temp1 + @r11 temp2 + @r12 temp3 + @r14 temp4 + + stmfd sp!, {r4-r12,r14} @ backup registers + + ldr r12, [sp, #48] @ r12 = right + ldr r10, [sp, #40] @ r10 = left + sub r12, r2, r12 @ temp3 = yuv420_width-right@ + sub r10, r12, r10 @ temp1 = temp3-left@ + cmp r10, #256 @ if (temp1 >= 256) + blt LOOP_HEIGHT_64_START + + ldr r5, [sp, #44] @ i = top +LOOP_HEIGHT_256: + ldr r6, [sp, #40] @ j = left + mov r14, r5, asr #5 @ temp4 = i>>5 + bic r12, r6, #0xFF @ temp3 = (j>>8)<<8 + mov r12, r12, asr #6 @ temp3 = temp3>>6 + and r11, r14, #0x1 @ if (temp4 & 0x1) + cmp r11, #0x1 + bne LOOP_HEIGHT_256_GET_TILED_EVEN +LOOP_HEIGHT_256_GET_TILED_ODD: + sub r7, r14, #1 @ tiled_offset = temp4-1 + add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = tiled_offset*(temp1>>6) + mul r7, r7, r10 + add r7, r7, r12 @ tiled_offset = tiled_offset+temp3 + add r7, r7, #2 @ tiled_offset = tiled_offset+2 + bic r10, r12, #0x3 @ temp1 = (temp3>>2)<<2 + add r7, r7, r10 @ tiled_offset = tiled_offset+temp1 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2 + mov r14, #8 + b LOOP_HEIGHT_256_GET_TILED_END + +LOOP_HEIGHT_256_GET_TILED_EVEN: + add r11, r3, #31 @ temp2 = ((yuv420_height+31)>>5)<<5 + bic r11, r11, #0x1F + add r10, r5, #32 @ if ((i+32)>2)<<2 + add r7, r12, r10 @ tiled_offset = temp3+temp1@ + add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = tiled_offset+temp4*(temp1>>6) + mla r7, r14, r10, r7 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #12288 @ tiled_offset1 = tiled_offset+2048*6 + mov r14, #8 + b LOOP_HEIGHT_256_GET_TILED_END + +LOOP_HEIGHT_256_GET_TILED_EVEN1: + add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = temp4*(temp1>>6) + mul r7, r14, r10 + add r7, r7, r12 @ tiled_offset = tiled_offset+temp3 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2 + mov r14, #4 + +LOOP_HEIGHT_256_GET_TILED_END: + + ldr r12, [sp, #48] @ right + ldr r9, [sp, #44] @ top + and r10, r5, #0x1F @ temp1 = i&0x1F + add r7, r7, r10, lsl #6 @ tiled_offset = tiled_offset+64*(temp1) + add r8, r8, r10, lsl #6 @ tiled_offset1 = tiled_offset1+64*(temp1) + sub r11, r2, r6 @ temp2 = yuv420_width-left(==j)-right + sub r11, r11, r12 + sub r9, r5, r9 @ linear_offset = temp2*(i-top)@ + mul r9, r11, r9 + add r12, r6, #256 @ temp3 = ((j+256)>>8)<<8@ + bic r12, r12, #0xFF + sub r12, r12, r6 @ temp3 = temp3-j@ + and r10, r6, #0x3F @ temp1 = left(==j)&0x3F + + cmp r12, #192 @ if (temp3 > 192) + ble LOOP_HEIGHT_256_LEFT_192 + add r11, r1, r7 @ r11 = nv12t_src+tiled_offset+temp1 + add r11, r11, r10 + pld [r11] + add r12, r1, r7 @ r12 = nv12t_src+tiled_offset+2048 + pld [r11, #32] + add r12, r12, #2048 + pld [r12] + cmp r10, #0 + pld [r12, #32] + stmnefd sp!, {r9-r12, r14} @ backup registers + rsbne r10, r10, #64 + blne MEMCOPY_UNDER_64 + ldmnefd sp!, {r9-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_256_64 + vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64} + vld1.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64} + vst1.8 {q2, q3}, [r11]! +LOOP_HEIGHT_256_LEFT_256_64: + add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1 + pld [r11] + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r11, #32] + vld1.8 {q6, q7}, [r12] + add r12, r11, #2048 @ r12 = nv12t_src+tiled_offset1+2048 + pld [r12] + vld1.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1, 64} + pld [r12, #32] + vld1.8 {q10, q11}, [r11] + vld1.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset1+2048, 64} + vld1.8 {q14, q15}, [r12] + + sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1 + add r12, r9, #64 + add r11, r11, r12 + + vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64} + vst1.8 {q6, q7}, [r11]! + vst1.8 {q8, q9}, [r11]! @ store {yuv420_dest+linear_offset+128-temp1, 64} + vst1.8 {q10, q11}, [r11]! + vst1.8 {q12, q13}, [r11]! @ store {yuv420_dest+linear_offset+192-temp1, 64} + vst1.8 {q14, q15}, [r11]! + + add r9, r9, #256 + sub r9, r9, r10 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_192: + cmp r12, #128 @ if (temp3 > 128) + ble LOOP_HEIGHT_256_LEFT_128 + add r11, r1, r7 @ r11 = nv12t_src+tiled_offset+2048+temp1 + add r11, r11, r10 + add r11, r11, #2048 + pld [r11] + add r12, r1, r8 @ r12 = nv12t_src+tiled_offset1 + pld [r11, #32] + cmp r10, #0 + pld [r12] + stmnefd sp!, {r9-r12, r14} @ backup registers + pld [r12, #32] + rsbne r10, r10, #64 + blne MEMCOPY_UNDER_64 + ldmnefd sp!, {r9-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_192_64 + vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+2048+temp1, 64} + vld1.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64} + vst1.8 {q2, q3}, [r11]! +LOOP_HEIGHT_256_LEFT_192_64: + add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+2048 + add r11, r11, #2048 + pld [r11] + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64} + pld [r11, #32] + vld1.8 {q6, q7}, [r12] + vld1.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1+2048, 64} + vld1.8 {q10, q11}, [r11] + + sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1 + add r12, r9, #64 + add r11, r11, r12 + + vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64} + vst1.8 {q6, q7}, [r11]! + vst1.8 {q8, q9}, [r11]! @ store {yuv420_dest+linear_offset+128-temp1, 64} + vst1.8 {q10, q11}, [r11]! + + add r9, r9, #192 + sub r9, r9, r10 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_128: + cmp r12, #64 @ if (temp3 > 64) + ble LOOP_HEIGHT_256_LEFT_64 + add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+temp1 + add r11, r11, r10 + pld [r11] + add r12, r1, r8 @ r12 = nv12t_src+tiled_offset1 + add r12, r12, #2048 + pld [r11, #32] + cmp r10, #0 + pld [r12] + stmnefd sp!, {r9-r12, r14} @ backup registers + pld [r12, #32] + rsbne r10, r10, #64 + blne MEMCOPY_UNDER_64 + ldmnefd sp!, {r9-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_128_64 + vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64} + vld1.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64} + vst1.8 {q2, q3}, [r11]! +LOOP_HEIGHT_256_LEFT_128_64: + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64} + vld1.8 {q6, q7}, [r12] + + sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1 + add r12, r9, #64 + add r11, r11, r12 + + vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64} + vst1.8 {q6, q7}, [r11]! + + add r9, r9, #128 + sub r9, r9, r10 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_64: + add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+2048+temp1 + add r11, r11, #2048 + add r11, r11, r10 + cmp r10, #0 + pld [r11] + stmnefd sp!, {r9-r12, r14} @ backup registers + pld [r11, #32] + rsbne r10, r10, #64 + blne MEMCOPY_UNDER_64 + ldmnefd sp!, {r9-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_64_64 + vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64} + vld1.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64} + vst1.8 {q2, q3}, [r11]! +LOOP_HEIGHT_256_LEFT_64_64: + add r9, r9, #64 + sub r9, r9, r10 + +LOOP_HEIGHT_256_LEFT_END: + + ldr r12, [sp, #48] @ right + add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048 + add r10, r1, r7 @ r10 = nv12t_src+tiled_offset + pld [r10] + bic r6, r6, #0xFF @ j = (left>>8)<<8 + pld [r10, #32] + add r6, r6, #256 @ j = j + 256 + sub r11, r2, r12 @ temp2 = yuv420_width-right-256 + sub r11, r11, #256 + cmp r6, r11 + bgt LOOP_HEIGHT_256_WIDTH_END + +LOOP_HEIGHT_256_WIDTH: + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + pld [r12] + vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset, 64} + pld [r12, #32] + vld1.8 {q2, q3}, [r10] + + add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048 + add r10, r1, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r10] + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r10, #32] + vld1.8 {q6, q7}, [r12] + + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + pld [r12] + vld1.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r12, #32] + vld1.8 {q10, q11}, [r10] + + add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048 + add r10, r1, r7 + pld [r10] + vld1.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r10, #32] + vld1.8 {q14, q15}, [r12] + + add r12, r0, r9 @ r12 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r12]! + vst1.8 {q2, q3}, [r12]! + vst1.8 {q4, q5}, [r12]! + vst1.8 {q6, q7}, [r12]! + vst1.8 {q8, q9}, [r12]! + vst1.8 {q10, q11}, [r12]! + vst1.8 {q12, q13}, [r12]! + vst1.8 {q14, q15}, [r12]! + add r9, r9, #256 @ linear_offset = linear_offset+256 + + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + + add r6, r6, #256 @ j=j+256 + cmp r6, r11 @ j<=temp2 + ble LOOP_HEIGHT_256_WIDTH + +LOOP_HEIGHT_256_WIDTH_END: + + add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048 + ldr r14, [sp, #48] @ right + sub r11, r2, r6 @ temp2 = yuv420_width-right-j + sub r11, r11, r14 + cmp r11, #0 + beq LOOP_HEIGHT_256_RIGHT_END + cmp r11, #192 + ble LOOP_HEIGHT_256_RIGHT_192 + add r12, r10, #2048 + pld [r12] + vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r12, #32] + vld1.8 {q2, q3}, [r10] + + add r10, r1, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r10] + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048} + pld [r10, #32] + vld1.8 {q6, q7}, [r12] + + add r14, r10, #2048 @ r10 = nv12t_src+tiled_offset1+2048 + pld [r14] + vld1.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset1} + pld [r14, #32] + vld1.8 {q10, q11}, [r10] + + add r12, r0, r9 @ r12 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r12]! + vst1.8 {q2, q3}, [r12]! + vst1.8 {q4, q5}, [r12]! + vst1.8 {q6, q7}, [r12]! + vst1.8 {q8, q9}, [r12]! + vst1.8 {q10, q11}, [r12]! + add r9, r9, #192 @ linear_offset = linear_offset+192 + + stmfd sp!, {r9-r12, r14} @ backup registers + sub r10, r11, #192 + mov r11, r14 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_192: + cmp r11, #128 + ble LOOP_HEIGHT_256_RIGHT_128 + add r12, r10, #2048 + pld [r12] + vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r12, #32] + vld1.8 {q2, q3}, [r10] + + add r14, r1, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r14] + vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048} + pld [r14, #32] + vld1.8 {q6, q7}, [r12] + + add r12, r0, r9 @ r12 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r12]! + vst1.8 {q2, q3}, [r12]! + vst1.8 {q4, q5}, [r12]! + vst1.8 {q6, q7}, [r12]! + add r9, r9, #128 @ linear_offset = linear_offset+128 + + stmfd sp!, {r9-r12, r14} @ backup registers + sub r10, r11, #128 + mov r11, r14 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_128: + cmp r11, #64 + ble LOOP_HEIGHT_256_RIGHT_64 + add r14, r10, #2048 + pld [r14] + vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r14, #32] + vld1.8 {q2, q3}, [r10] + + add r12, r0, r9 @ r12 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r12]! + vst1.8 {q2, q3}, [r12]! + add r9, r9, #64 @ linear_offset = linear_offset+64 + + stmfd sp!, {r9-r12, r14} @ backup registers + sub r10, r11, #64 + mov r11, r14 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_64: + stmfd sp!, {r9-r12, r14} @ backup registers + mov r14, r11 + mov r11, r10 + mov r10, r14 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12, r14} @ restore registers + +LOOP_HEIGHT_256_RIGHT_END: + + ldr r14, [sp, #52] @ buttom + add r5, r5, #1 @ i=i+1 + sub r14, r3, r14 @ i= 64) + blt LOOP_HEIGHT_2_START + + ldr r5, [sp, #44] @ i = top +LOOP_HEIGHT_64: + ldr r6, [sp, #40] @ j = left + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r2 + mov r1, r3 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + ldr r9, [sp, #44] @ linear_offset = top + add r11, r6, #64 @ temp2 = ((j+64)>>6)<<6 + bic r11, r11, #0x3F + sub r11, r11, r6 @ temp2 = temp2-j + sub r9, r5, r9 @ linear_offset = temp1*(i-top) + mul r9, r9, r10 + and r14, r6, #0x3 @ temp4 = j&0x3 + add r7, r7, r14 @ tiled_offset = tiled_offset+temp4 + stmfd sp!, {r9-r12} @ backup parameters + mov r10, r11 + add r11, r1, r7 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12} @ restore parameters + add r9, r9, r11 @ linear_offset = linear_offset+temp2 + add r6, r6, r11 @ j = j+temp2@ + + add r14, r6, #64 + cmp r14, r12 + bgt LOOP_HEIGHT_64_1 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r2 + mov r1, r3 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + add r7, r1, r7 + vld1.8 {q0, q1}, [r7]! + vld1.8 {q2, q3}, [r7] + add r7, r0, r9 + vst1.8 {q0, q1}, [r7]! + vst1.8 {q2, q3}, [r7] + add r9, r9, #64 + add r6, r6, #64 + +LOOP_HEIGHT_64_1: + add r14, r6, #64 + cmp r14, r12 + bgt LOOP_HEIGHT_64_2 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r2 + mov r1, r3 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + add r7, r1, r7 + vld1.8 {q0, q1}, [r7]! + vld1.8 {q2, q3}, [r7] + add r7, r0, r9 + vst1.8 {q0, q1}, [r7]! + vst1.8 {q2, q3}, [r7] + add r9, r9, #64 + add r6, r6, #64 + +LOOP_HEIGHT_64_2: + cmp r6, r12 + bge LOOP_HEIGHT_64_3 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r2 + mov r1, r3 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + sub r11, r12, r6 + stmfd sp!, {r9-r12} @ backup parameters + mov r10, r11 + add r11, r1, r7 + bl MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12} @ restore parameters + +LOOP_HEIGHT_64_3: + + ldr r14, [sp, #52] @ buttom + add r5, r5, #1 @ i=i+1 + sub r14, r3, r14 @ i>6)<<6 + bic r11, r11, #0x3F + sub r11, r11, r6 @ temp2 = temp2-j + sub r9, r5, r9 @ linear_offset = temp1*(i-top) + mul r9, r10, r9 + add r9, r0, r9 @ linear_offset = linear_dst+linear_offset +LOOP_HEIGHT_2_WIDTH: + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r2 + mov r1, r3 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + + and r14, r6, #0x3 @ temp4 = j&0x3@ + add r7, r7, r14 @ tiled_offset = tiled_offset+temp4@ + add r7, r1, r7 + + ldrh r14, [r7] + strh r14, [r9], #2 + + ldr r14, [sp, #48] @ right + add r6, r6, #2 @ j=j+2 + sub r14, r2, r14 @ j= 256) + blt LOOP_HEIGHT_64_START + + ldr r5, [sp, #48] @ top +LOOP_HEIGHT_256: + ldr r6, [sp, #44] @ j = left + mov r14, r5, asr #5 @ temp4 = i>>5 + bic r12, r6, #0xFF @ temp3 = (j>>8)<<8 + mov r12, r12, asr #6 @ temp3 = temp3>>6 + and r11, r14, #0x1 @ if (temp4 & 0x1) + cmp r11, #0x1 + bne LOOP_HEIGHT_256_GET_TILED_EVEN +LOOP_HEIGHT_256_GET_TILED_ODD: + sub r7, r14, #1 @ tiled_offset = temp4-1 + add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = tiled_offset*(temp1>>6) + mul r7, r7, r10 + add r7, r7, r12 @ tiled_offset = tiled_offset+temp3 + add r7, r7, #2 @ tiled_offset = tiled_offset+2 + bic r10, r12, #0x3 @ temp1 = (temp3>>2)<<2 + add r7, r7, r10 @ tiled_offset = tiled_offset+temp1 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2 + mov r14, #8 + b LOOP_HEIGHT_256_GET_TILED_END + +LOOP_HEIGHT_256_GET_TILED_EVEN: + add r11, r4, #31 @ temp2 = ((yuv420_height+31)>>5)<<5 + bic r11, r11, #0x1F + add r10, r5, #32 @ if ((i+32)>2)<<2 + add r7, r12, r10 @ tiled_offset = temp3+temp1@ + add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = tiled_offset+temp4*(temp1>>6) + mla r7, r14, r10, r7 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #12288 @ tiled_offset1 = tiled_offset+2048*6 + mov r14, #8 + b LOOP_HEIGHT_256_GET_TILED_END + +LOOP_HEIGHT_256_GET_TILED_EVEN1: + add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7 + bic r10, r10, #0x7F + mov r10, r10, asr #6 @ tiled_offset = temp4*(temp1>>6) + mul r7, r14, r10 + add r7, r7, r12 @ tiled_offset = tiled_offset+temp3 + mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11 + add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2 + mov r14, #4 + +LOOP_HEIGHT_256_GET_TILED_END: + + ldr r12, [sp, #52] @ right + ldr r9, [sp, #48] @ top + and r10, r5, #0x1F @ temp1 = i&0x1F + add r7, r7, r10, lsl #6 @ tiled_offset = tiled_offset+64*(temp1) + add r8, r8, r10, lsl #6 @ tiled_offset1 = tiled_offset1+64*(temp1) + sub r11, r3, r6 @ temp2 = yuv420_width-left(==j)-right + sub r11, r11, r12 + sub r9, r5, r9 @ linear_offset = temp2*(i-top)/2@ + mul r9, r11, r9 + mov r9, r9, asr #1 + add r12, r6, #256 @ temp3 = ((j+256)>>8)<<8@ + bic r12, r12, #0xFF + sub r12, r12, r6 @ temp3 = temp3-j@ + and r10, r6, #0x3F @ temp1 = left(==j)&0x3F + + cmp r12, #192 @ if (temp3 > 192) + ble LOOP_HEIGHT_256_LEFT_192 + add r11, r2, r7 @ r11 = nv12t_src+tiled_offset+temp1 + add r11, r11, r10 + pld [r11] + add r12, r2, r7 @ r12 = nv12t_src+tiled_offset+2048 + pld [r11, #32] + add r12, r12, #2048 + pld [r12] + cmp r10, #0 + pld [r12, #32] + stmnefd sp!, {r8-r12, r14} @ backup registers + rsbne r10, r10, #64 + blne INTERLEAVED_MEMCOPY_UNDER_64 + ldmnefd sp!, {r8-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_256_64 + vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64} + vld2.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r11]! + vst1.8 {q2}, [r11]! + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r11]! + vst1.8 {q3}, [r11]! +LOOP_HEIGHT_256_LEFT_256_64: + add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1 + pld [r11] + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r11, #32] + vld2.8 {q6, q7}, [r12] + add r12, r11, #2048 @ r12 = nv12t_src+tiled_offset1+2048 + pld [r12] + vld2.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1, 64} + pld [r12, #32] + vld2.8 {q10, q11}, [r11] + vld2.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset1+2048, 64} + vld2.8 {q14, q15}, [r12] + + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q4}, [r11]! + vst1.8 {q6}, [r11]! + vst1.8 {q8}, [r11]! + vst1.8 {q10}, [r11]! + vst1.8 {q12}, [r11]! + vst1.8 {q14}, [r11]! + + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q5}, [r11]! + vst1.8 {q7}, [r11]! + vst1.8 {q9}, [r11]! + vst1.8 {q11}, [r11]! + vst1.8 {q13}, [r11]! + vst1.8 {q15}, [r11]! + + add r9, r9, #128 + sub r9, r9, r10, asr #1 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_192: + cmp r12, #128 @ if (temp3 > 128) + ble LOOP_HEIGHT_256_LEFT_128 + add r11, r2, r7 @ r11 = nv12t_src+tiled_offset+2048+temp1 + add r11, r11, r10 + add r11, r11, #2048 + pld [r11] + add r12, r2, r8 @ r12 = nv12t_src+tiled_offset1 + pld [r11, #32] + cmp r10, #0 + pld [r12] + stmnefd sp!, {r8-r12, r14} @ backup registers + pld [r12, #32] + rsbne r10, r10, #64 + blne INTERLEAVED_MEMCOPY_UNDER_64 + ldmnefd sp!, {r8-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_192_64 + vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+2048+temp1, 64} + vld2.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r11]! + vst1.8 {q2}, [r11]! + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r11]! + vst1.8 {q3}, [r11]! +LOOP_HEIGHT_256_LEFT_192_64: + add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+2048 + add r11, r11, #2048 + pld [r11] + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64} + pld [r11, #32] + vld2.8 {q6, q7}, [r12] + vld2.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1+2048, 64} + vld2.8 {q10, q11}, [r11] + + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q4}, [r11]! + vst1.8 {q6}, [r11]! + vst1.8 {q8}, [r11]! + vst1.8 {q10}, [r11]! + + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q5}, [r11]! + vst1.8 {q7}, [r11]! + vst1.8 {q9}, [r11]! + vst1.8 {q11}, [r11]! + + add r9, r9, #96 + sub r9, r9, r10, asr #1 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_128: + cmp r12, #64 @ if (temp3 > 64) + ble LOOP_HEIGHT_256_LEFT_64 + add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+temp1 + add r11, r11, r10 + pld [r11] + add r12, r2, r8 @ r12 = nv12t_src+tiled_offset1 + add r12, r12, #2048 + pld [r11, #32] + cmp r10, #0 + pld [r12] + stmnefd sp!, {r8-r12, r14} @ backup registers + pld [r12, #32] + rsbne r10, r10, #64 + blne INTERLEAVED_MEMCOPY_UNDER_64 + ldmnefd sp!, {r8-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_128_64 + vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64} + vld2.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r11]! + vst1.8 {q2}, [r11]! + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r11]! + vst1.8 {q3}, [r11]! +LOOP_HEIGHT_256_LEFT_128_64: + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64} + vld2.8 {q6, q7}, [r12] + + add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q4}, [r11]! + vst1.8 {q6}, [r11]! + + add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2 + add r11, r11, #32 + sub r11, r11, r10, asr #1 + vst1.8 {q5}, [r11]! + vst1.8 {q7}, [r11]! + + add r9, r9, #64 + sub r9, r9, r10, asr #1 + b LOOP_HEIGHT_256_LEFT_END + +LOOP_HEIGHT_256_LEFT_64: + add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+2048+temp1 + add r11, r11, #2048 + add r11, r11, r10 + cmp r10, #0 + pld [r11] + stmnefd sp!, {r8-r12, r14} @ backup registers + pld [r11, #32] + rsbne r10, r10, #64 + blne INTERLEAVED_MEMCOPY_UNDER_64 + ldmnefd sp!, {r8-r12, r14} @ restore registers + bne LOOP_HEIGHT_256_LEFT_64_64 + vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64} + vld2.8 {q2, q3}, [r11] + add r11, r0, r9 @ r11 = yuv420_dest+linear_offset + vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64} + vst1.8 {q2, q3}, [r11]! +LOOP_HEIGHT_256_LEFT_64_64: + add r9, r9, #32 + sub r9, r9, r10, asr #1 + +LOOP_HEIGHT_256_LEFT_END: + + ldr r12, [sp, #52] @ right + add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048 + add r10, r2, r7 @ r10 = nv12t_src+tiled_offset + pld [r10] + bic r6, r6, #0xFF @ j = (left>>8)<<8 + pld [r10, #32] + add r6, r6, #256 @ j = j + 256 + sub r11, r3, r12 @ temp2 = yuv420_width-right-256 + sub r11, r11, #256 + cmp r6, r11 + bgt LOOP_HEIGHT_256_WIDTH_END + +LOOP_HEIGHT_256_WIDTH: + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + pld [r12] + vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset, 64} + pld [r12, #32] + vld2.8 {q2, q3}, [r10] + + add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048 + add r10, r2, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r10] + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r10, #32] + vld2.8 {q6, q7}, [r12] + + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + pld [r12] + vld2.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r12, #32] + vld2.8 {q10, q11}, [r10] + + add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048 + add r10, r2, r7 + pld [r10] + vld2.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64} + pld [r10, #32] + vld2.8 {q14, q15}, [r12] + + add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r12]! + vst1.8 {q2}, [r12]! + vst1.8 {q4}, [r12]! + vst1.8 {q6}, [r12]! + vst1.8 {q8}, [r12]! + vst1.8 {q10}, [r12]! + vst1.8 {q12}, [r12]! + vst1.8 {q14}, [r12]! + add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r12]! + vst1.8 {q3}, [r12]! + vst1.8 {q5}, [r12]! + vst1.8 {q7}, [r12]! + vst1.8 {q9}, [r12]! + vst1.8 {q11}, [r12]! + vst1.8 {q13}, [r12]! + vst1.8 {q15}, [r12]! + add r9, r9, #128 @ linear_offset = linear_offset+128 + + add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048 + + add r6, r6, #256 @ j=j+256 + cmp r6, r11 @ j<=temp2 + ble LOOP_HEIGHT_256_WIDTH + +LOOP_HEIGHT_256_WIDTH_END: + + add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048 + ldr r14, [sp, #52] @ right + sub r11, r3, r6 @ temp2 = yuv420_width-right-j + sub r11, r11, r14 + cmp r11, #0 + beq LOOP_HEIGHT_256_RIGHT_END + cmp r11, #192 + ble LOOP_HEIGHT_256_RIGHT_192 + add r12, r10, #2048 + pld [r12] + vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r12, #32] + vld2.8 {q2, q3}, [r10] + + add r10, r2, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r10] + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048} + pld [r10, #32] + vld2.8 {q6, q7}, [r12] + + add r14, r10, #2048 @ r10 = nv12t_src+tiled_offset1+2048 + pld [r14] + vld2.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset1} + pld [r14, #32] + vld2.8 {q10, q11}, [r10] + + add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r12]! + vst1.8 {q2}, [r12]! + vst1.8 {q4}, [r12]! + vst1.8 {q6}, [r12]! + vst1.8 {q8}, [r12]! + vst1.8 {q10}, [r12]! + add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r12]! + vst1.8 {q3}, [r12]! + vst1.8 {q5}, [r12]! + vst1.8 {q7}, [r12]! + vst1.8 {q9}, [r12]! + vst1.8 {q11}, [r12]! + add r9, r9, #96 @ linear_offset = linear_offset+96 + + stmfd sp!, {r8-r12, r14} @ backup registers + sub r10, r11, #192 + mov r11, r14 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r8-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_192: + cmp r11, #128 + ble LOOP_HEIGHT_256_RIGHT_128 + add r12, r10, #2048 + pld [r12] + vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r12, #32] + vld2.8 {q2, q3}, [r10] + + add r14, r2, r8 @ r10 = nv12t_src+tiled_offset1 + pld [r14] + vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048} + pld [r14, #32] + vld2.8 {q6, q7}, [r12] + + add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r12]! + vst1.8 {q2}, [r12]! + vst1.8 {q4}, [r12]! + vst1.8 {q6}, [r12]! + add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r12]! + vst1.8 {q3}, [r12]! + vst1.8 {q5}, [r12]! + vst1.8 {q7}, [r12]! + add r9, r9, #64 @ linear_offset = linear_offset+64 + + stmfd sp!, {r8-r12, r14} @ backup registers + sub r10, r11, #128 + mov r11, r14 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r8-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_128: + cmp r11, #64 + ble LOOP_HEIGHT_256_RIGHT_64 + add r14, r10, #2048 + pld [r14] + vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset} + pld [r14, #32] + vld2.8 {q2, q3}, [r10] + + add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset + vst1.8 {q0}, [r12]! + vst1.8 {q2}, [r12]! + add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset + vst1.8 {q1}, [r12]! + vst1.8 {q3}, [r12]! + add r9, r9, #32 @ linear_offset = linear_offset+32 + + stmfd sp!, {r8-r12, r14} @ backup registers + sub r10, r11, #64 + mov r11, r14 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r8-r12, r14} @ restore registers + b LOOP_HEIGHT_256_RIGHT_END + +LOOP_HEIGHT_256_RIGHT_64: + stmfd sp!, {r8-r12, r14} @ backup registers + mov r14, r11 + mov r11, r10 + mov r10, r14 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r8-r12, r14} @ restore registers + +LOOP_HEIGHT_256_RIGHT_END: + + ldr r14, [sp, #56] @ buttom + add r5, r5, #1 @ i=i+1 + sub r14, r4, r14 @ i= 64) + blt LOOP_HEIGHT_2_START + + ldr r5, [sp, #48] @ i = top +LOOP_HEIGHT_64: + ldr r6, [sp, #44] @ j = left + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r3 + mov r1, r4 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + ldr r9, [sp, #48] @ linear_offset = top + ldr r12, [sp, #52] @ r12 = right + add r11, r6, #64 @ temp2 = ((j+64)>>6)<<6 + bic r11, r11, #0x3F + sub r11, r11, r6 @ temp2 = temp2-j + sub r12, r3, r12 @ temp3 = yuv420_width-right + sub r14, r12, r6 @ temp4 = temp3-left + sub r9, r5, r9 @ linear_offset = temp4*(i-top)/2 + mul r9, r9, r14 + mov r9, r9, asr #1 + and r14, r6, #0x3 @ temp4 = j&0x3 + add r7, r7, r14 @ tiled_offset = tiled_offset+temp4 + stmfd sp!, {r9-r12} @ backup parameters + mov r10, r11 + add r11, r2, r7 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12} @ restore parameters + add r9, r9, r11, asr #1 @ linear_offset = linear_offset+temp2/2 + add r6, r6, r11 @ j = j+temp2@ + + add r14, r6, #64 + cmp r14, r12 + bgt LOOP_HEIGHT_64_1 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r3 + mov r1, r4 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + add r7, r2, r7 + vld2.8 {q0, q1}, [r7]! + vld2.8 {q2, q3}, [r7] + add r7, r0, r9 + vst1.8 {q0}, [r7]! + vst1.8 {q2}, [r7] + add r7, r1, r9 + vst1.8 {q1}, [r7]! + vst1.8 {q3}, [r7] + add r9, r9, #32 + add r6, r6, #64 + +LOOP_HEIGHT_64_1: + add r14, r6, #64 + cmp r14, r12 + bgt LOOP_HEIGHT_64_2 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r3 + mov r1, r4 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + add r7, r2, r7 + vld2.8 {q0, q1}, [r7]! + vld2.8 {q2, q3}, [r7] + add r7, r0, r9 + vst1.8 {q0}, [r7]! + vst1.8 {q2}, [r7] + add r7, r1, r9 + vst1.8 {q1}, [r7]! + vst1.8 {q3}, [r7] + add r9, r9, #32 + add r6, r6, #64 + +LOOP_HEIGHT_64_2: + cmp r6, r12 + bge LOOP_HEIGHT_64_3 + stmfd sp!, {r0-r3, r12} @ backup parameters + mov r0, r3 + mov r1, r4 + mov r2, r6 + mov r3, r5 + bl tile_4x2_read_asm + mov r7, r0 + ldmfd sp!, {r0-r3, r12} @ restore parameters + sub r11, r12, r6 + stmfd sp!, {r9-r12} @ backup parameters + mov r10, r11 + add r11, r2, r7 + bl INTERLEAVED_MEMCOPY_UNDER_64 + ldmfd sp!, {r9-r12} @ restore parameters + +LOOP_HEIGHT_64_3: + + ldr r14, [sp, #56] @ buttom + add r5, r5, #1 @ i=i+1 + sub r14, r4, r14 @ i> 4) << 4; + + for (i = 0; i < aligned_height; i = i + 16) { + for (j = 0; j> 4) << 4; + + for (i = 0; i < aligned_height; i = i + 8) { + for (j = 0; j> 4) << 4; + + for (i = 0; i < aligned_height; i = i + 8) { + for (j = 0; j> 1) * i + (j >> 1); + for (k = 0; k < 4; k++) { + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, 16); + src_offset += 16; + dst_offset += width >> 1; + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, 16); + src_offset += 16; + dst_offset += width >> 1; + } + } + if (aligned_width != width) { + src_offset = (tiled_width * i) + (j << 3); + dst_offset = (width >> 1) * i + (j >> 1); + for (k = 0; k < 4; k++) { + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, width - j); + src_offset += 16; + dst_offset += width >> 1; + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, width - j); + src_offset += 16; + dst_offset += width >> 1; + } + } + } + if (aligned_height != height) { + for (j = 0; j> 1) * i + (j >> 1); + for (k = 0; k < height - aligned_height; k = k + 1) { + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, 16); + src_offset += 16; + dst_offset += width >> 1; + } + } + if (aligned_width != width) { + src_offset = (tiled_width * i) + (j << 3); + dst_offset = (width >> 1) * i + (j >> 1); + for (k = 0; k < height - aligned_height; k = k + 1) { + csc_deinterleave_memcpy(u_dst + dst_offset, v_dst + dst_offset, + uv_src + src_offset, width - j); + src_offset += 16; + dst_offset += width >> 1; + } + } + } +} + +/* + * Converts linear data to tiled + * It supports mfc 6.x tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height) +{ + +} + +/* + * Converts and interleaves linear data to tiled + * It supports mfc 6.x tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height) +{ + +} + +void Tile2D_To_YUV420(unsigned char *Y_plane, unsigned char *Cb_plane, unsigned char *Cr_plane, + unsigned int y_addr, unsigned int c_addr, unsigned int width, unsigned int height) +{ + int x, y, j, k, l; + int out_of_width, actual_width; + unsigned int base_addr, data; + + // y: 0, 16, 32, ... + for (y = 0; y < height; y += 16) { + // x: 0, 16, 32, ... + for (x = 0; x < width; x += 16) { + out_of_width = (x + 16) > width ? 1 : 0; + base_addr = y_addr + Tile2D_To_Linear(width, height, x, y, 0); + + for (k = 0; (k < 16) && ((y + k) < height); k++) { + actual_width = out_of_width ? ((width%4)?((width%16) / 4 + 1) : ((width%16) / 4)) : 4; + for (l = 0; l < actual_width; l++) { + data = *((unsigned int*)(base_addr + 16*k + l*4)); + for (j = 0; (j < 4) && (x + l*4 + j) < width; j++) { + Y_plane[(y+k)*width + x + l*4 +j] = (data>>(8*j))&0xff; + } + } + } + } + } + + for (y = 0; y < height/2; y += 8) { + for (x = 0; x < width; x += 16) { + out_of_width = (x + 16) > width ? 1 : 0; + base_addr = c_addr + Tile2D_To_Linear(width, height/2, x, y, 1); + for (k = 0; (k < 8) && ((y+k) < height/2); k++) { + actual_width = out_of_width ? ((width%4) ? ((width%16) / 4 + 1) : ((width%16) / 4)) : 4; + for (l = 0; l < actual_width; l++) { + data = *((unsigned int*)(base_addr + 16*k + l*4)); + for (j = 0; (j < 2) && (x/2 + l*2 +j) < width/2; j++) { + Cb_plane[(y+k)*width/2 + x/2 + l*2 +j] = (data>> (8*2*j))&0xff; + Cr_plane[(y+k)*width/2 + x/2 + l*2 +j] = (data>>(8*2*j+8))&0xff; + } + } + } + } + } +} + +/* + * Converts RGB565 to YUV420P + * + * @param y_dst + * Y plane address of YUV420P[out] + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420P( + unsigned char *y_dst, + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *rgb_src, + int width, + int height) +{ + unsigned int i, j; + unsigned int tmp; + + unsigned int R, G, B; + unsigned int Y, U, V; + + unsigned int offset1 = width * height; + unsigned int offset2 = width/2 * height/2; + + unsigned short int *pSrc = (unsigned short int *)rgb_src; + + unsigned char *pDstY = (unsigned char *)y_dst; + unsigned char *pDstU = (unsigned char *)u_dst; + unsigned char *pDstV = (unsigned char *)v_dst; + + unsigned int yIndex = 0; + unsigned int uIndex = 0; + unsigned int vIndex = 0; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + tmp = pSrc[j * width + i]; + + R = (tmp & 0x0000F800) >> 8; + G = (tmp & 0x000007E0) >> 3; + B = (tmp & 0x0000001F); + B = B << 3; + + Y = ((66 * R) + (129 * G) + (25 * B) + 128); + Y = Y >> 8; + Y += 16; + + pDstY[yIndex++] = (unsigned char)Y; + + if ((j % 2) == 0 && (i % 2) == 0) { + U = ((-38 * R) - (74 * G) + (112 * B) + 128); + U = U >> 8; + U += 128; + V = ((112 * R) - (94 * G) - (18 * B) + 128); + V = V >> 8; + V += 128; + + pDstU[uIndex++] = (unsigned char)U; + pDstV[vIndex++] = (unsigned char)V; + } + } + } +} + +/* + * Converts RGB565 to YUV420SP + * + * @param y_dst + * Y plane address of YUV420SP[out] + * + * @param uv_dst + * UV plane address of YUV420SP[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + int width, + int height) +{ + unsigned int i, j; + unsigned int tmp; + + unsigned int R, G, B; + unsigned int Y, U, V; + + unsigned int offset = width * height; + + unsigned short int *pSrc = (unsigned short int *)rgb_src; + + unsigned char *pDstY = (unsigned char *)y_dst; + unsigned char *pDstUV = (unsigned char *)uv_dst; + + unsigned int yIndex = 0; + unsigned int uvIndex = 0; + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + tmp = pSrc[j * width + i]; + + R = (tmp & 0x0000F800) >> 11; + R = R * 8; + G = (tmp & 0x000007E0) >> 5; + G = G * 4; + B = (tmp & 0x0000001F); + B = B * 8; + + Y = ((66 * R) + (129 * G) + (25 * B) + 128); + Y = Y >> 8; + Y += 16; + + pDstY[yIndex++] = (unsigned char)Y; + + if ((j % 2) == 0 && (i % 2) == 0) { + U = ((-38 * R) - (74 * G) + (112 * B) + 128); + U = U >> 8; + U += 128; + V = ((112 * R) - (94 * G) - (18 * B) + 128); + V = V >> 8; + V += 128; + + pDstUV[uvIndex++] = (unsigned char)U; + pDstUV[uvIndex++] = (unsigned char)V; + } + } + } +} diff --git a/exynos/multimedia/utils/csc/exynos5/color_space_convertor.h b/exynos/multimedia/utils/csc/exynos5/color_space_convertor.h new file mode 100644 index 0000000..202011e --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/color_space_convertor.h @@ -0,0 +1,411 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file color_space_convertor.h + * @brief SEC_OMX specific define. It support MFC 6.x tiled. + * NV12T(tiled) layout: + * Each element is not pixel. It is 64x32 pixel block. + * uv pixel block is interleaved as u v u v u v ... + * y1 y2 y7 y8 y9 y10 y15 y16 + * y3 y4 y5 y6 y11 y12 y13 y14 + * y17 y18 y23 y24 y25 y26 y31 y32 + * y19 y20 y21 y22 y27 y28 y29 y30 + * uv1 uv2 uv7 uv8 uv9 uv10 uv15 uv16 + * uv3 uv4 uv5 uv6 uv11 uv12 uv13 uv14 + * YUV420Planar(linear) layout: + * Each element is not pixel. It is 64x32 pixel block. + * y1 y2 y3 y4 y5 y6 y7 y8 + * y9 y10 y11 y12 y13 y14 y15 y16 + * y17 y18 y19 y20 y21 y22 y23 y24 + * y25 y26 y27 y28 y29 y30 y31 y32 + * u1 u2 u3 u4 u5 u6 u7 u8 + * v1 v2 v3 v4 v5 v6 v7 v8 + * YUV420Semiplanar(linear) layout: + * Each element is not pixel. It is 64x32 pixel block. + * uv pixel block is interleaved as u v u v u v ... + * y1 y2 y3 y4 y5 y6 y7 y8 + * y9 y10 y11 y12 y13 y14 y15 y16 + * y17 y18 y19 y20 y21 y22 y23 y24 + * y25 y26 y27 y28 y29 y30 y31 y32 + * uv1 uv2 uv3 uv4 uv5 uv6 uv7 uv8 + * uv9 uv10 uv11 uv12 uv13 uv14 uv15 uv16 + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.12.01 : Create + */ + +#ifndef COLOR_SPACE_CONVERTOR_H_ +#define COLOR_SPACE_CONVERTOR_H_ + +/*--------------------------------------------------------------------------------*/ +/* Format Conversion API */ +/*--------------------------------------------------------------------------------*/ +/* C Code */ +/* + * De-interleaves src to dest1, dest2 + * + * @param dest1 + * Address of de-interleaved data[out] + * + * @param dest2 + * Address of de-interleaved data[out] + * + * @param src + * Address of interleaved data[in] + * + * @param src_size + * Size of interleaved data[in] + */ +void csc_deinterleave_memcpy( + unsigned char *dest1, + unsigned char *dest2, + unsigned char *src, + unsigned int src_size); + +/* + * Interleaves src1, src2 to dest + * + * @param dest + * Address of interleaved data[out] + * + * @param src1 + * Address of de-interleaved data[in] + * + * @param src2 + * Address of de-interleaved data[in] + * + * @param src_size + * Size of de-interleaved data[in] + */ +void csc_interleave_memcpy( + unsigned char *dest, + unsigned char *src1, + unsigned char *src2, + unsigned int src_size); + +/* + * Converts tiled data to linear + * It supports mfc 6.x tiled + * 1. y of nv12t to y of yuv420p + * 2. y of nv12t to y of yuv420s + * + * @param dst + * y address of yuv420[out] + * + * @param src + * y address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_tiled_to_linear_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear + * It supports mfc 6.x tiled + * 1. uv of nv12t to y of yuv420s + * + * @param dst + * uv address of yuv420s[out] + * + * @param src + * uv address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420s[in] + * + * @param yuv420_height + * real height of yuv420s[in] + * + */ +void csc_tiled_to_linear_uv( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear + * It supports mfc 6.x tiled + * 1. uv of nt12t to uv of yuv420p + * + * @param u_dst + * u address of yuv420p[out] + * + * @param v_dst + * v address of yuv420p[out] + * + * @param uv_src + * uv address of nt12t[in] + * + * @param yuv420_width + * real width of yuv420p[in] + * + * @param yuv420_height + * real height of yuv420p[in] + */ +void csc_tiled_to_linear_uv_deinterleave( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts linear data to tiled + * It supports mfc 6.x tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts and interleaves linear data to tiled + * It supports mfc 6.x tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of nv12t[out] + * + * @param src + * u address of yuv420[in] + * + * @param src + * v address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv( + unsigned char *uv_dst, + unsigned char *u_src, + unsigned char *v_src, + unsigned int width, + unsigned int height); + +/* + * Converts RGB565 to YUV420P + * + * @param y_dst + * Y plane address of YUV420P[out] + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420P( + unsigned char *y_dst, + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *rgb_src, + int width, + int height); + +/* + * Converts RGB565 to YUV420S + * + * @param y_dst + * Y plane address of YUV420S[out] + * + * @param uv_dst + * UV plane address of YUV420S[out] + * + * @param rgb_src + * Address of RGB565[in] + * + * @param width + * Width of RGB565[in] + * + * @param height + * Height of RGB565[in] + */ +void csc_RGB565_to_YUV420SP( + unsigned char *y_dst, + unsigned char *uv_dst, + unsigned char *rgb_src, + int width, + int height); + +/* + * Converts tiled data to linear for mfc 6.x + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * + * @param dst + * Y address of YUV420[out] + * + * @param src + * Y address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * Y: real height of YUV420[in] + * + */ +void csc_tiled_to_linear_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear for mfc 6.x + * 1. UV of NV12T to Y of YUV420S + * + * @param u_dst + * UV plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_neon( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts tiled data to linear for mfc 6.x + * Deinterleave src to u_dst, v_dst + * 1. UV of NV12T to Y of YUV420P + * + * @param u_dst + * U plane address of YUV420P[out] + * + * @param v_dst + * V plane address of YUV420P[out] + * + * @param nv12t_src + * Y or UV plane address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in] + * + * @param yuv420_height + * (real height)/2 of YUV420[in] + */ +void csc_tiled_to_linear_uv_deinterleave_neon( + unsigned char *u_dst, + unsigned char *v_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +/* + * Converts linear data to tiled + * It supports mfc 6.x tiled + * 1. y of yuv420 to y of nv12t + * + * @param dst + * y address of nv12t[out] + * + * @param src + * y address of yuv420[in] + * + * @param yuv420_width + * real width of yuv420[in] + * it should be even + * + * @param yuv420_height + * real height of yuv420[in] + * it should be even. + * + */ +void csc_linear_to_tiled_y_neon( + unsigned char *y_dst, + unsigned char *y_src, + unsigned int width, + unsigned int height); + +/* + * Converts and interleave linear data to tiled + * It supports mfc 6.x tiled + * 1. uv of nv12t to uv of yuv420 + * + * @param dst + * uv address of yuv420[out] + * + * @param src + * uv address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420[in] + * + * @param yuv420_height + * real height of yuv420[in] + * + */ +void csc_linear_to_tiled_uv_neon( + unsigned char *uv_dst, + unsigned char *uv_src, + unsigned int width, + unsigned int height); + +#endif /*COLOR_SPACE_CONVERTOR_H_*/ diff --git a/exynos/multimedia/utils/csc/exynos5/csc_fimc.cpp b/exynos/multimedia/utils/csc/exynos5/csc_fimc.cpp new file mode 100644 index 0000000..89d0f97 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_fimc.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_fimc.cpp + * + * @brief csc_fimc use fimc1 to color space convertion + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.11.01 : Create + */ + +#include +#include + +#include "SecFimc.h" +#include "csc_fimc.h" + +#define ALIGN(value, base) (((value) + (base) - 1) & ~((base) - 1)) + +unsigned int OMXtoHarPixelFomrat(OMX_COLOR_FORMATTYPE ColorFormat) +{ + unsigned int v4l2_format = 0; + switch (ColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + v4l2_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + v4l2_format = HAL_PIXEL_FORMAT_YCbCr_420_SP; + break; + default: + v4l2_format = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + } + return v4l2_format; +} + +/* + * create and open fimc handle + * + * @return + * fimc handle + */ +void *csc_fimc_open() +{ + SecFimc *(*create_instance)(); + void (*destroy_instance)(void *); + SecFimc *handle_fimc = NULL; + void* hdl = NULL; + + hdl = dlopen("libfimc.so", RTLD_NOW); + if (hdl == NULL) { + LOGE("%s:: load libfimc.so failed", __func__); + return NULL; + } + + create_instance = (SecFimc *(*)())dlsym(hdl, "create_instance"); + handle_fimc = (SecFimc *)create_instance(); + if (handle_fimc == NULL) { + LOGE("%s:: create handle_fimc failed", __func__); + return NULL; + } + + if (!handle_fimc->create(SecFimc::DEV_1, SecFimc::MODE_MULTI_BUF, 1)) { + destroy_instance = (void (*)(void *))dlsym(hdl, "destroy_instance"); + destroy_instance(handle_fimc); + LOGE("%s:: create() failed", __func__); + return NULL; + } + return (void *)handle_fimc; +} + +/* + * close and destroy fimc handle + * + * @param handle + * fimc handle[in] + * + * @return + * pass or fail + */ +CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle) +{ + void (*destroy_instance)(void *); + SecFimc *handle_fimc = (SecFimc *)handle; + void* hdl = NULL; + + if (!handle_fimc->destroy()) { + LOGE("%s:: destroy() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + hdl = dlopen("libfimc.so", RTLD_NOW); + if (hdl == NULL) { + LOGE("%s:: load libfimc.so failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + destroy_instance = (void (*)(void *))dlsym(hdl, "destroy_instance"); + destroy_instance(handle); + + return CSC_FIMC_RET_OK; +} + +/* + * convert color space nv12t to omxformat + * + * @param handle + * fimc handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * pass or fail + */ +CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat) +{ + int rotate_value = 0; + + SecFimc *handle_fimc = (SecFimc *)handle; + + unsigned int src_crop_x = 0; + unsigned int src_crop_y = 0; + unsigned int src_crop_width = width; + unsigned int src_crop_height = height; + + unsigned int dst_crop_x = 0; + unsigned int dst_crop_y = 0; + unsigned int dst_crop_width = width; + unsigned int dst_crop_height = height; + + unsigned int HarPixelformat = 0; + HarPixelformat = OMXtoHarPixelFomrat(omxformat); + + // set post processor configuration + if (!handle_fimc->setSrcParams(width, height, src_crop_x, src_crop_y, + &src_crop_width, &src_crop_height, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)) { + LOGE("%s:: setSrcParms() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + if (!handle_fimc->setSrcAddr((unsigned int)src_addr[0], + (unsigned int)src_addr[1], + (unsigned int)src_addr[1], + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)) { + LOGE("%s:: setSrcPhyAddr() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + if (!handle_fimc->setRotVal(rotate_value)) { + LOGE("%s:: setRotVal() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + if (!handle_fimc->setDstParams(width, height, dst_crop_x, dst_crop_y, + &dst_crop_width, &dst_crop_height, + HarPixelformat)) { + LOGE("%s:: setDstParams() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + switch (omxformat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + if (!handle_fimc->setDstAddr((unsigned int)(dst_addr[0]), + (unsigned int)(dst_addr[1]), + (unsigned int)(dst_addr[1]))) { + LOGE("%s:: setDstPhyAddr() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + break; + case OMX_COLOR_FormatYUV420Planar: + default: + if (!handle_fimc->setDstAddr((unsigned int)(dst_addr[0]), + (unsigned int)(dst_addr[1]), + (unsigned int)(dst_addr[2]))) { + LOGE("%s:: setDstPhyAddr() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + break; + } + + if (!handle_fimc->draw(0, 0)) { + LOGE("%s:: handleOneShot() failed", __func__); + return CSC_FIMC_RET_FAIL; + } + + return CSC_FIMC_RET_OK; +} diff --git a/exynos/multimedia/utils/csc/exynos5/csc_fimc.h b/exynos/multimedia/utils/csc/exynos5/csc_fimc.h new file mode 100644 index 0000000..3ae24ac --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_fimc.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_fimc.h + * + * @brief csc_fimc use fimc1 to color space convertion + * + * @author ShinWon Lee (shinwon.lee@samsung.com) + * + * @version 1.0 + * + * @history + * 2011.11.01 : Create + */ + +#ifndef CSC_FIMC_H + +#define CSC_FIMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + CSC_FIMC_RET_OK = 0, + CSC_FIMC_RET_FAIL = -1 +} CSC_FIMC_ERROR_CODE; + +/*--------------------------------------------------------------------------------*/ +/* CSC FIMC APIs */ +/*--------------------------------------------------------------------------------*/ +/* + * create and open fimc handle + * + * @return + * fimc handle + */ +void *csc_fimc_open(); + +/* + * close and destroy fimc handle + * + * @param handle + * fimc handle[in] + * + * @return + * error code + */ +CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle); + +/* + * convert color space nv12t to omxformat + * + * @param handle + * fimc handle[in] + * + * @param dst_addr + * y,u,v address of dst_addr[out] + * + * @param src_addr + * y,uv address of src_addr.Format is nv12t[in] + * + * @param width + * width of dst image[in] + * + * @param height + * height of dst image[in] + * + * @param omxformat + * omxformat of dst image[in] + * + * @return + * error code + */ +CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t( + void *handle, + void **dst_addr, + void **src_addr, + unsigned int width, + unsigned int height, + OMX_COLOR_FORMATTYPE omxformat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/multimedia/utils/csc/exynos5/csc_interleave_memcpy_neon.s b/exynos/multimedia/utils/csc/exynos5/csc_interleave_memcpy_neon.s new file mode 100644 index 0000000..3d2b41f --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_interleave_memcpy_neon.s @@ -0,0 +1,120 @@ +/* + * + * Copyright 2012 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_linear_to_tiled_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2012.01.04 : Create + */ + +/* + * Interleave src1, src2 to dst + * + * @param dest + * dst address[out] + * + * @param src1 + * src1 address[in] + * + * @param src2 + * src2 address[in] + * + * @param src_size + * src_size or src1 + */ + + .arch armv7-a + .text + .global csc_interleave_memcpy_neon + .type csc_interleave_memcpy_neon, %function +csc_interleave_memcpy_neon: + .fnstart + + @r0 dest + @r1 src1 + @r2 src2 + @r3 src_size + @r4 + @r5 + @r6 + @r7 + @r8 temp1 + @r9 temp2 + @r10 dest_addr + @r11 src1_addr + @r12 src2_addr + @r14 i + + stmfd sp!, {r8-r12,r14} @ backup registers + + mov r10, r0 + mov r11, r1 + mov r12, r2 + mov r14, r3 + + cmp r14, #128 + blt LESS_THAN_128 + +LOOP_128: + vld1.8 {q0}, [r11]! + vld1.8 {q2}, [r11]! + vld1.8 {q4}, [r11]! + vld1.8 {q6}, [r11]! + vld1.8 {q8}, [r11]! + vld1.8 {q10}, [r11]! + vld1.8 {q12}, [r11]! + vld1.8 {q14}, [r11]! + vld1.8 {q1}, [r12]! + vld1.8 {q3}, [r12]! + vld1.8 {q5}, [r12]! + vld1.8 {q7}, [r12]! + vld1.8 {q9}, [r12]! + vld1.8 {q11}, [r12]! + vld1.8 {q13}, [r12]! + vld1.8 {q15}, [r12]! + + vst2.8 {q0, q1}, [r10]! + vst2.8 {q2, q3}, [r10]! + vst2.8 {q4, q5}, [r10]! + vst2.8 {q6, q7}, [r10]! + vst2.8 {q8, q9}, [r10]! + vst2.8 {q10, q11}, [r10]! + vst2.8 {q12, q13}, [r10]! + vst2.8 {q14, q15}, [r10]! + + sub r14, #128 + cmp r14, #128 + bgt LOOP_128 + +LESS_THAN_128: + cmp r14, #0 + beq RESTORE_REG + +LOOP_1: + ldrb r8, [r11], #1 + ldrb r9, [r12], #1 + strb r8, [r10], #1 + strb r9, [r10], #1 + subs r14, #1 + bne LOOP_1 + +RESTORE_REG: + ldmfd sp!, {r8-r12,r15} @ restore registers + .fnend diff --git a/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_deinterleave_neon.s b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_deinterleave_neon.s new file mode 100644 index 0000000..1e76a2e --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_deinterleave_neon.s @@ -0,0 +1,249 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_tiled_to_linear_uv_deinterleave_neon.s + * @brief SEC_OMX specific define. It support MFC 6.x tiled. + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.12.01 : Create + */ + +/* + * Converts and Deinterleave tiled data to linear for mfc 6.x + * 1. UV of NV12T to Y of YUV420P + * + * @param u_dst + * U address of YUV420[out] + * + * @param v_dst + * V address of YUV420[out] + * + * @param uv_src + * UV address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in]. It should be even. + * + * @param yuv420_height + * real height of YUV420[in] It should be even. + */ + + .arch armv7-a + .text + .global csc_tiled_to_linear_uv_deinterleave_neon + .type csc_tiled_to_linear_uv_deinterleave_neon, %function +csc_tiled_to_linear_uv_deinterleave_neon: + .fnstart + + .equ CACHE_LINE_SIZE, 64 + + @r0 u_dst + @r1 v_dst + @r2 uv_src + @r3 width + @r4 height + @r5 i + @r6 j + @r7 dst_offset + @r8 src_offset + @r9 aligned_height + @r10 aligned_width + @r11 tiled_width + @r12 temp1 + @r14 temp2 + + stmfd sp!, {r4-r12,r14} @ backup registers + ldr r4, [sp, #40] @ r4 = height + + bic r9, r4, #0x7 @ aligned_height = height & (~0x7) + bic r10, r3, #0xF @ aligned_width = width & (~0xF) + add r11, r3, #15 @ tiled_width = ((width + 15) >> 4) << 4 + mov r11, r11, asr #4 + mov r11, r11, lsl #4 + + mov r5, #0 +LOOP_MAIN_ALIGNED_HEIGHT: + mul r8, r11, r5 @ src_offset = tiled_width * i + mov r6, #0 + add r8, r2, r8 @ src_offset = uv_src + src_offset +LOOP_MAIN_ALIGNED_WIDTH: + mov r12, r3, asr #1 @ temp1 = (width >> 1) * i + (j >> 1) + mul r12, r12, r5 + + pld [r8, #CACHE_LINE_SIZE] + vld2.8 {q0, q1}, [r8]! + add r12, r12, r6, asr #1 + vld2.8 {q2, q3}, [r8]! + add r7, r0, r12 @ dst_offset = u_dst + temp1 + pld [r8, #CACHE_LINE_SIZE] + vld2.8 {q4, q5}, [r8]! + mov r14, r3, asr #1 @ temp2 = width / 2 + vld2.8 {q6, q7}, [r8]! + + vst1.8 {d0}, [r7], r14 + vst1.8 {d1}, [r7], r14 + vst1.8 {d4}, [r7], r14 + vst1.8 {d5}, [r7], r14 + vst1.8 {d8}, [r7], r14 + vst1.8 {d9}, [r7], r14 + vst1.8 {d12}, [r7], r14 + vst1.8 {d13}, [r7], r14 + + add r7, r1, r12 @ dst_offset = v_dst + temp1 + + vst1.8 {d2}, [r7], r14 + vst1.8 {d3}, [r7], r14 + vst1.8 {d6}, [r7], r14 + vst1.8 {d7}, [r7], r14 + vst1.8 {d10}, [r7], r14 + vst1.8 {d11}, [r7], r14 + add r6, r6, #16 + vst1.8 {d14}, [r7], r14 + cmp r6, r10 + vst1.8 {d15}, [r7], r14 + blt LOOP_MAIN_ALIGNED_WIDTH + +MAIN_REMAIN_WIDTH_START: + cmp r10, r3 @ if (aligned_width != width) { + beq MAIN_REMAIN_WIDTH_END + stmfd sp!, {r0-r2,r4} @ backup registers + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3) + add r8, r8, r6, lsl #3 + add r8, r2, r8 @ r8 = uv_src + src_offset + mov r12, r3, asr #1 @ temp1 = (width >> 1) * i + (j >> 1) + mul r12, r12, r5 + add r12, r12, r6, asr #1 + add r7, r0, r12 @ r7 = u_dst + temp1 + add r12, r1, r12 @ r12 = v_dst + temp1 + sub r14, r3, r6 @ r14 = (width - j) / 2 + mov r14, r14, asr #1 + + mov r4, #0 +LOOP_MAIN_REMAIN_HEIGHT: + mov r0, #0 @ r0 is index in de-interleave +LOOP_MAIN_REMAIN_WIDTH: + ldrb r1, [r8], #1 + ldrb r2, [r8], #1 + strb r1, [r7], #1 + strb r2, [r12], #1 + add r0, #1 + cmp r0, r14 + blt LOOP_MAIN_REMAIN_WIDTH + + sub r8, r8, r14, lsl #1 + sub r7, r7, r14 + sub r12, r12, r14 + add r8, r8, #16 + add r7, r7, r3, asr #1 + add r12, r12, r3, asr #1 + + add r4, #1 + cmp r4, #8 + blt LOOP_MAIN_REMAIN_HEIGHT + ldmfd sp!, {r0-r2,r4} @ restore registers +MAIN_REMAIN_WIDTH_END: + + add r5, r5, #8 + cmp r5, r9 + blt LOOP_MAIN_ALIGNED_HEIGHT + +REMAIN_HEIGHT_START: + cmp r9, r4 @ if (aligned_height != height) { + beq REMAIN_HEIGHT_END + + mov r6, #0 +LOOP_REMAIN_HEIGHT_WIDTH16: + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3) + add r8, r8, r6, lsl #3 + add r8, r2, r8 @ src_offset = uv_src + src_offset + + mov r12, r3, asr #1 @ temp1 = (width >> 1) * i + (j >> 1) + mul r12, r12, r5 + add r12, r12, r6, asr #1 + add r7, r0, r12 @ r7 = u_dst + temp1 + add r12, r1, r12 @ r12 = v_dst + temp1 + mov r14, r3, asr #1 @ temp2 = width / 2 + + stmfd sp!, {r0-r1} @ backup registers + mov r0, #0 + sub r1, r4, r9 +LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1: + vld2.8 {d0, d1}, [r8]! + vst1.8 {d0}, [r7], r14 + vst1.8 {d1}, [r12], r14 + + add r0, r0, #1 + cmp r0, r1 + blt LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1 + ldmfd sp!, {r0-r1} @ restore registers + + add r6, r6, #16 + cmp r6, r10 + blt LOOP_REMAIN_HEIGHT_WIDTH16 + +REMAIN_HEIGHT_REMAIN_WIDTH_START: + cmp r10, r3 + beq REMAIN_HEIGHT_REMAIN_WIDTH_END + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3) + add r8, r8, r6, lsl #3 + add r8, r2, r8 @ src_offset = uv_src + src_offset + + mov r12, r3, asr #1 @ temp1 = (width >> 1) * i + (j >> 1) + mul r12, r12, r5 + add r12, r12, r6, asr #1 + add r7, r0, r12 @ r7 = u_dst + temp1 + add r12, r1, r12 @ r12 = v_dst + temp1 + sub r14, r3, r6 @ r14 = (width - j) /2 + mov r14, r14, asr #1 + + stmfd sp!, {r0-r2,r4-r5} @ backup registers + mov r0, #0 + sub r1, r4, r9 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1: + + mov r4, #0 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx: + ldrb r2, [r8], #1 + ldrb r5, [r8], #1 + strb r2, [r7], #1 + strb r5, [r12], #1 + add r4, #1 + cmp r4, r14 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx + + sub r8, r8, r14, lsl #1 + sub r7, r7, r14 + sub r12, r12, r14 + add r8, r8, #16 + add r7, r7, r3, asr #1 + add r12, r12, r3, asr #1 + + add r0, r0, #1 + cmp r0, r1 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1 + ldmfd sp!, {r0-r2,r4-r5} @ restore registers + +REMAIN_HEIGHT_REMAIN_WIDTH_END: + +REMAIN_HEIGHT_END: + +RESTORE_REG: + ldmfd sp!, {r4-r12,r15} @ restore registers + + .fnend diff --git a/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_neon.s b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_neon.s new file mode 100644 index 0000000..ad58419 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_uv_neon.s @@ -0,0 +1,216 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_tiled_to_linear_uv.s + * @brief SEC_OMX specific define. It support MFC 6.x tiled. + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.12.01 : Create + */ + +/* + * Converts tiled data to linear for mfc 6.x tiled + * 1. uv of nv12t to y of yuv420s + * + * @param dst + * uv address of yuv420s[out] + * + * @param src + * uv address of nv12t[in] + * + * @param yuv420_width + * real width of yuv420s[in] + * + * @param yuv420_height + * real height of yuv420s[in] + * + */ + .arch armv7-a + .text + .global csc_tiled_to_linear_uv_neon + .type csc_tiled_to_linear_uv_neon, %function +csc_tiled_to_linear_uv_neon: + .fnstart + + .equ CACHE_LINE_SIZE, 64 + + @r0 y_dst + @r1 y_src + @r2 width + @r3 height + @r4 temp3 + @r5 i + @r6 j + @r7 dst_offset + @r8 src_offset + @r9 aligned_height + @r10 aligned_width + @r11 tiled_width + @r12 temp1 + @r14 temp2 + + stmfd sp!, {r4-r12,r14} @ backup registers + ldr r4, [sp, #40] @ r4 = height + + bic r9, r3, #0x7 @ aligned_height = height & (~0xF) + bic r10, r2, #0xF @ aligned_width = width & (~0xF) + add r11, r2, #15 @ tiled_width = ((width + 15) >> 4) << 4 + mov r11, r11, asr #4 + mov r11, r11, lsl #4 + + mov r5, #0 +LOOP_MAIN_ALIGNED_HEIGHT: + mul r8, r11, r5 @ src_offset = tiled_width * i + mov r6, #0 + add r8, r1, r8 @ src_offset = y_src + src_offset +LOOP_MAIN_ALIGNED_WIDTH: + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q0, q1}, [r8]! + mul r12, r2, r5 @ temp1 = width * i + j; + vld1.8 {q2, q3}, [r8]! + add r12, r12, r6 + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q4, q5}, [r8]! + add r7, r0, r12 @ dst_offset = y_dst + temp1 + vld1.8 {q6, q7}, [r8]! + + vst1.8 {q0}, [r7], r2 + vst1.8 {q1}, [r7], r2 + vst1.8 {q2}, [r7], r2 + vst1.8 {q3}, [r7], r2 + vst1.8 {q4}, [r7], r2 + vst1.8 {q5}, [r7], r2 + vst1.8 {q6}, [r7], r2 + vst1.8 {q7}, [r7], r2 + add r6, r6, #16 + cmp r6, r10 + blt LOOP_MAIN_ALIGNED_WIDTH + +MAIN_REMAIN_WIDTH_START: + cmp r10, r2 @ if (aligned_width != width) { + beq MAIN_REMAIN_WIDTH_END + + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3); + add r8, r8, r6, lsl #3 + add r8, r1, r8 @ r8 = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + sub r14, r2, r6 @ r14 = width - j + + stmfd sp!, {r0-r1} @ backup registers + mov r1, #0 +LOOP_MAIN_REMAIN_HEIGHT: + mov r0, #0 @ r0 is index in memcpy +LOOP_MAIN_REMAIN_WIDTH: + ldrh r4, [r8], #2 + strh r4, [r7], #2 + add r0, #2 + cmp r0, r14 + blt LOOP_MAIN_REMAIN_WIDTH + + sub r8, r8, r14 + sub r7, r7, r14 + add r8, r8, #16 + add r7, r7, r2 + + add r1, #1 + cmp r1, #8 + blt LOOP_MAIN_REMAIN_HEIGHT + ldmfd sp!, {r0-r1} @ restore registers +MAIN_REMAIN_WIDTH_END: + + add r5, r5, #8 + cmp r5, r9 + blt LOOP_MAIN_ALIGNED_HEIGHT + +REMAIN_HEIGHT_START: + cmp r9, r3 @ if (aligned_height != height) { + beq REMAIN_HEIGHT_END + + mov r6, #0 +LOOP_REMAIN_HEIGHT_WIDTH16: + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3) + add r8, r8, r6, lsl #3 + add r8, r1, r8 @ src_offset = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + + sub r12, r3, r9 + mov r14, #0 +LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1: + vld1.8 {q0}, [r8]! + vld1.8 {q1}, [r8]! + vst1.8 {q0}, [r7], r2 + vst1.8 {q1}, [r7], r2 + + add r14, r14, #2 + cmp r14, r12 + blt LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1 + + add r6, r6, #16 + cmp r6, r10 + blt LOOP_REMAIN_HEIGHT_WIDTH16 + +REMAIN_HEIGHT_REMAIN_WIDTH_START: + cmp r10, r2 + beq REMAIN_HEIGHT_REMAIN_WIDTH_END + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 3) + add r8, r8, r6, lsl #3 + add r8, r1, r8 @ src_offset = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + + stmfd sp!, {r0-r1,r3} @ backup registers + mov r0, #0 + sub r1, r3, r9 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1: + + sub r14, r2, r6 + mov r4, #0 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx: + ldrh r3, [r8], #2 + strh r3, [r7], #2 + add r4, #2 + cmp r4, r14 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx + + sub r8, r8, r14 + sub r7, r7, r14 + add r8, r8, #16 + add r7, r7, r2 + + add r0, r0, #1 + cmp r0, r1 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1 + ldmfd sp!, {r0-r1,r3} @ restore registers + +REMAIN_HEIGHT_REMAIN_WIDTH_END: + +REMAIN_HEIGHT_END: + +RESTORE_REG: + ldmfd sp!, {r4-r12,r15} @ restore registers + + .fnend diff --git a/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_y_neon.s b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_y_neon.s new file mode 100644 index 0000000..1aa3b13 --- /dev/null +++ b/exynos/multimedia/utils/csc/exynos5/csc_tiled_to_linear_y_neon.s @@ -0,0 +1,231 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file csc_tiled_to_linear_y.s + * @brief SEC_OMX specific define. It support MFC 6.x tiled. + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2011.12.01 : Create + */ + +/* + * Converts tiled data to linear for mfc 6.x + * 1. Y of NV12T to Y of YUV420P + * 2. Y of NV12T to Y of YUV420S + * + * @param dst + * Y address of YUV420[out] + * + * @param src + * Y address of NV12T[in] + * + * @param yuv420_width + * real width of YUV420[in]. It should be even. + * + * @param yuv420_height + * real height of YUV420[in] It should be even. + * + */ + .arch armv7-a + .text + .global csc_tiled_to_linear_y_neon + .type csc_tiled_to_linear_y_neon, %function +csc_tiled_to_linear_y_neon: + .fnstart + + .equ CACHE_LINE_SIZE, 64 + + @r0 y_dst + @r1 y_src + @r2 width + @r3 height + @r4 temp3 + @r5 i + @r6 j + @r7 dst_offset + @r8 src_offset + @r9 aligned_height + @r10 aligned_width + @r11 tiled_width + @r12 temp1 + @r14 temp2 + + stmfd sp!, {r4-r12,r14} @ backup registers + ldr r4, [sp, #40] @ r4 = height + + bic r9, r3, #0xF @ aligned_height = height & (~0xF) + bic r10, r2, #0xF @ aligned_width = width & (~0xF) + add r11, r2, #15 @ tiled_width = ((width + 15) >> 4) << 4 + mov r11, r11, asr #4 + mov r11, r11, lsl #4 + + mov r5, #0 +LOOP_MAIN_ALIGNED_HEIGHT: + mul r8, r11, r5 @ src_offset = tiled_width * i + mov r6, #0 + add r8, r1, r8 @ src_offset = y_src + src_offset +LOOP_MAIN_ALIGNED_WIDTH: + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q0, q1}, [r8]! + vld1.8 {q2, q3}, [r8]! + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q4, q5}, [r8]! + vld1.8 {q6, q7}, [r8]! + mul r12, r2, r5 @ temp1 = width * i + j; + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q8, q9}, [r8]! + add r12, r12, r6 + vld1.8 {q10, q11}, [r8]! + add r7, r0, r12 @ dst_offset = y_dst + temp1 + pld [r8, #CACHE_LINE_SIZE] + vld1.8 {q12, q13}, [r8]! + vld1.8 {q14, q15}, [r8]! + + vst1.8 {q0}, [r7], r2 + vst1.8 {q1}, [r7], r2 + vst1.8 {q2}, [r7], r2 + vst1.8 {q3}, [r7], r2 + vst1.8 {q4}, [r7], r2 + vst1.8 {q5}, [r7], r2 + vst1.8 {q6}, [r7], r2 + vst1.8 {q7}, [r7], r2 + vst1.8 {q8}, [r7], r2 + vst1.8 {q9}, [r7], r2 + vst1.8 {q10}, [r7], r2 + vst1.8 {q11}, [r7], r2 + vst1.8 {q12}, [r7], r2 + vst1.8 {q13}, [r7], r2 + add r6, r6, #16 + vst1.8 {q14}, [r7], r2 + cmp r6, r10 + vst1.8 {q15}, [r7], r2 + blt LOOP_MAIN_ALIGNED_WIDTH + +MAIN_REMAIN_WIDTH_START: + cmp r10, r2 @ if (aligned_width != width) { + beq MAIN_REMAIN_WIDTH_END + + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 4); + add r8, r8, r6, lsl #4 + add r8, r1, r8 @ r8 = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + sub r14, r2, r6 @ r14 = width - j + + stmfd sp!, {r0-r1} @ backup registers + mov r1, #0 +LOOP_MAIN_REMAIN_HEIGHT: + mov r0, #0 @ r0 is index in memcpy +LOOP_MAIN_REMAIN_WIDTH: + ldrh r4, [r8], #2 + strh r4, [r7], #2 + add r0, #2 + cmp r0, r14 + blt LOOP_MAIN_REMAIN_WIDTH + + sub r8, r8, r14 + sub r7, r7, r14 + add r8, r8, #16 + add r7, r7, r2 + + add r1, #1 + cmp r1, #16 + blt LOOP_MAIN_REMAIN_HEIGHT + ldmfd sp!, {r0-r1} @ restore registers +MAIN_REMAIN_WIDTH_END: + + add r5, r5, #16 + cmp r5, r9 + blt LOOP_MAIN_ALIGNED_HEIGHT + +REMAIN_HEIGHT_START: + cmp r9, r3 @ if (aligned_height != height) { + beq REMAIN_HEIGHT_END + + mov r6, #0 +LOOP_REMAIN_HEIGHT_WIDTH16: + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 4) + add r8, r8, r6, lsl #4 + add r8, r1, r8 @ src_offset = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + + sub r12, r3, r9 + mov r14, #0 +LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1: + vld1.8 {q0}, [r8]! + vld1.8 {q1}, [r8]! + vst1.8 {q0}, [r7], r2 + vst1.8 {q1}, [r7], r2 + + add r14, r14, #2 + cmp r14, r12 + blt LOOP_REMAIN_HEIGHT_WIDTH16_HEIGHT1 + + add r6, r6, #16 + cmp r6, r10 + blt LOOP_REMAIN_HEIGHT_WIDTH16 + +REMAIN_HEIGHT_REMAIN_WIDTH_START: + cmp r10, r2 + beq REMAIN_HEIGHT_REMAIN_WIDTH_END + mul r8, r11, r5 @ src_offset = (tiled_width * i) + (j << 4) + add r8, r8, r6, lsl #4 + add r8, r1, r8 @ src_offset = y_src + src_offset + + mul r12, r2, r5 @ temp1 = width * i + j; + add r12, r12, r6 + add r7, r0, r12 @ r7 = y_dst + temp1 + + stmfd sp!, {r0-r1,r3} @ backup registers + mov r0, #0 + sub r1, r3, r9 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1: + + sub r14, r2, r6 + mov r4, #0 +LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx: + ldrh r3, [r8], #2 + strh r3, [r7], #2 + add r4, #2 + cmp r4, r14 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1_WIDTHx + + sub r8, r8, r14 + sub r7, r7, r14 + add r8, r8, #16 + add r7, r7, r2 + + add r0, r0, #1 + cmp r0, r1 + blt LOOP_REMAIN_HEIGHT_REMAIN_WIDTH_HEIGHT1 + ldmfd sp!, {r0-r1,r3} @ restore registers + +REMAIN_HEIGHT_REMAIN_WIDTH_END: + +REMAIN_HEIGHT_END: + +RESTORE_REG: + ldmfd sp!, {r4-r12,r15} @ restore registers + + .fnend diff --git a/exynos4/Android.mk b/exynos4/Android.mk deleted file mode 100644 index 3c99f1a..0000000 --- a/exynos4/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2012 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -ifeq ($(TARGET_BOARD_PLATFORM),exynos4) - -BOARD_HAL_PATH := hardware/samsung/exynos4/hal -BOARD_HMM_PATH := hardware/samsung/exynos4/multimedia - -include $(BOARD_HAL_PATH)/Android.mk -include $(BOARD_HMM_PATH)/Android.mk - -endif diff --git a/exynos4/exynos4210/Android.mk b/exynos4/exynos4210/Android.mk new file mode 100644 index 0000000..89f6189 --- /dev/null +++ b/exynos4/exynos4210/Android.mk @@ -0,0 +1,22 @@ +# +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +exynos4210_dirs := liblights libsensors + +include $(call all-named-subdir-makefiles,$(exynos4210_dirs)) + +endif diff --git a/exynos4/exynos4210/liblights/Android.mk b/exynos4/exynos4210/liblights/Android.mk new file mode 100644 index 0000000..995bd02 --- /dev/null +++ b/exynos4/exynos4210/liblights/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2011 The Android Open Source Project +# Copyright (C) 2011 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation, not prelinked and stored in +# hw/..so +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := lights.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_SHARED_LIBRARIES := liblog + +LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM) + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + diff --git a/exynos4/exynos4210/liblights/NOTICE b/exynos4/exynos4210/liblights/NOTICE new file mode 100644 index 0000000..f921593 --- /dev/null +++ b/exynos4/exynos4210/liblights/NOTICE @@ -0,0 +1,190 @@ + + Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/exynos4/exynos4210/liblights/lights.c b/exynos4/exynos4210/liblights/lights.c new file mode 100644 index 0000000..7cbe9d4 --- /dev/null +++ b/exynos4/exynos4210/liblights/lights.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#define LOG_TAG "lights" +#define LOG_NDEBUG 0 + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/******************************************************************************/ + +static pthread_once_t g_init = PTHREAD_ONCE_INIT; +static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; +static int g_enable_touchlight = -1; + +#ifdef EXYNOS4210_TABLET +char const*const PANEL_FILE + = "/sys/class/backlight/backlight/brightness"; +#else +char const*const PANEL_FILE + = "/sys/class/backlight/panel/brightness"; + +char const*const BUTTON_POWER + = "/sys/class/sec/sec_touchkey/enable_disable"; + +char const*const BUTTON_FILE + = "/sys/class/sec/sec_touchkey/brightness"; +#endif + +void init_globals(void) +{ + // init the mutex + pthread_mutex_init(&g_lock, NULL); +} + +void +load_settings() +{ + FILE* fp = fopen("/data/.disable_touchlight", "r"); + if (!fp) { + g_enable_touchlight = 1; + } else { + g_enable_touchlight = (int)(fgetc(fp)); + if (g_enable_touchlight == '1') + g_enable_touchlight = 1; + else + g_enable_touchlight = 0; + + fclose(fp); + } +} + +static int +write_int(char const* path, int value) +{ + int fd; + static int already_warned = 0; + + fd = open(path, O_RDWR); + if (fd >= 0) { + char buffer[20]; + int bytes = sprintf(buffer, "%d\n", value); + int amt = write(fd, buffer, bytes); + close(fd); + return amt == -1 ? -errno : 0; + } else { + if (already_warned == 0) { + LOGE("write_int failed to open %s\n", path); + already_warned = 1; + } + return -errno; + } +} + +static int +is_lit(struct light_state_t const* state) +{ + return state->color & 0x00ffffff; +} + +static int +rgb_to_brightness(struct light_state_t const* state) +{ + int color = state->color & 0x00ffffff; + return ((77*((color>>16)&0x00ff)) + + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; +} + +static int +set_light_backlight(struct light_device_t* dev, + struct light_state_t const* state) +{ + load_settings(); + + int err = 0; + int brightness = rgb_to_brightness(state); + + pthread_mutex_lock(&g_lock); + err = write_int(PANEL_FILE, brightness); + +#ifndef EXYNOS4210_TABLET + if (g_enable_touchlight == -1 || g_enable_touchlight > 0) + err = write_int(BUTTON_FILE, brightness > 0 ? 1 : 0); +#endif + + pthread_mutex_unlock(&g_lock); + + return err; +} + +static int +set_light_keyboard(struct light_device_t* dev, + struct light_state_t const* state) +{ + return 0; +} + +static int +set_light_buttons(struct light_device_t* dev, + struct light_state_t const* state) +{ +#ifdef EXYNOS4210_TABLET + return 0; +#else + + load_settings(); + + int err = 0; + + pthread_mutex_lock(&g_lock); + LOGD("set_light_button on=%d\n", g_enable_touchlight ? 1 : 0); + err = write_int(BUTTON_FILE, g_enable_touchlight ? 1 : 0); + pthread_mutex_unlock(&g_lock); + + return err; +#endif +} + +static int +set_light_battery(struct light_device_t* dev, + struct light_state_t const* state) +{ + return 0; +} + +static int +set_light_notification(struct light_device_t* dev, + struct light_state_t const* state) +{ + return 0; +} + +static int +set_light_attention(struct light_device_t* dev, + struct light_state_t const* state) +{ + return 0; +} + +static int +close_lights(struct light_device_t *dev) +{ + if (dev) { + free(dev); + } + return 0; +} + + +/******************************************************************************/ +static int open_lights(const struct hw_module_t* module, char const* name, + struct hw_device_t** device) +{ + int (*set_light)(struct light_device_t* dev, + struct light_state_t const* state); + + if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) { + set_light = set_light_backlight; + } + else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) { + set_light = set_light_keyboard; + } + else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) { + set_light = set_light_buttons; + } + else if (0 == strcmp(LIGHT_ID_BATTERY, name)) { + set_light = set_light_battery; + } + else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) { + set_light = set_light_notification; + } + else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) { + set_light = set_light_attention; + } + else { + return -EINVAL; + } + + pthread_once(&g_init, init_globals); + + struct light_device_t *dev = malloc(sizeof(struct light_device_t)); + memset(dev, 0, sizeof(*dev)); + + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = (struct hw_module_t*)module; + dev->common.close = (int (*)(struct hw_device_t*))close_lights; + dev->set_light = set_light; + + *device = (struct hw_device_t*)dev; + return 0; +} + + +static struct hw_module_methods_t lights_module_methods = { + .open = open_lights, +}; + +const struct hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = LIGHTS_HARDWARE_MODULE_ID, + .name = "Samsung Exynos4210 Lights Module", + .author = "The CyanogenMod Project", + .methods = &lights_module_methods, +}; diff --git a/exynos4/exynos4210/libsensors/AkmSensor.cpp b/exynos4/exynos4210/libsensors/AkmSensor.cpp new file mode 100644 index 0000000..98a17cb --- /dev/null +++ b/exynos4/exynos4210/libsensors/AkmSensor.cpp @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ak8973b.h" + +#include +#include "AkmSensor.h" + +//#define LOG_NDEBUG 0 + +/*****************************************************************************/ + +int (*akm_is_sensor_enabled)(uint32_t sensor_type); +int (*akm_enable_sensor)(uint32_t sensor_type); +int (*akm_disable_sensor)(uint32_t sensor_type); +int (*akm_set_delay)(uint32_t sensor_type, uint64_t delay); + +int stub_is_sensor_enabled(uint32_t sensor_type) { + return 0; +} + +int stub_enable_disable_sensor(uint32_t sensor_type) { + return -ENODEV; +} + +int stub_set_delay(uint32_t sensor_type, uint64_t delay) { + return -ENODEV; +} + +AkmSensor::AkmSensor() +: SensorBase(NULL, NULL), + mEnabled(0), + mPendingMask(0), + mInputReader(32) +{ + /* Open the library before opening the input device. The library + * creates a uinput device. + */ + if (loadAKMLibrary() == 0) { + data_name = "compass_sensor"; + data_fd = openInput("compass_sensor"); + } + + memset(mPendingEvents, 0, sizeof(mPendingEvents)); + + mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); + mPendingEvents[Accelerometer].sensor = ID_A; + mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; + mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; + + mPendingEvents[MagneticField].version = sizeof(sensors_event_t); + mPendingEvents[MagneticField].sensor = ID_M; + mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; + mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH; + + mPendingEvents[Orientation ].version = sizeof(sensors_event_t); + mPendingEvents[Orientation ].sensor = ID_O; + mPendingEvents[Orientation ].type = SENSOR_TYPE_ORIENTATION; + mPendingEvents[Orientation ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH; + + // read the actual value of all sensors if they're enabled already + struct input_absinfo absinfo; + short flags = 0; + + if (akm_is_sensor_enabled(SENSOR_TYPE_ACCELEROMETER)) { + mEnabled |= 1<= numSensors) + return -EINVAL; + + int newState = en ? 1 : 0; + int err = 0; + + if ((uint32_t(newState)<type; + if (type == EV_REL) { + processEvent(event->code, event->value); + mInputReader.next(); + } else if (type == EV_SYN) { + int64_t time = timevalToNano(event->time); + for (int j=0 ; count && mPendingMask && jcode); + mInputReader.next(); + } + } + return numEventReceived; +} + +void AkmSensor::processEvent(int code, int value) +{ + switch (code) { + case EVENT_TYPE_ACCEL_X: + mPendingMask |= 1< +#include +#include +#include + + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class AkmSensor : public SensorBase { +public: + AkmSensor(); + virtual ~AkmSensor(); + + enum { + Accelerometer = 0, + MagneticField = 1, + Orientation = 2, + numSensors + }; + + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); + virtual int readEvents(sensors_event_t* data, int count); + void processEvent(int code, int value); + +private: + int loadAKMLibrary(); + int update_delay(); + void *mLibAKM; + uint32_t mEnabled; + uint32_t mPendingMask; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvents[numSensors]; + uint64_t mDelays[numSensors]; +}; + +/*****************************************************************************/ + +#endif // ANDROID_AKM_SENSOR_H diff --git a/exynos4/exynos4210/libsensors/Android.mk b/exynos4/exynos4210/libsensors/Android.mk new file mode 100644 index 0000000..15c29a2 --- /dev/null +++ b/exynos4/exynos4210/libsensors/Android.mk @@ -0,0 +1,45 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +LOCAL_PATH := $(call my-dir) + +ifneq ($(TARGET_SIMULATOR),true) + +# HAL module implemenation, not prelinked, and stored in +# hw/..so +include $(CLEAR_VARS) + +LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM) + +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\" +LOCAL_SRC_FILES := \ + sensors.cpp \ + SensorBase.cpp \ + LightSensor.cpp \ + ProximitySensor.cpp \ + AkmSensor.cpp \ + GyroSensor.cpp \ + InputEventReader.cpp + +LOCAL_SHARED_LIBRARIES := liblog libcutils libdl +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif # !TARGET_SIMULATOR diff --git a/exynos4/exynos4210/libsensors/GyroSensor.cpp b/exynos4/exynos4210/libsensors/GyroSensor.cpp new file mode 100644 index 0000000..ef0c01c --- /dev/null +++ b/exynos4/exynos4210/libsensors/GyroSensor.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GyroSensor.h" + +#define FETCH_FULL_EVENT_BEFORE_RETURN 1 +#define IGNORE_EVENT_TIME 350000000 +/*****************************************************************************/ + +GyroSensor::GyroSensor() + : SensorBase(NULL, "gyro_sensor"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false), + mEnabledTime(0) +{ + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_GY; + mPendingEvent.type = SENSOR_TYPE_GYROSCOPE; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + enable(0, 1); + } +} + +GyroSensor::~GyroSensor() { + if (mEnabled) { + enable(0, 0); + } +} + +int GyroSensor::setInitialState() { + struct input_absinfo absinfo_x; + struct input_absinfo absinfo_y; + struct input_absinfo absinfo_z; + float value; + if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_x) && + !ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_y) && + !ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_z)) { + value = absinfo_x.value; + mPendingEvent.data[0] = value * CONVERT_GYRO_X; + value = absinfo_x.value; + mPendingEvent.data[1] = value * CONVERT_GYRO_Y; + value = absinfo_x.value; + mPendingEvent.data[2] = value * CONVERT_GYRO_Z; + mHasPendingEvent = true; + } + return 0; +} + +int GyroSensor::enable(int32_t, int en) { + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + setInitialState(); + return 0; + } + return -1; + } + return 0; +} + +bool GyroSensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int GyroSensor::setDelay(int32_t handle, int64_t delay_ns) +{ + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%lld", delay_ns); + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + +int GyroSensor::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + +#if FETCH_FULL_EVENT_BEFORE_RETURN +again: +#endif + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_REL) { + float value = event->value; + if (event->code == EVENT_TYPE_GYRO_X) { + mPendingEvent.data[0] = value * CONVERT_GYRO_X; + } else if (event->code == EVENT_TYPE_GYRO_Y) { + mPendingEvent.data[1] = value * CONVERT_GYRO_Y; + } else if (event->code == EVENT_TYPE_GYRO_Z) { + mPendingEvent.data[2] = value * CONVERT_GYRO_Z; + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + if (mPendingEvent.timestamp >= mEnabledTime) { + *data++ = mPendingEvent; + numEventReceived++; + } + count--; + } + } else { + LOGE("GyroSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + +#if FETCH_FULL_EVENT_BEFORE_RETURN + /* if we didn't read a complete event, see if we can fill and + try again instead of returning with nothing and redoing poll. */ + if (numEventReceived == 0 && mEnabled == 1) { + n = mInputReader.fill(data_fd); + if (n) + goto again; + } +#endif + + return numEventReceived; +} + diff --git a/exynos4/exynos4210/libsensors/GyroSensor.h b/exynos4/exynos4210/libsensors/GyroSensor.h new file mode 100644 index 0000000..e8997de --- /dev/null +++ b/exynos4/exynos4210/libsensors/GyroSensor.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GYRO_SENSOR_H +#define ANDROID_GYRO_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class GyroSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + int64_t mEnabledTime; + + int setInitialState(); + +public: + GyroSensor(); + virtual ~GyroSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_GYRO_SENSOR_H diff --git a/exynos4/exynos4210/libsensors/InputEventReader.cpp b/exynos4/exynos4210/libsensors/InputEventReader.cpp new file mode 100644 index 0000000..1014f29 --- /dev/null +++ b/exynos4/exynos4210/libsensors/InputEventReader.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +InputEventCircularReader::InputEventCircularReader(size_t numEvents) + : mBuffer(new input_event[numEvents * 2]), + mBufferEnd(mBuffer + numEvents), + mHead(mBuffer), + mCurr(mBuffer), + mFreeSpace(numEvents) +{ +} + +InputEventCircularReader::~InputEventCircularReader() +{ + delete [] mBuffer; +} + +ssize_t InputEventCircularReader::fill(int fd) +{ + size_t numEventsRead = 0; + if (mFreeSpace) { + const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); + if (nread<0 || nread % sizeof(input_event)) { + // we got a partial event!! + return nread<0 ? -errno : -EINVAL; + } + + numEventsRead = nread / sizeof(input_event); + if (numEventsRead) { + mHead += numEventsRead; + mFreeSpace -= numEventsRead; + if (mHead > mBufferEnd) { + size_t s = mHead - mBufferEnd; + memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); + mHead = mBuffer + s; + } + } + } + + return numEventsRead; +} + +ssize_t InputEventCircularReader::readEvent(input_event const** events) +{ + *events = mCurr; + ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; + return available ? 1 : 0; +} + +void InputEventCircularReader::next() +{ + mCurr++; + mFreeSpace++; + if (mCurr >= mBufferEnd) { + mCurr = mBuffer; + } +} diff --git a/exynos4/exynos4210/libsensors/InputEventReader.h b/exynos4/exynos4210/libsensors/InputEventReader.h new file mode 100644 index 0000000..180aade --- /dev/null +++ b/exynos4/exynos4210/libsensors/InputEventReader.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INPUT_EVENT_READER_H +#define ANDROID_INPUT_EVENT_READER_H + +#include +#include +#include +#include + +/*****************************************************************************/ + +struct input_event; + +class InputEventCircularReader +{ + struct input_event* const mBuffer; + struct input_event* const mBufferEnd; + struct input_event* mHead; + struct input_event* mCurr; + ssize_t mFreeSpace; + +public: + InputEventCircularReader(size_t numEvents); + ~InputEventCircularReader(); + ssize_t fill(int fd); + ssize_t readEvent(input_event const** events); + void next(); +}; + +/*****************************************************************************/ + +#endif // ANDROID_INPUT_EVENT_READER_H diff --git a/exynos4/exynos4210/libsensors/LightSensor.cpp b/exynos4/exynos4210/libsensors/LightSensor.cpp new file mode 100644 index 0000000..1d4f0e4 --- /dev/null +++ b/exynos4/exynos4210/libsensors/LightSensor.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "LightSensor.h" + +// #define LOG_NDEBUG 0 + +/*****************************************************************************/ + +LightSensor::LightSensor() + : SensorBase(NULL, "light_sensor"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_L; + mPendingEvent.type = SENSOR_TYPE_LIGHT; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + enable(0, 1); + } +} + +LightSensor::~LightSensor() { + if (mEnabled) { + enable(0, 0); + } +} + +int LightSensor::setInitialState() { + struct input_absinfo absinfo; + if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_LIGHT), &absinfo)) { + // make sure to report an event immediately + mHasPendingEvent = true; + mPendingEvent.light = absinfo.value; + } + return 0; +} + +int LightSensor::setDelay(int32_t handle, int64_t ns) +{ + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%lld", ns); + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + +int LightSensor::enable(int32_t handle, int en) +{ + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + return 0; + } + return -1; + } + return 0; +} + +bool LightSensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int LightSensor::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + if (event->code == EVENT_TYPE_LIGHT) { + if (event->value != -1) { + LOGV("LightSensor: event (value=%d)", event->value); + // FIXME: not sure why we're getting -1 sometimes + mPendingEvent.light = event->value; + } + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + LOGE("LightSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + return numEventReceived; +} diff --git a/exynos4/exynos4210/libsensors/LightSensor.h b/exynos4/exynos4210/libsensors/LightSensor.h new file mode 100644 index 0000000..85e65d9 --- /dev/null +++ b/exynos4/exynos4210/libsensors/LightSensor.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_LIGHT_SENSOR_H +#define ANDROID_LIGHT_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class LightSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + float indexToValue(size_t index) const; + int setInitialState(); + +public: + LightSensor(); + virtual ~LightSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_LIGHT_SENSOR_H diff --git a/exynos4/exynos4210/libsensors/MODULE_LICENSE_APACHE2 b/exynos4/exynos4210/libsensors/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 diff --git a/exynos4/exynos4210/libsensors/ProximitySensor.cpp b/exynos4/exynos4210/libsensors/ProximitySensor.cpp new file mode 100644 index 0000000..46424a5 --- /dev/null +++ b/exynos4/exynos4210/libsensors/ProximitySensor.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "ProximitySensor.h" + +/*****************************************************************************/ + +ProximitySensor::ProximitySensor() + : SensorBase(NULL, "proximity_sensor"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_P; + mPendingEvent.type = SENSOR_TYPE_PROXIMITY; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + enable(0, 1); + } +} + +ProximitySensor::~ProximitySensor() { + if (mEnabled) { + enable(0, 0); + } +} + +int ProximitySensor::setInitialState() { + struct input_absinfo absinfo; + if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo)) { + // make sure to report an event immediately + mHasPendingEvent = true; + mPendingEvent.distance = indexToValue(absinfo.value); + } + return 0; +} + +int ProximitySensor::enable(int32_t, int en) { + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[2]; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + setInitialState(); + return 0; + } + return -1; + } + return 0; +} + +bool ProximitySensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int ProximitySensor::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + if (event->code == EVENT_TYPE_PROXIMITY) { + mPendingEvent.distance = indexToValue(event->value); + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + LOGE("ProximitySensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + return numEventReceived; +} + +float ProximitySensor::indexToValue(size_t index) const +{ + LOGV("ProximitySensor: Index = %zu", index); + return index * PROXIMITY_THRESHOLD_CM; +} diff --git a/exynos4/exynos4210/libsensors/ProximitySensor.h b/exynos4/exynos4210/libsensors/ProximitySensor.h new file mode 100644 index 0000000..08ea49c --- /dev/null +++ b/exynos4/exynos4210/libsensors/ProximitySensor.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROXIMITY_SENSOR_H +#define ANDROID_PROXIMITY_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class ProximitySensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + int setInitialState(); + float indexToValue(size_t index) const; + +public: + ProximitySensor(); + virtual ~ProximitySensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_PROXIMITY_SENSOR_H diff --git a/exynos4/exynos4210/libsensors/SensorBase.cpp b/exynos4/exynos4210/libsensors/SensorBase.cpp new file mode 100644 index 0000000..d448eb2 --- /dev/null +++ b/exynos4/exynos4210/libsensors/SensorBase.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "SensorBase.h" + +/*****************************************************************************/ + +SensorBase::SensorBase( + const char* dev_name, + const char* data_name) + : dev_name(dev_name), data_name(data_name), + dev_fd(-1), data_fd(-1) +{ + if (data_name) { + data_fd = openInput(data_name); + } +} + +SensorBase::~SensorBase() { + if (data_fd >= 0) { + close(data_fd); + } + if (dev_fd >= 0) { + close(dev_fd); + } +} + +int SensorBase::open_device() { + if (dev_fd<0 && dev_name) { + dev_fd = open(dev_name, O_RDONLY); + LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno)); + } + return 0; +} + +int SensorBase::close_device() { + if (dev_fd >= 0) { + close(dev_fd); + dev_fd = -1; + } + return 0; +} + +int SensorBase::getFd() const { + if (!data_name) { + return dev_fd; + } + return data_fd; +} + +int SensorBase::setDelay(int32_t handle, int64_t ns) { + return 0; +} + +bool SensorBase::hasPendingEvents() const { + return false; +} + +int64_t SensorBase::getTimestamp() { + struct timespec t; + t.tv_sec = t.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &t); + return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; +} + +int SensorBase::openInput(const char* inputName) { + int fd = -1; + const char *dirname = "/dev/input"; + char devname[PATH_MAX]; + char *filename; + DIR *dir; + struct dirent *de; + dir = opendir(dirname); + if(dir == NULL) + return -1; + strcpy(devname, dirname); + filename = devname + strlen(devname); + *filename++ = '/'; + while((de = readdir(dir))) { + if(de->d_name[0] == '.' && + (de->d_name[1] == '\0' || + (de->d_name[1] == '.' && de->d_name[2] == '\0'))) + continue; + strcpy(filename, de->d_name); + fd = open(devname, O_RDONLY); + if (fd>=0) { + char name[80]; + if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { + name[0] = '\0'; + } + if (!strcmp(name, inputName)) { + strcpy(input_name, filename); + break; + } else { + close(fd); + fd = -1; + } + } + } + closedir(dir); + LOGE_IF(fd<0, "couldn't find '%s' input device", inputName); + return fd; +} diff --git a/exynos4/exynos4210/libsensors/SensorBase.h b/exynos4/exynos4210/libsensors/SensorBase.h new file mode 100644 index 0000000..bb4d055 --- /dev/null +++ b/exynos4/exynos4210/libsensors/SensorBase.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SENSOR_BASE_H +#define ANDROID_SENSOR_BASE_H + +#include +#include +#include +#include + + +/*****************************************************************************/ + +struct sensors_event_t; + +class SensorBase { +protected: + const char* dev_name; + const char* data_name; + char input_name[PATH_MAX]; + int dev_fd; + int data_fd; + + int openInput(const char* inputName); + static int64_t getTimestamp(); + + + static int64_t timevalToNano(timeval const& t) { + return t.tv_sec*1000000000LL + t.tv_usec*1000; + } + + int open_device(); + int close_device(); + +public: + SensorBase( + const char* dev_name, + const char* data_name); + + virtual ~SensorBase(); + + virtual int readEvents(sensors_event_t* data, int count) = 0; + virtual bool hasPendingEvents() const; + virtual int getFd() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled) = 0; +}; + +/*****************************************************************************/ + +#endif // ANDROID_SENSOR_BASE_H diff --git a/exynos4/exynos4210/libsensors/ak8973b.h b/exynos4/exynos4210/libsensors/ak8973b.h new file mode 100644 index 0000000..9b7ab60 --- /dev/null +++ b/exynos4/exynos4210/libsensors/ak8973b.h @@ -0,0 +1,51 @@ +/* + * Definitions for akm8973 compass chip. + */ +#ifndef AKM8973_H +#define AKM8973_H + +#include + +#define AKM8973_I2C_NAME "ak8973b" + +#define AKMIO 0xA1 + +/* IOCTLs for AKM library */ +#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char*) +#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char*) +#define ECS_IOCTL_RESET _IO(AKMIO, 0x03) +#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x04, short) +#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[SENSOR_DATA_SIZE]) +#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12]) +#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int) +#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int) +#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, int64_t) +#define ECS_IOCTL_GET_PROJECT_NAME _IOR(AKMIO, 0x0D, char[64]) +#define ECS_IOCTL_GET_MATRIX _IOR(AKMIO, 0x0E, short [4][3][3]) + +/* IOCTLs for APPs */ +#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short) +#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short) +#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short) +#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short) +#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short) +#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short) +#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short) +#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17) +#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, int64_t) +#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY + +/* Set raw magnetic vector flag */ +#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short) + +/* Get raw magnetic vector flag */ +#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short) + +struct akm8973_platform_data { + short layouts[4][3][3]; + char project_name[64]; + int gpio_RST; + int gpio_INT; +}; + +#endif diff --git a/exynos4/exynos4210/libsensors/sensors.cpp b/exynos4/exynos4210/libsensors/sensors.cpp new file mode 100644 index 0000000..6f0bdad --- /dev/null +++ b/exynos4/exynos4210/libsensors/sensors.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "Sensors" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "sensors.h" + +#include "LightSensor.h" +#include "ProximitySensor.h" +#include "AkmSensor.h" +#include "GyroSensor.h" + +/*****************************************************************************/ + +#define DELAY_OUT_TIME 0x7FFFFFFF + +#define LIGHT_SENSOR_POLLTIME 2000000000 + + +#define SENSORS_ACCELERATION (1<getFd(); + mPollFds[light].events = POLLIN; + mPollFds[light].revents = 0; + + mSensors[proximity] = new ProximitySensor(); + mPollFds[proximity].fd = mSensors[proximity]->getFd(); + mPollFds[proximity].events = POLLIN; + mPollFds[proximity].revents = 0; + + mSensors[akm] = new AkmSensor(); + mPollFds[akm].fd = mSensors[akm]->getFd(); + mPollFds[akm].events = POLLIN; + mPollFds[akm].revents = 0; + + mSensors[gyro] = new GyroSensor(); + mPollFds[gyro].fd = mSensors[gyro]->getFd(); + mPollFds[gyro].events = POLLIN; + mPollFds[gyro].revents = 0; + + int wakeFds[2]; + int result = pipe(wakeFds); + LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); + fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); + fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); + mWritePipeFd = wakeFds[1]; + + mPollFds[wake].fd = wakeFds[0]; + mPollFds[wake].events = POLLIN; + mPollFds[wake].revents = 0; +} + +sensors_poll_context_t::~sensors_poll_context_t() { + for (int i=0 ; ienable(handle, enabled); + if (enabled && !err) { + const char wakeMessage(WAKE_MESSAGE); + int result = write(mWritePipeFd, &wakeMessage, 1); + LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); + } + return err; +} + +int sensors_poll_context_t::setDelay(int handle, int64_t ns) { + + int index = handleToDriver(handle); + if (index < 0) return index; + return mSensors[index]->setDelay(handle, ns); +} + +int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) +{ + int nbEvents = 0; + int n = 0; + + do { + // see if we have some leftover from the last poll() + for (int i=0 ; count && ihasPendingEvents())) { + int nb = sensor->readEvents(data, count); + if (nb < count) { + // no more data for this sensor + mPollFds[i].revents = 0; + } + count -= nb; + nbEvents += nb; + data += nb; + } + } + + if (count) { + // we still have some room, so try to see if we can get + // some events immediately or just wait if we don't have + // anything to return + n = poll(mPollFds, numFds, nbEvents ? 0 : -1); + if (n<0) { + LOGE("poll() failed (%s)", strerror(errno)); + return -errno; + } + if (mPollFds[wake].revents & POLLIN) { + char msg; + int result = read(mPollFds[wake].fd, &msg, 1); + LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); + LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); + mPollFds[wake].revents = 0; + } + } + // if we have events and space, go read them + } while (n && count); + + return nbEvents; +} + +/*****************************************************************************/ + +static int poll__close(struct hw_device_t *dev) +{ + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + if (ctx) { + delete ctx; + } + return 0; +} + +static int poll__activate(struct sensors_poll_device_t *dev, + int handle, int enabled) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->activate(handle, enabled); +} + +static int poll__setDelay(struct sensors_poll_device_t *dev, + int handle, int64_t ns) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->setDelay(handle, ns); +} + +static int poll__poll(struct sensors_poll_device_t *dev, + sensors_event_t* data, int count) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->pollEvents(data, count); +} + +/*****************************************************************************/ + +/** Open a new instance of a sensor device using name */ +static int open_sensors(const struct hw_module_t* module, const char* id, + struct hw_device_t** device) +{ + int status = -EINVAL; + sensors_poll_context_t *dev = new sensors_poll_context_t(); + + memset(&dev->device, 0, sizeof(sensors_poll_device_t)); + + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = poll__close; + dev->device.activate = poll__activate; + dev->device.setDelay = poll__setDelay; + dev->device.poll = poll__poll; + + *device = &dev->device.common; + status = 0; + + return status; +} + diff --git a/exynos4/exynos4210/libsensors/sensors.h b/exynos4/exynos4210/libsensors/sensors.h new file mode 100644 index 0000000..ecc6fed --- /dev/null +++ b/exynos4/exynos4210/libsensors/sensors.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SENSORS_H +#define ANDROID_SENSORS_H + +#include +#include +#include +#include + +#include + +#include +#include + +__BEGIN_DECLS + +/*****************************************************************************/ + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define ID_A (0) +#define ID_M (1) +#define ID_O (2) +#define ID_L (3) +#define ID_P (4) +#define ID_GY (5) + +/*****************************************************************************/ + +/* + * The SENSORS Module + */ + +/* the CM3663 is a binary proximity sensor that triggers around 6 cm on + * this hardware */ +#define PROXIMITY_THRESHOLD_CM 6.0f + +/*****************************************************************************/ + +#define AKM_DEVICE_NAME "/dev/akm8975" +#define CM_DEVICE_NAME "/dev/i2c11" // FIXME Proximity +#define LS_DEVICE_NAME "/dev/i2c11" // FIXME Lig + +/* + E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) + E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) + E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) +*/ + +// for akm8975 +#define EVENT_TYPE_ACCEL_X ABS_Y //1 +#define EVENT_TYPE_ACCEL_Y ABS_X //0 +#define EVENT_TYPE_ACCEL_Z ABS_Z //2 +//#define EVENT_TYPE_ACCEL_STATUS ABS_WHEEL //8 + +#define EVENT_TYPE_YAW ABS_RX //3 +#define EVENT_TYPE_PITCH ABS_RY //4 +#define EVENT_TYPE_ROLL ABS_RZ //5 +#define EVENT_TYPE_ORIENT_STATUS ABS_WHEEL //8 + +#define EVENT_TYPE_MAGV_X ABS_RUDDER // 6 +#define EVENT_TYPE_MAGV_Y ABS_THROTTLE // 7 +#define EVENT_TYPE_MAGV_Z ABS_GAS // 9 + +#define EVENT_TYPE_TEMPERATURE ABS_THROTTLE +#define EVENT_TYPE_STEP_COUNT ABS_GAS +#define EVENT_TYPE_PROXIMITY ABS_DISTANCE +#define EVENT_TYPE_LIGHT ABS_MISC + +#define EVENT_TYPE_GYRO_X REL_RY +#define EVENT_TYPE_GYRO_Y REL_RX +#define EVENT_TYPE_GYRO_Z REL_RZ + +// 90 LSB = 1G for KR3DM +#define LSB (90.0f) +#define NUMOFACCDATA (8.0f) + +// conversion of acceleration data to SI units (m/s^2) +#define RANGE_A (2*GRAVITY_EARTH) +#define CONVERT_A (GRAVITY_EARTH / LSB / NUMOFACCDATA) +#define CONVERT_A_X (CONVERT_A) +#define CONVERT_A_Y (-CONVERT_A) +#define CONVERT_A_Z (-CONVERT_A) + +// conversion of magnetic data to uT units +#define CONVERT_M (1.0f/16.0f) +#define CONVERT_M_X (CONVERT_M) +#define CONVERT_M_Y (-CONVERT_M) +#define CONVERT_M_Z (CONVERT_M) + +/* conversion of orientation data to degree units */ +#define CONVERT_O (1.0f/64.0f) +#define CONVERT_O_A (CONVERT_O) +#define CONVERT_O_P (CONVERT_O) +#define CONVERT_O_R (-CONVERT_O) + +// conversion of gyro data to SI units (radian/sec) +#define RANGE_GYRO (2000.0f*(float)M_PI/180.0f) +#define CONVERT_GYRO ((70.0f / 1000.0f) * ((float)M_PI / 180.0f)) +#define CONVERT_GYRO_X (CONVERT_GYRO) +#define CONVERT_GYRO_Y (-CONVERT_GYRO) +#define CONVERT_GYRO_Z (CONVERT_GYRO) + +#define SENSOR_STATE_MASK (0x7FFF) + +/*****************************************************************************/ + +__END_DECLS + +#endif // ANDROID_SENSORS_H diff --git a/exynos4/hal/Android.mk b/exynos4/hal/Android.mk index c1c40da..5765418 100644 --- a/exynos4/hal/Android.mk +++ b/exynos4/hal/Android.mk @@ -1,2 +1,29 @@ -exynos4_dirs := libfimg libhwconverter liblights libs5pjpeg libsensors libswconverter libump -include $(call all-named-subdir-makefiles,$(exynos4_dirs)) +# +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +#common_exynos4_dirs := libgralloc_ump libhdmi libfimc libhwcomposer libcamera libhwconverter +common_exynos4_dirs := libgralloc_ump libhdmi libfimc libhwcomposer libhwconverter +exynos4210_dirs := $(common_exynos4_dirs) libs5pjpeg libfimg3x + +exynos4x12_dirs := $(common_exynos4_dirs) libhwjpeg libfimg4x + +ifeq ($(TARGET_SOC),exynos4210) + include $(call all-named-subdir-makefiles,$(exynos4210_dirs)) +else + include $(call all-named-subdir-makefiles,$(exynos4x12_dirs)) +endif +endif diff --git a/exynos4/hal/include/SecHdmi.h b/exynos4/hal/include/SecHdmi.h index 67c3378..08bee20 100644 --- a/exynos4/hal/include/SecHdmi.h +++ b/exynos4/hal/include/SecHdmi.h @@ -159,6 +159,7 @@ private : void *mFBaddr; unsigned int mFBsize; int mFBionfd; + unsigned int mFBIndex; int mHdmiFd[HDMI_LAYER_MAX]; int mDstWidth[HDMI_LAYER_MAX]; diff --git a/exynos4/hal/include/gralloc_priv.h b/exynos4/hal/include/gralloc_priv.h index 9f3346a..8ffd161 100644 --- a/exynos4/hal/include/gralloc_priv.h +++ b/exynos4/hal/include/gralloc_priv.h @@ -1,6 +1,14 @@ /* * Copyright (C) 2010 ARM Limited. All rights reserved. * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * struct private_handle_t + * * usesPhysicallyContiguousMemory() + * * validate() + * * dynamicCast() + * * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,145 +35,200 @@ #include #include -#include +/*#include */ +#include "ump.h" + +/* + * HWC_HWOVERLAY is flag for location of glReadPixels(). + * Enable this define if you want that glReadPixesl() is in HWComposer. + * If you disable this define, glReadPixesl() is called in threadloop(). + */ +#define HWC_HWOVERLAY 1 #define GRALLOC_ARM_UMP_MODULE 1 struct private_handle_t; -struct private_module_t -{ - gralloc_module_t base; - - private_handle_t* framebuffer; - uint32_t flags; - uint32_t numBuffers; - uint32_t bufferMask; - pthread_mutex_t lock; - buffer_handle_t currentBuffer; - - struct fb_var_screeninfo info; - struct fb_fix_screeninfo finfo; - float xdpi; - float ydpi; - float fps; - - enum - { - // flag to indicate we'll post this buffer - PRIV_USAGE_LOCKED_FOR_POST = 0x80000000 - }; +struct private_module_t { + gralloc_module_t base; + + private_handle_t* framebuffer; + uint32_t flags; + uint32_t numBuffers; + uint32_t bufferMask; + pthread_mutex_t lock; + buffer_handle_t currentBuffer; + int ion_client; + + struct fb_var_screeninfo info; + struct fb_fix_screeninfo finfo; + float xdpi; + float ydpi; + float fps; + int enableVSync; + + enum { + PRIV_USAGE_LOCKED_FOR_POST = 0x80000000 + }; }; +#ifdef USE_PARTIAL_FLUSH +struct private_handle_rect { + int handle; + int stride; + int l; + int t; + int w; + int h; + int locked; + struct private_handle_rect *next; +}; +#endif + #ifdef __cplusplus struct private_handle_t : public native_handle { #else -struct private_handle_t -{ - struct native_handle nativeHandle; +struct private_handle_t { + struct native_handle nativeHandle; #endif - - enum - { - PRIV_FLAGS_FRAMEBUFFER = 0x00000001, - PRIV_FLAGS_USES_UMP = 0x00000002, - }; - - enum - { - LOCK_STATE_WRITE = 1<<31, - LOCK_STATE_MAPPED = 1<<30, - LOCK_STATE_READ_MASK = 0x3FFFFFFF - }; - - // ints - int magic; - int flags; - int size; - int base; - int lockState; - int writeOwner; - int pid; - - // Following members are for UMP memory only - int ump_id; - int ump_mem_handle; - - // Following members is for framebuffer only - int fd; - int offset; - + enum { + PRIV_FLAGS_FRAMEBUFFER = 0x00000001, + PRIV_FLAGS_USES_UMP = 0x00000002, + PRIV_FLAGS_USES_PMEM = 0x00000004, + PRIV_FLAGS_USES_IOCTL = 0x00000008, + PRIV_FLAGS_USES_HDMI = 0x00000010, + PRIV_FLAGS_USES_ION = 0x00000020, + PRIV_FLAGS_NONE_CACHED = 0x00000040, + }; + + enum { + LOCK_STATE_WRITE = 1<<31, + LOCK_STATE_MAPPED = 1<<30, + LOCK_STATE_READ_MASK = 0x3FFFFFFF + }; + + int fd; + + int magic; + int flags; + int size; + int base; + int lockState; + int writeOwner; + int pid; + + /* Following members are for UMP memory only */ + int ump_id; + int ump_mem_handle; + int offset; + int paddr; + + int format; + int usage; + int width; + int height; + int bpp; + int stride; + + /* Following members are for ION memory only */ + int ion_client; + + /* Following members ard for YUV information */ + unsigned int yaddr; + unsigned int uoffset; + unsigned int voffset; #ifdef __cplusplus - static const int sNumInts = 11; - static const int sNumFds = 0; - static const int sMagic = 0x3141592; - - private_handle_t(int flags, int size, int base, int lock_state, ump_secure_id secure_id, ump_handle handle): - magic(sMagic), - flags(flags), - size(size), - base(base), - lockState(lock_state), - writeOwner(0), - pid(getpid()), - ump_id((int)secure_id), - ump_mem_handle((int)handle), - fd(0), - offset(0) - { - version = sizeof(native_handle); - numFds = sNumFds; - numInts = sNumInts; - } - - private_handle_t(int flags, int size, int base, int lock_state, int fb_file, int fb_offset): - magic(sMagic), - flags(flags), - size(size), - base(base), - lockState(lock_state), - writeOwner(0), - pid(getpid()), - ump_id((int)UMP_INVALID_SECURE_ID), - ump_mem_handle((int)UMP_INVALID_MEMORY_HANDLE), - fd(fb_file), - offset(fb_offset) - { - version = sizeof(native_handle); - numFds = sNumFds; - numInts = sNumInts; - } - - ~private_handle_t() - { - magic = 0; - } - - bool usesPhysicallyContiguousMemory() - { - return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false; - } - - static int validate(const native_handle* h) - { - const private_handle_t* hnd = (const private_handle_t*)h; - if (!h || h->version != sizeof(native_handle) || h->numInts != sNumInts || h->numFds != sNumFds || hnd->magic != sMagic) - { - return -EINVAL; - } - return 0; - } - - static private_handle_t* dynamicCast(const native_handle* in) - { - if (validate(in) == 0) - { - return (private_handle_t*) in; - } - return NULL; - } + static const int sNumInts = 21; + static const int sNumFds = 1; + static const int sMagic = 0x3141592; + + private_handle_t(int flags, int size, int base, int lock_state, ump_secure_id secure_id, ump_handle handle,int fd_val, int offset_val, int paddr_val): + fd(fd_val), + magic(sMagic), + flags(flags), + size(size), + base(base), + lockState(lock_state), + writeOwner(0), + pid(getpid()), + ump_id((int)secure_id), + ump_mem_handle((int)handle), + offset(offset_val), + paddr(paddr_val), + format(0), + usage(0), + width(0), + height(0), + bpp(0), + stride(0), + ion_client(0), + yaddr(0), + uoffset(0), + voffset(0) + { + version = sizeof(native_handle); + numFds = sNumFds; + numInts = sNumInts; + } + + private_handle_t(int flags, int size, int base, int lock_state, int fb_file, int fb_offset): + fd(fb_file), + magic(sMagic), + flags(flags), + size(size), + base(base), + lockState(lock_state), + writeOwner(0), + pid(getpid()), + ump_id((int)UMP_INVALID_SECURE_ID), + ump_mem_handle((int)UMP_INVALID_MEMORY_HANDLE), + offset(fb_offset), + paddr(0), + format(0), + usage(0), + width(0), + height(0), + bpp(0), + stride(0), + ion_client(0), + yaddr(0), + uoffset(0), + voffset(0) + { + version = sizeof(native_handle); + numFds = sNumFds; + numInts = sNumInts; + } + + ~private_handle_t() + { + magic = 0; + } + + bool usesPhysicallyContiguousMemory() + { + return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false; + } + + static int validate(const native_handle* h) + { + const private_handle_t* hnd = (const private_handle_t*)h; + if (!h || h->version != sizeof(native_handle) || + h->numInts != sNumInts || + h->numFds != sNumFds || + hnd->magic != sMagic) + return -EINVAL; + return 0; + } + + static private_handle_t* dynamicCast(const native_handle* in) + { + if (validate(in) == 0) + return (private_handle_t*) in; + return NULL; + } #endif }; diff --git a/exynos4/hal/include/s3c_lcd.h b/exynos4/hal/include/s3c_lcd.h index 7f2dec7..2782542 100644 --- a/exynos4/hal/include/s3c_lcd.h +++ b/exynos4/hal/include/s3c_lcd.h @@ -55,7 +55,6 @@ typedef struct { #ifdef BOARD_USE_V4L2_ION struct s3c_fb_user_ion_client { int fd; - int offset; }; #endif diff --git a/exynos4/hal/include/sec_format.h b/exynos4/hal/include/sec_format.h index 8722b45..23534c5 100644 --- a/exynos4/hal/include/sec_format.h +++ b/exynos4/hal/include/sec_format.h @@ -27,8 +27,6 @@ enum { HAL_PIXEL_FORMAT_CbYCrY_420_I = 0x104, HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x105, HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106, - HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x107, - HAL_PIXEL_FORMAT_ARGB888 = 0x108, // support custom format for zero copy HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110, HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111, diff --git a/exynos4/hal/include/swconverter.h b/exynos4/hal/include/swconverter.h deleted file mode 100644 index eb2eae3..0000000 --- a/exynos4/hal/include/swconverter.h +++ /dev/null @@ -1,462 +0,0 @@ -/* - * - * Copyright 2012 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file swconverter.h - * @brief SEC_OMX specific define. It support MFC 5.x tiled. - * NV12T(tiled) layout: - * Each element is not pixel. It is 64x32 pixel block. - * uv pixel block is interleaved as u v u v u v ... - * y1 y2 y7 y8 y9 y10 y15 y16 - * y3 y4 y5 y6 y11 y12 y13 y14 - * y17 y18 y23 y24 y25 y26 y31 y32 - * y19 y20 y21 y22 y27 y28 y29 y30 - * uv1 uv2 uv7 uv8 uv9 uv10 uv15 uv16 - * uv3 uv4 uv5 uv6 uv11 uv12 uv13 uv14 - * YUV420Planar(linear) layout: - * Each element is not pixel. It is 64x32 pixel block. - * y1 y2 y3 y4 y5 y6 y7 y8 - * y9 y10 y11 y12 y13 y14 y15 y16 - * y17 y18 y19 y20 y21 y22 y23 y24 - * y25 y26 y27 y28 y29 y30 y31 y32 - * u1 u2 u3 u4 u5 u6 u7 u8 - * v1 v2 v3 v4 v5 v6 v7 v8 - * YUV420Semiplanar(linear) layout: - * Each element is not pixel. It is 64x32 pixel block. - * uv pixel block is interleaved as u v u v u v ... - * y1 y2 y3 y4 y5 y6 y7 y8 - * y9 y10 y11 y12 y13 y14 y15 y16 - * y17 y18 y19 y20 y21 y22 y23 y24 - * y25 y26 y27 y28 y29 y30 y31 y32 - * uv1 uv2 uv3 uv4 uv5 uv6 uv7 uv8 - * uv9 uv10 uv11 uv12 uv13 uv14 uv15 uv16 - * @author ShinWon Lee (shinwon.lee@samsung.com) - * @version 1.0 - * @history - * 2012.02.01 : Create - */ - -#ifndef SW_CONVERTOR_H_ -#define SW_CONVERTOR_H_ - -/*--------------------------------------------------------------------------------*/ -/* Format Conversion API */ -/*--------------------------------------------------------------------------------*/ -/* - * De-interleaves src to dest1, dest2 - * - * @param dest1 - * Address of de-interleaved data[out] - * - * @param dest2 - * Address of de-interleaved data[out] - * - * @param src - * Address of interleaved data[in] - * - * @param src_size - * Size of interleaved data[in] - */ -void csc_deinterleave_memcpy( - unsigned char *dest1, - unsigned char *dest2, - unsigned char *src, - unsigned int src_size); - -/* - * Interleaves src1, src2 to dest - * - * @param dest - * Address of interleaved data[out] - * - * @param src1 - * Address of de-interleaved data[in] - * - * @param src2 - * Address of de-interleaved data[in] - * - * @param src_size - * Size of de-interleaved data[in] - */ -void csc_interleave_memcpy( - unsigned char *dest, - unsigned char *src1, - unsigned char *src2, - unsigned int src_size); - -/* C Code */ -/* - * Converts tiled data to linear - * 1. y of nv12t to y of yuv420p - * 2. y of nv12t to y of yuv420s - * - * @param dst - * y address of yuv420[out] - * - * @param src - * y address of nv12t[in] - * - * @param yuv420_width - * real width of yuv420[in] - * it should be even - * - * @param yuv420_height - * real height of yuv420[in] - * it should be even. - * - */ -void csc_tiled_to_linear_y( - unsigned char *y_dst, - unsigned char *y_src, - unsigned int width, - unsigned int height); - -/* - * Converts tiled data to linear - * 1. uv of nv12t to y of yuv420s - * - * @param dst - * uv address of yuv420s[out] - * - * @param src - * uv address of nv12t[in] - * - * @param yuv420_width - * real width of yuv420s[in] - * - * @param yuv420_height - * real height of yuv420s[in] - * - */ -void csc_tiled_to_linear_uv( - unsigned char *uv_dst, - unsigned char *uv_src, - unsigned int width, - unsigned int height); - -/* - * Converts tiled data to linear - * 1. uv of nt12t to uv of yuv420p - * - * @param u_dst - * u address of yuv420p[out] - * - * @param v_dst - * v address of yuv420p[out] - * - * @param uv_src - * uv address of nt12t[in] - * - * @param yuv420_width - * real width of yuv420p[in] - * - * @param yuv420_height - * real height of yuv420p[in] - */ -void csc_tiled_to_linear_uv_deinterleave( - unsigned char *u_dst, - unsigned char *v_dst, - unsigned char *uv_src, - unsigned int width, - unsigned int height); - -/* - * Converts linear data to tiled - * 1. y of yuv420 to y of nv12t - * - * @param dst - * y address of nv12t[out] - * - * @param src - * y address of yuv420[in] - * - * @param yuv420_width - * real width of yuv420[in] - * it should be even - * - * @param yuv420_height - * real height of yuv420[in] - * it should be even. - * - */ -void csc_linear_to_tiled_y( - unsigned char *y_dst, - unsigned char *y_src, - unsigned int width, - unsigned int height); - -/* - * Converts and interleaves linear data to tiled - * 1. uv of nv12t to uv of yuv420 - * - * @param dst - * uv address of nv12t[out] - * - * @param src - * u address of yuv420[in] - * - * @param src - * v address of yuv420[in] - * - * @param yuv420_width - * real width of yuv420[in] - * - * @param yuv420_height - * real height of yuv420[in] - * - */ -void csc_linear_to_tiled_uv( - unsigned char *uv_dst, - unsigned char *u_src, - unsigned char *v_src, - unsigned int width, - unsigned int height); - -/* - * Converts tiled data to linear for mfc 6.x - * 1. Y of NV12T to Y of YUV420P - * 2. Y of NV12T to Y of YUV420S - * - * @param dst - * Y address of YUV420[out] - * - * @param src - * Y address of NV12T[in] - * - * @param yuv420_width - * real width of YUV420[in] - * - * @param yuv420_height - * Y: real height of YUV420[in] - * - */ -void csc_tiled_to_linear_y_neon( - unsigned char *y_dst, - unsigned char *y_src, - unsigned int width, - unsigned int height); - -/* - * Converts tiled data to linear for mfc 6.x - * 1. UV of NV12T to Y of YUV420S - * - * @param u_dst - * UV plane address of YUV420P[out] - * - * @param nv12t_src - * Y or UV plane address of NV12T[in] - * - * @param yuv420_width - * real width of YUV420[in] - * - * @param yuv420_height - * (real height)/2 of YUV420[in] - */ -void csc_tiled_to_linear_uv_neon( - unsigned char *uv_dst, - unsigned char *uv_src, - unsigned int width, - unsigned int height); - -/* - * Converts tiled data to linear for mfc 6.x - * Deinterleave src to u_dst, v_dst - * 1. UV of NV12T to Y of YUV420P - * - * @param u_dst - * U plane address of YUV420P[out] - * - * @param v_dst - * V plane address of YUV420P[out] - * - * @param nv12t_src - * Y or UV plane address of NV12T[in] - * - * @param yuv420_width - * real width of YUV420[in] - * - * @param yuv420_height - * (real height)/2 of YUV420[in] - */ -void csc_tiled_to_linear_uv_deinterleave_neon( - unsigned char *u_dst, - unsigned char *v_dst, - unsigned char *uv_src, - unsigned int width, - unsigned int height); - -/* - * Converts linear data to tiled - * 1. y of yuv420 to y of nv12t - * - * @param dst - * y address of nv12t[out] - * - * @param src - * y address of yuv420[in] - * - * @param yuv420_width - * real width of yuv420[in] - * it should be even - * - * @param yuv420_height - * real height of yuv420[in] - * it should be even. - * - */ -void csc_linear_to_tiled_y_neon( - unsigned char *y_dst, - unsigned char *y_src, - unsigned int width, - unsigned int height); - -/* - * Converts and interleaves linear data to tiled - * 1. uv of nv12t to uv of yuv420 - * - * @param dst - * uv address of nv12t[out] - * - * @param src - * u address of yuv420[in] - * - * @param src - * v address of yuv420[in] - * - * @param yuv420_width - * real width of yuv420[in] - * - * @param yuv420_height - * real height of yuv420[in] - * - */ -void csc_linear_to_tiled_uv_neon( - unsigned char *uv_dst, - unsigned char *u_src, - unsigned char *v_src, - unsigned int width, - unsigned int height); - -/* - * Converts RGB565 to YUV420P - * - * @param y_dst - * Y plane address of YUV420P[out] - * - * @param u_dst - * U plane address of YUV420P[out] - * - * @param v_dst - * V plane address of YUV420P[out] - * - * @param rgb_src - * Address of RGB565[in] - * - * @param width - * Width of RGB565[in] - * - * @param height - * Height of RGB565[in] - */ -void csc_RGB565_to_YUV420P( - unsigned char *y_dst, - unsigned char *u_dst, - unsigned char *v_dst, - unsigned char *rgb_src, - unsigned int width, - unsigned int height); - -/* - * Converts RGB565 to YUV420S - * - * @param y_dst - * Y plane address of YUV420S[out] - * - * @param uv_dst - * UV plane address of YUV420S[out] - * - * @param rgb_src - * Address of RGB565[in] - * - * @param width - * Width of RGB565[in] - * - * @param height - * Height of RGB565[in] - */ -void csc_RGB565_to_YUV420SP( - unsigned char *y_dst, - unsigned char *uv_dst, - unsigned char *rgb_src, - unsigned int width, - unsigned int height); - -/* - * Converts ARGB8888 to YUV420P - * - * @param y_dst - * Y plane address of YUV420P[out] - * - * @param u_dst - * U plane address of YUV420P[out] - * - * @param v_dst - * V plane address of YUV420P[out] - * - * @param rgb_src - * Address of ARGB8888[in] - * - * @param width - * Width of ARGB8888[in] - * - * @param height - * Height of ARGB8888[in] - */ -void csc_ARGB8888_to_YUV420P( - unsigned char *y_dst, - unsigned char *u_dst, - unsigned char *v_dst, - unsigned char *rgb_src, - unsigned int width, - unsigned int height); - -/* - * Converts ARGB888 to YUV420SP - * - * @param y_dst - * Y plane address of YUV420SP[out] - * - * @param uv_dst - * UV plane address of YUV420SP[out] - * - * @param rgb_src - * Address of ARGB8888[in] - * - * @param width - * Width of ARGB8888[in] - * - * @param height - * Height of ARGB8888[in] - */ -void csc_ARGB8888_to_YUV420SP( - unsigned char *y_dst, - unsigned char *uv_dst, - unsigned char *rgb_src, - unsigned int width, - unsigned int height); - -#endif /*COLOR_SPACE_CONVERTOR_H_*/ diff --git a/exynos4/hal/include/ump.h b/exynos4/hal/include/ump.h new file mode 100644 index 0000000..fd01c44 --- /dev/null +++ b/exynos4/hal/include/ump.h @@ -0,0 +1,263 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2008-2010 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump.h + * + * This file contains the user space part of the UMP API. + */ + +#ifndef _UNIFIED_MEMORY_PROVIDER_H_ +#define _UNIFIED_MEMORY_PROVIDER_H_ + + +/** @defgroup ump_user_space_api UMP User Space API + * @{ */ + + +#include "ump_platform.h" + + +#include "ion.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * External representation of a UMP handle in user space. + */ +typedef void * ump_handle; + +/** + * Typedef for a secure ID, a system wide identificator for UMP memory buffers. + */ +typedef unsigned int ump_secure_id; + +/** + * Value to indicate an invalid UMP memory handle. + */ +#define UMP_INVALID_MEMORY_HANDLE ((ump_handle)0) + +/** + * Value to indicate an invalid secure Id. + */ +#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) + +/** + * UMP error codes for user space. + */ +typedef enum +{ + UMP_OK, /**< indicates success */ + UMP_ERROR, /**< indicates failure */ +} ump_result; + + +/** + * Opens and initializes the UMP library. + * + * This function must be called at least once before calling any other UMP API functions. + * Each open is reference counted and must be matched with a call to @ref ump_close "ump_close". + * + * @see ump_close + * + * @return UMP_OK indicates success, UMP_ERROR indicates failure. + */ +UMP_API_EXPORT ump_result ump_open(void); + + +/** + * Terminate the UMP library. + * + * This must be called once for every successful @ref ump_open "ump_open". The UMP library is + * terminated when, and only when, the last open reference to the UMP interface is closed. + * + * @see ump_open + */ +UMP_API_EXPORT void ump_close(void); + + +/** + * Retrieves the secure ID for the specified UMP memory. + * + * This identificator is unique across the entire system, and uniquely identifies + * the specified UMP memory. This identificator can later be used through the + * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" or + * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" + * functions in order to access this UMP memory, for instance from another process. + * + * @note There is a kernel space equivalent function called @ref ump_dd_secure_id_get "ump_dd_secure_id_get" + * + * @see ump_handle_create_from_secure_id + * @see ump_dd_handle_create_from_secure_id + * @see ump_dd_secure_id_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the secure ID for the specified UMP memory. + */ +UMP_API_EXPORT ump_secure_id ump_secure_id_get(ump_handle mem); + + +/** + * Retrieves a handle to allocated UMP memory. + * + * The usage of UMP memory is reference counted, so this will increment the reference + * count by one for the specified UMP memory. + * Use @ref ump_reference_release "ump_reference_release" when there is no longer any + * use for the retrieved handle. + * + * @note There is a kernel space equivalent function called @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" + * + * @see ump_reference_release + * @see ump_dd_handle_create_from_secure_id + * + * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. + * + * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. + */ +UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id); + + +/** + * Retrieves the actual size of the specified UMP memory. + * + * The size is reported in bytes, and is typically page aligned. + * + * @note There is a kernel space equivalent function called @ref ump_dd_size_get "ump_dd_size_get" + * + * @see ump_dd_size_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the allocated size of the specified UMP memory, in bytes. + */ +UMP_API_EXPORT unsigned long ump_size_get(ump_handle mem); + + +/** + * Read from specified UMP memory. + * + * Another way of reading from (and writing to) UMP memory is to use the + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve + * a CPU mapped pointer to the memory. + * + * @see ump_mapped_pointer_get + * + * @param dst Destination buffer. + * @param src Handle to UMP memory to read from. + * @param offset Where to start reading, given in bytes. + * @param length How much to read, given in bytes. + */ +UMP_API_EXPORT void ump_read(void * dst, ump_handle src, unsigned long offset, unsigned long length); + + +/** + * Write to specified UMP memory. + * + * Another way of writing to (and reading from) UMP memory is to use the + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve + * a CPU mapped pointer to the memory. + * + * @see ump_mapped_pointer_get + * + * @param dst Handle to UMP memory to write to. + * @param offset Where to start writing, given in bytes. + * @param src Buffer to read from. + * @param length How much to write, given in bytes. + */ +UMP_API_EXPORT void ump_write(ump_handle dst, unsigned long offset, const void * src, unsigned long length); + + +/** + * Retrieves a memory mapped pointer to the specified UMP memory. + * + * This function retrieves a memory mapped pointer to the specified UMP memory, + * that can be used by the CPU. Every successful call to + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" is reference counted, + * and must therefor be followed by a call to + * @ref ump_mapped_pointer_release "ump_mapped_pointer_release " when the + * memory mapping is no longer needed. + * + * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required. + * + * @see ump_mapped_pointer_release + * + * @param mem Handle to UMP memory. + * + * @return NULL indicates failure, otherwise a CPU mapped pointer is returned. + */ +UMP_API_EXPORT void * ump_mapped_pointer_get(ump_handle mem); + + +/** + * Releases a previously mapped pointer to the specified UMP memory. + * + * The CPU mapping of the specified UMP memory memory is reference counted, + * so every call to @ref ump_mapped_pointer_get "ump_mapped_pointer_get" must + * be matched with a call to this function when the mapping is no longer needed. + * + * The CPU mapping is not removed before all references to the mapping is released. + * + * @note Systems without a MMU must still implement this function, even though no unmapping should be needed. + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle mem); + + +/** + * Adds an extra reference to the specified UMP memory. + * + * This function adds an extra reference to the specified UMP memory. This function should + * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle + * variable. The function @ref ump_reference_release "ump_reference_release" must then be used + * to release each copy of the UMP memory handle. + * + * @note You are not required to call @ref ump_reference_add "ump_reference_add" + * for UMP handles returned from + * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id", + * because these handles are already reference counted by this function. + * + * @note There is a kernel space equivalent function called @ref ump_dd_reference_add "ump_dd_reference_add" + * + * @see ump_dd_reference_add + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_reference_add(ump_handle mem); + + +/** + * Releases a reference from the specified UMP memory. + * + * This function should be called once for every reference to the UMP memory handle. + * When the last reference is released, all resources associated with this UMP memory + * handle are freed. + * + * @note There is a kernel space equivalent function called @ref ump_dd_reference_release "ump_dd_reference_release" + * + * @see ump_dd_reference_release + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_reference_release(ump_handle mem); + + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* end group ump_user_space_api */ + + +#endif /*_UNIFIED_MEMORY_PROVIDER_H_ */ diff --git a/exynos4/hal/include/ump_platform.h b/exynos4/hal/include/ump_platform.h new file mode 100644 index 0000000..9285aef --- /dev/null +++ b/exynos4/hal/include/ump_platform.h @@ -0,0 +1,46 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2008-2010 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump_platform.h + * + * This file should define UMP_API_EXPORT, + * which dictates how the UMP user space API should be exported/imported. + * Modify this file, if needed, to match your platform setup. + */ + +#ifndef __UMP_PLATFORM_H__ +#define __UMP_PLATFORM_H__ + +/** @addtogroup ump_user_space_api + * @{ */ + +/** + * A define which controls how UMP user space API functions are imported and exported. + * This define should be set by the implementor of the UMP API. + */ +#if defined(_WIN32) + +#define UMP_API_EXPORT + +#elif defined(__SYMBIAN32__) + +#define UMP_API_EXPORT IMPORT_C + +#else + +#define UMP_API_EXPORT + +#endif + +/** @} */ /* end group ump_user_space_api */ + + +#endif /* __UMP_PLATFORM_H__ */ diff --git a/exynos4/hal/include/ump_ref_drv.h b/exynos4/hal/include/ump_ref_drv.h new file mode 100644 index 0000000..6320f1d --- /dev/null +++ b/exynos4/hal/include/ump_ref_drv.h @@ -0,0 +1,59 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2009-2010 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump_ref_drv.h + * + * Reference driver extensions to the UMP user space API for allocating UMP memory + */ + +#ifndef _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ +#define _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ + +#include "ump.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + /* This enum must match with the IOCTL enum in ump_ioctl.h */ + UMP_REF_DRV_CONSTRAINT_NONE = 0, + UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR = 1, + /* This enum is included by samsung */ + UMP_REF_DRV_CONSTRAINT_USE_CACHE = 128, +} ump_alloc_constraints; + +/** Allocate an UMP handle containing a memory buffer. + * Input: Size: The minimum size for the allocation. + * Usage: If this is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu. + * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached. + * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported.*/ +UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage); + +UMP_API_EXPORT ump_handle ump_ref_drv_ion_import(int ion_fd, ump_alloc_constraints constraints); +typedef enum { + UMP_MSYNC_CLEAN = 0 , + UMP_MSYNC_CLEAN_AND_INVALIDATE = 1, + UMP_MSYNC_READOUT_CACHE_ENABLED = 128, +} ump_cpu_msync_op; + +/** Flushing cache for an ump_handle. + * The function will always CLEAN_AND_INVALIDATE as long as the \a op is not UMP_MSYNC_READOUT_CACHE_ENABLED. + * If so it will only report back if the given ump_handle is cacheable. + * At the momement the implementation does not use \a address or \a size. + * Return value is 1 if cache is enabled, and 0 if it is disabled for the given allocation.*/ +UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void* address, int size); + +#ifdef __cplusplus +} +#endif + +#endif /*_UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ */ diff --git a/exynos4/hal/libcamera/Android.mk b/exynos4/hal/libcamera/Android.mk new file mode 100644 index 0000000..9523db9 --- /dev/null +++ b/exynos4/hal/libcamera/Android.mk @@ -0,0 +1,38 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# HAL module implemenation stored in +# hw/..so +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES:= \ + SecCamera.cpp SecCameraHWInterface.cpp + +LOCAL_SHARED_LIBRARIES:= libutils libcutils libbinder liblog libcamera_client libhardware + +ifeq ($(TARGET_SOC), exynos4210) +LOCAL_SHARED_LIBRARIES += libs5pjpeg +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC), exynos4x12) +LOCAL_SHARED_LIBRARIES += libhwjpeg +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +ifeq ($(BOARD_USE_V4L2), true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +ifeq ($(BOARD_USE_V4L2_ION), true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2 +LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION +endif + +LOCAL_MODULE := camera.$(TARGET_BOARD_PLATFORM) + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libcamera/NOTICE b/exynos4/hal/libcamera/NOTICE new file mode 100644 index 0000000..f921593 --- /dev/null +++ b/exynos4/hal/libcamera/NOTICE @@ -0,0 +1,190 @@ + + Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/exynos4/hal/libcamera/SecCamera.cpp b/exynos4/hal/libcamera/SecCamera.cpp new file mode 100644 index 0000000..9c7bf94 --- /dev/null +++ b/exynos4/hal/libcamera/SecCamera.cpp @@ -0,0 +1,4360 @@ +/* + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +************************************ +* Filename: SecCamera.cpp +* Author: Sachin P. Kamat +* Purpose: This file interacts with the Camera and JPEG drivers. +************************************* +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SecCamera" + +#include +#include +#include +#include +#include "SecCamera.h" +#include "cutils/properties.h" + +using namespace android; + +#define CHECK(return_value) \ + if (return_value < 0) { \ + LOGE("%s::%d fail. errno: %s, m_camera_id = %d", \ + __func__, __LINE__, strerror(errno), m_camera_id); \ + return -1; \ + } + +#define CHECK_PTR(return_value) \ + if (return_value < 0) { \ + LOGE("%s::%d fail, errno: %s, m_camera_id = %d", \ + __func__,__LINE__, strerror(errno), m_camera_id); \ + return NULL; \ + } + +namespace android { + +static struct timeval time_start; +static struct timeval time_stop; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 +unsigned long measure_time_camera(struct timeval *start, struct timeval *stop) +{ + unsigned long sec, usec, time; + + sec = stop->tv_sec - start->tv_sec; + + if (stop->tv_usec >= start->tv_usec) { + usec = stop->tv_usec - start->tv_usec; + } else { + usec = stop->tv_usec + 1000000 - start->tv_usec; + sec--; + } + + time = (sec * 1000000) + usec; + + return time; +} +#endif + +static int close_buffers(struct SecBuffer *buffers, int num_of_buf) +{ + int ret; + + for (int i = 0; i < num_of_buf; i++) { + for(int j = 0; j < MAX_PLANES; j++) { + if (buffers[i].virt.extP[j]) { +#ifndef BOARD_USE_V4L2_ION + ret = munmap(buffers[i].virt.extP[j], buffers[i].size.extS[j]); + LOGV("munmap():buffers[%d].virt.extP[%d]: 0x%x size = %d", + i, j, (unsigned int) buffers[i].virt.extP[j], + buffers[i].size.extS[j]); +#endif + buffers[i].virt.extP[j] = NULL; + } + } + } + + return 0; +} + +static int get_pixel_depth(unsigned int fmt) +{ + int depth = 0; + + switch (fmt) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YVU420M: + depth = 12; + break; + + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUV422P: + depth = 16; + break; + + case V4L2_PIX_FMT_RGB32: + depth = 32; + break; + } + + return depth; +} + +static int fimc_poll(struct pollfd *events) +{ + int ret; + + /* 10 second delay is because sensor can take a long time + * to do auto focus and capture in dark settings + */ + ret = poll(events, 1, 10000); + if (ret < 0) { + LOGE("ERR(%s):poll error", __func__); + return ret; + } + + if (ret == 0) { + LOGE("ERR(%s):No data in 10 secs..", __func__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_querycap(int fp) +{ + struct v4l2_capability cap; + + if (ioctl(fp, VIDIOC_QUERYCAP, &cap) < 0) { + LOGE("ERR(%s):VIDIOC_QUERYCAP failed", __func__); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("ERR(%s):no capture devices", __func__); + return -1; + } + + return 0; +} + +static const __u8* fimc_v4l2_enuminput(int fp, int index) +{ + static struct v4l2_input input; + + input.index = index; + if (ioctl(fp, VIDIOC_ENUMINPUT, &input) != 0) { + LOGE("ERR(%s):No matching index found", __func__); + return NULL; + } + LOGI("Name of input channel[%d] is %s", input.index, input.name); + + return input.name; +} + +static int fimc_v4l2_s_input(int fp, int index) +{ + struct v4l2_input input; + + input.index = index; + + if (ioctl(fp, VIDIOC_S_INPUT, &input) < 0) { + LOGE("ERR(%s):VIDIOC_S_INPUT failed", __func__); + return -1; + } + + return 0; +} + +static int fimc_v4l2_s_fmt(int fp, int width, int height, unsigned int fmt, enum v4l2_field field, unsigned int num_plane) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + unsigned int framesize; + + memset(&v4l2_fmt, 0, sizeof(struct v4l2_format)); + v4l2_fmt.type = V4L2_BUF_TYPE; + +#ifdef BOARD_USE_V4L2 + framesize = (width * height * get_pixel_depth(fmt)) / 8; + + v4l2_fmt.fmt.pix_mp.width = width; + v4l2_fmt.fmt.pix_mp.height = height; + v4l2_fmt.fmt.pix_mp.pixelformat = fmt; + v4l2_fmt.fmt.pix_mp.field = field; + if (num_plane == 1) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = framesize; + } else if (num_plane == 2) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width * height, 2048); + v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 16) * ALIGN(height/2, 16) * 2; + } else if (num_plane == 3) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 16) * ALIGN(height/2, 16); + v4l2_fmt.fmt.pix_mp.plane_fmt[2].sizeimage = ALIGN(width/2, 16) * ALIGN(height/2, 16); + } else { + LOGE("ERR(%s): Invalid plane number", __func__); + return -1; + } + v4l2_fmt.fmt.pix_mp.num_planes = num_plane; +#else + memset(&pixfmt, 0, sizeof(pixfmt)); + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + pixfmt.field = V4L2_FIELD_NONE; + + v4l2_fmt.fmt.pix = pixfmt; + LOGV("fimc_v4l2_s_fmt : width(%d) height(%d)", width, height); +#endif + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +static int fimc_v4l2_s_fmt_cap(int fp, int width, int height, unsigned int fmt) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + v4l2_fmt.type = V4L2_BUF_TYPE; + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + if (fmt == V4L2_PIX_FMT_JPEG) + pixfmt.colorspace = V4L2_COLORSPACE_JPEG; + + v4l2_fmt.fmt.pix = pixfmt; + LOGV("fimc_v4l2_s_fmt_cap : width(%d) height(%d)", width, height); + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_s_fmt_is(int fp, int width, int height, unsigned int fmt, enum v4l2_field field) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + v4l2_fmt.type = V4L2_BUF_TYPE_PRIVATE; + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + pixfmt.field = field; + + v4l2_fmt.fmt.pix = pixfmt; + LOGV("fimc_v4l2_s_fmt_is : width(%d) height(%d)", width, height); + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +static int fimc_v4l2_enum_fmt(int fp, unsigned int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int found = 0; + + fmtdesc.type = V4L2_BUF_TYPE; + fmtdesc.index = 0; + + while (ioctl(fp, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { + if (fmtdesc.pixelformat == fmt) { + LOGV("passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description); + found = 1; + break; + } + + fmtdesc.index++; + } + + if (!found) { + LOGE("unsupported pixel format"); + return -1; + } + + return 0; +} + +static int fimc_v4l2_reqbufs(int fp, enum v4l2_buf_type type, int nr_bufs) +{ + struct v4l2_requestbuffers req; + + req.count = nr_bufs; + req.type = type; + req.memory = V4L2_MEMORY_TYPE; + + if (ioctl(fp, VIDIOC_REQBUFS, &req) < 0) { + LOGE("ERR(%s):VIDIOC_REQBUFS failed", __func__); + return -1; + } + + return req.count; +} + +static int fimc_v4l2_querybuf(int fp, struct SecBuffer *buffers, enum v4l2_buf_type type, int nr_frames, int num_plane) +{ + struct v4l2_buffer v4l2_buf; +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[VIDEO_MAX_PLANES]; +#endif + int i, ret, plane_index; + + for (i = 0; i < nr_frames; i++) { + v4l2_buf.type = type; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + v4l2_buf.index = i; +#ifdef BOARD_USE_V4L2 + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; // this is for multi-planar + LOGV("QUERYBUF(index=%d)", i); + LOGV("memory plane is %d", v4l2_buf.length); +#endif + + ret = ioctl(fp, VIDIOC_QUERYBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_QUERYBUF failed", __func__); + return -1; + } + +#ifdef BOARD_USE_V4L2 + for (plane_index = 0; plane_index < num_plane; plane_index++) { + LOGV("Offset : 0x%x", v4l2_buf.m.planes[plane_index].m.mem_offset); + LOGV("Plane Length : 0x%x", v4l2_buf.m.planes[plane_index].length); + + buffers[i].phys.extP[plane_index] = (unsigned int)v4l2_buf.m.planes[plane_index].cookie; + + buffers[i].size.extS[plane_index] = v4l2_buf.m.planes[plane_index].length; + LOGV("length[%d] : 0x%x", i, buffers[i].size.extS[plane_index]); + if ((buffers[i].virt.extP[plane_index] = (char *)mmap(0, v4l2_buf.m.planes[plane_index].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fp, v4l2_buf.m.planes[plane_index].m.mem_offset)) < 0) { + LOGE("mmap failed"); + return -1; + } + LOGV("vaddr[%d][%d] : 0x%x", i, plane_index, (__u32) buffers[i].virt.extP[plane_index]); + } +#else + buffers[i].size.s = v4l2_buf.length; + + if ((buffers[i].virt.p = (char *)mmap(0, v4l2_buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, + fp, v4l2_buf.m.offset)) < 0) { + LOGE("%s %d] mmap() failed",__func__, __LINE__); + return -1; + } + LOGV("buffers[%d].virt.p = %p v4l2_buf.length = %d", i, buffers[i].virt.p, v4l2_buf.length); +#endif + } + return 0; +} + +static int fimc_v4l2_streamon(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE; + int ret; + + ret = ioctl(fp, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMON failed", __func__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_streamoff(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE; + int ret; + + LOGV("%s :", __func__); + ret = ioctl(fp, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMOFF failed", __func__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_qbuf(int fp, int width, int height, struct SecBuffer *vaddr, int index, int num_plane, int mode) +{ + struct v4l2_buffer v4l2_buf; + int ret; + +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; +#endif + + v4l2_buf.type = V4L2_BUF_TYPE; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + v4l2_buf.index = index; + +#ifdef BOARD_USE_V4L2_ION + if (mode == PREVIEW_MODE) { + if (num_plane == 1) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = width * height * 2; + } else if (num_plane == 2) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(width/2, 16) * ALIGN(height/2, 16); + } else if (num_plane == 3) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(width/2, 16) * ALIGN(height/2, 16); + v4l2_buf.m.planes[2].m.userptr = (long unsigned int)vaddr[index].virt.extP[2]; + v4l2_buf.m.planes[2].length = ALIGN(width/2, 16) * ALIGN(height/2, 16); + } else { + LOGE("ERR(%s): Invalid plane number", __func__); + return -1; + } + } else if (mode == CAPTURE_MODE) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = width * height * 2; + } else if (mode == RECORD_MODE) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(ALIGN(width, 16) * ALIGN(height, 16), 2048); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(ALIGN(width, 16) * ALIGN(height >> 1, 8), 2048); + } else { + LOGE("ERR(%s): Invalid mode", __func__); + return -1; + } +#endif + + ret = ioctl(fp, VIDIOC_QBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_QBUF failed", __func__); + return ret; + } + + return 0; +} + +static int fimc_v4l2_dqbuf(int fp, int num_plane) +{ + struct v4l2_buffer v4l2_buf; + int ret; + +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; +#endif + + v4l2_buf.type = V4L2_BUF_TYPE; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + + ret = ioctl(fp, VIDIOC_DQBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_DQBUF failed, dropped frame", __func__); + return ret; + } + + return v4l2_buf.index; +} + +static int fimc_v4l2_g_ctrl(int fp, unsigned int id) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + + ret = ioctl(fp, VIDIOC_G_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s): VIDIOC_G_CTRL(id = 0x%x (%d)) failed, ret = %d", + __func__, id, id-V4L2_CID_PRIVATE_BASE, ret); + return ret; + } + + return ctrl.value; +} + +static int fimc_v4l2_s_ctrl(int fp, unsigned int id, unsigned int value) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + ctrl.value = value; + + ret = ioctl(fp, VIDIOC_S_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_CTRL(id = %#x (%d), value = %d) failed ret = %d", + __func__, id, id-V4L2_CID_PRIVATE_BASE, value, ret); + + return ret; + } + + return ctrl.value; +} + +static int fimc_v4l2_s_ext_ctrl(int fp, unsigned int id, void *value) +{ + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + int ret; + + ctrl.id = id; + + ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ctrls.count = 1; + ctrls.controls = &ctrl; + + ret = ioctl(fp, VIDIOC_S_EXT_CTRLS, &ctrls); + if (ret < 0) + LOGE("ERR(%s):VIDIOC_S_EXT_CTRLS failed", __func__); + + return ret; +} + +static int fimc_v4l2_s_ext_ctrl_face_detection(int fp, unsigned int id, void *value) +{ + struct v4l2_ext_control ext_ctrl_fd[111]; + struct v4l2_ext_controls ext_ctrls_fd; + struct v4l2_ext_controls *ctrls; + camera_frame_metadata_t *facedata = (camera_frame_metadata_t *)value; + int i, ret; + + ext_ctrl_fd[0].id = V4L2_CID_IS_FD_GET_FACE_COUNT; + for (i = 0; i < 5; i++) { + ext_ctrl_fd[22*i+1].id = V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER; + ext_ctrl_fd[22*i+2].id = V4L2_CID_IS_FD_GET_FACE_CONFIDENCE; + ext_ctrl_fd[22*i+3].id = V4L2_CID_IS_FD_GET_FACE_SMILE_LEVEL; + ext_ctrl_fd[22*i+4].id = V4L2_CID_IS_FD_GET_FACE_BLINK_LEVEL; + ext_ctrl_fd[22*i+5].id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X; + ext_ctrl_fd[22*i+6].id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y; + ext_ctrl_fd[22*i+7].id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+8].id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+9].id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X; + ext_ctrl_fd[22*i+10].id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y; + ext_ctrl_fd[22*i+11].id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+12].id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+13].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X; + ext_ctrl_fd[22*i+14].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y; + ext_ctrl_fd[22*i+15].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+16].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+17].id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X; + ext_ctrl_fd[22*i+18].id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y; + ext_ctrl_fd[22*i+19].id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+20].id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+21].id = V4L2_CID_IS_FD_GET_ANGLE; + ext_ctrl_fd[22*i+22].id = V4L2_CID_IS_FD_GET_NEXT; + } + + ext_ctrls_fd.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ext_ctrls_fd.count = 111; + ext_ctrls_fd.controls = ext_ctrl_fd; + ctrls = &ext_ctrls_fd; + + ret = ioctl(fp, VIDIOC_G_EXT_CTRLS, &ext_ctrls_fd); + + facedata->number_of_faces = ext_ctrls_fd.controls[0].value; + + for(i = 0; i < facedata->number_of_faces; i++) { + facedata->faces[i].rect[0] = ext_ctrl_fd[22*i+5].value; + facedata->faces[i].rect[1] = ext_ctrl_fd[22*i+6].value; + facedata->faces[i].rect[2] = ext_ctrl_fd[22*i+7].value; + facedata->faces[i].rect[3] = ext_ctrl_fd[22*i+8].value; + facedata->faces[i].score = ext_ctrl_fd[22*i+2].value; +/* TODO : id is unique value for each face. We need to suppot this. */ + facedata->faces[i].id = 0; + facedata->faces[i].left_eye[0] = (ext_ctrl_fd[22*i+9].value + ext_ctrl_fd[22*i+11].value) / 2; + facedata->faces[i].left_eye[1] = (ext_ctrl_fd[22*i+10].value + ext_ctrl_fd[22*i+12].value) / 2; + facedata->faces[i].right_eye[0] = (ext_ctrl_fd[22*i+13].value + ext_ctrl_fd[22*i+15].value) / 2; + facedata->faces[i].right_eye[1] = (ext_ctrl_fd[22*i+14].value + ext_ctrl_fd[22*i+16].value) / 2; + facedata->faces[i].mouth[0] = (ext_ctrl_fd[22*i+17].value + ext_ctrl_fd[22*i+19].value) / 2; + facedata->faces[i].mouth[1] = (ext_ctrl_fd[22*i+18].value + ext_ctrl_fd[22*i+20].value) / 2; + } + + return ret; +} + +static int fimc_v4l2_g_parm(int fp, struct v4l2_streamparm *streamparm) +{ + int ret; + + streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fp, VIDIOC_G_PARM, streamparm); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_G_PARM failed", __func__); + return -1; + } + + LOGV("%s : timeperframe: numerator %d, denominator %d", __func__, + streamparm->parm.capture.timeperframe.numerator, + streamparm->parm.capture.timeperframe.denominator); + + return 0; +} + +static int fimc_v4l2_s_parm(int fp, struct v4l2_streamparm *streamparm) +{ + int ret; + + streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fp, VIDIOC_S_PARM, streamparm); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_PARM failed", __func__); + return ret; + } + + return 0; +} + +SecCamera::SecCamera() : + m_flagCreate(0), + m_preview_state(0), + m_snapshot_state(0), + m_camera_id(CAMERA_ID_BACK), + m_camera_use_ISP(0), + m_cam_fd(-1), + m_cam_fd2(-1), + m_cam_fd3(-1), + m_cap_fd(-1), + m_rec_fd(-1), + m_jpeg_fd(-1), + m_flag_record_start(0), + m_preview_v4lformat(V4L2_PIX_FMT_YVU420), + m_preview_width (0), + m_preview_height (0), + m_preview_max_width (MAX_BACK_CAMERA_PREVIEW_WIDTH), + m_preview_max_height (MAX_BACK_CAMERA_PREVIEW_HEIGHT), + m_snapshot_v4lformat(V4L2_PIX_FMT_YUYV), + m_snapshot_width (0), + m_snapshot_height (0), + m_num_capbuf (0), + m_videosnapshot_width (0), + m_videosnapshot_height(0), + m_snapshot_max_width (MAX_BACK_CAMERA_SNAPSHOT_WIDTH), + m_snapshot_max_height (MAX_BACK_CAMERA_SNAPSHOT_HEIGHT), + m_recording_en (0), + m_record_hint (0), + m_recording_width (0), + m_recording_height (0), + m_angle(-1), + m_anti_banding(0), + m_wdr(0), + m_anti_shake(0), + m_zoom_level(-1), + m_object_tracking(-1), + m_smart_auto(-1), + m_beauty_shot(-1), + m_vintage_mode(-1), + m_face_detect(0), + m_object_tracking_start_stop(-1), + m_gps_latitude(-1), + m_gps_longitude(-1), + m_gps_altitude(-1), + m_gps_timestamp(-1), + m_sensor_mode(-1), + m_shot_mode(-1), + m_exif_orientation(-1), + m_chk_dataline(-1), + m_video_gamma(0), + m_slow_ae(0), + m_camera_af_flag(-1), + m_flag_camera_create(0), + m_flag_camera_start(0), + m_jpeg_thumbnail_width (0), + m_jpeg_thumbnail_height(0), + m_jpeg_thumbnail_quality(100), + m_jpeg_quality(100), + m_touch_af_start_stop(-1), + m_postview_offset(0), + m_auto_focus_state(0) +#ifdef ENABLE_ESD_PREVIEW_CHECK + , + m_esd_check_count(0) +#endif // ENABLE_ESD_PREVIEW_CHECK +{ + initParameters(0); + memset(&mExifInfo, 0, sizeof(mExifInfo)); + + memset(&m_events_c, 0, sizeof(m_events_c)); + memset(&m_events_c2, 0, sizeof(m_events_c2)); + memset(&m_events_c3, 0, sizeof(m_events_c3)); +} + +SecCamera::~SecCamera() +{ + LOGV("%s :", __func__); + DestroyCamera(); +} + +bool SecCamera::CreateCamera(int index) +{ + LOGV("%s :", __func__); + int ret = 0; + + switch (index) { + case CAMERA_ID_FRONT: + m_preview_max_width = MAX_FRONT_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_FRONT_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT; + break; + + case CAMERA_ID_BACK: + default: + m_preview_max_width = MAX_BACK_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_BACK_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_BACK_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT; + break; + } + + if (!m_flagCreate) { + /* Arun C + * Reset the lense position only during camera starts; don't do + * reset between shot to shot + */ + m_flagCreate = 1; + m_snapshot_state = 0; + m_camera_af_flag = -1; + m_camera_id = index; + m_recording_en = 0; + + m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR); + if (m_cam_fd < 0) { + LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, CAMERA_DEV_NAME, strerror(errno)); + return -1; + } + LOGV("%s: open(%s) --> m_cam_fd %d", __func__, CAMERA_DEV_NAME, m_cam_fd); + + ret = fimc_v4l2_querycap(m_cam_fd); + CHECK(ret); + if (!fimc_v4l2_enuminput(m_cam_fd, index)) { + LOGE("m_cam_fd(%d) fimc_v4l2_enuminput fail", m_cam_fd); + return -1; + } + ret = fimc_v4l2_s_input(m_cam_fd, index); + CHECK(ret); + + m_camera_use_ISP = getUseInternalISP(); + + if (m_camera_use_ISP) { + if (!m_recording_en) + fimc_v4l2_s_fmt_is(m_cam_fd, m_preview_max_width, m_preview_max_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + else + fimc_v4l2_s_fmt_is(m_cam_fd, m_preview_max_width, m_preview_max_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_VIDEO); + } + + ret = fimc_v4l2_s_fmt(m_cam_fd, m_preview_max_width, m_preview_max_height, + m_preview_v4lformat, V4L2_FIELD_ANY, PREVIEW_NUM_PLANE); + CHECK(ret); + + initParameters(m_camera_use_ISP); + +#ifdef SAMSUNG_EXYNOS4x12 +#ifdef ZERO_SHUTTER_LAG + if (m_camera_use_ISP) { + m_cam_fd2 = open(CAMERA_DEV_NAME2, O_RDWR); + LOGV("%s: open(%s) --> m_cam_fd2 = %d", __func__, CAMERA_DEV_NAME2, m_cam_fd2); + if (m_cam_fd2 < 0) { + LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, CAMERA_DEV_NAME2, strerror(errno)); + return -1; + } + + ret = fimc_v4l2_querycap(m_cam_fd2); + CHECK(ret); + if (!fimc_v4l2_enuminput(m_cam_fd2, index)) { + LOGE("m_cam_fd2(%d) fimc_v4l2_enuminput fail", m_cam_fd2); + return -1; + } + ret = fimc_v4l2_s_input(m_cam_fd2, index); + CHECK(ret); + } +#endif +#endif + + m_cam_fd3 = open(CAMERA_DEV_NAME3, O_RDWR); + LOGV("%s: open(%s) --> m_cam_fd3 = %d", __func__, CAMERA_DEV_NAME3, m_cam_fd3); + if (m_cam_fd3 < 0) { + LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, CAMERA_DEV_NAME3, strerror(errno)); + return -1; + } + + ret = fimc_v4l2_querycap(m_cam_fd3); + CHECK(ret); + if (!fimc_v4l2_enuminput(m_cam_fd3, index)) { + LOGE("m_cam_fd3(%d) fimc_v4l2_enuminput fail", m_cam_fd3); + return -1; + } + ret = fimc_v4l2_s_input(m_cam_fd3, index); + CHECK(ret); + + setExifFixedAttribute(); + } + +#ifdef ZERO_SHUTTER_LAG + if (m_camera_use_ISP) + m_cap_fd = m_cam_fd2; + else + m_cap_fd = m_cam_fd; +#else + m_cap_fd = m_cam_fd; +#endif + + m_rec_fd = m_cam_fd3; + + if (m_camera_use_ISP) + m_num_capbuf = CAP_BUFFERS; + else + m_num_capbuf = 1; + + m_flag_camera_create = 1; + + return 0; +} + +void SecCamera::resetCamera() +{ + LOGV("%s :", __func__); + DestroyCamera(); + CreateCamera(m_camera_id); +} + +bool SecCamera::DestroyCamera() +{ + LOGV("%s :", __func__); + + if (m_flagCreate) { + + stopRecord(); + + /* close m_cam_fd after stopRecord() because stopRecord() + * uses m_cam_fd to change frame rate + */ + LOGI("DestroyCamera: m_cam_fd(%d)", m_cam_fd); + if (m_cam_fd > -1) { + close(m_cam_fd); + m_cam_fd = -1; + } + +#ifdef ZERO_SHUTTER_LAG + if (m_camera_use_ISP) { + LOGI("DestroyCamera: m_cam_fd2(%d)", m_cam_fd2); + if (m_cam_fd2 > -1) { + close(m_cam_fd2); + m_cam_fd2 = -1; + } + } +#endif + + LOGI("DestroyCamera: m_cam_fd3(%d)", m_cam_fd3); + if (m_cam_fd3 > -1) { + close(m_cam_fd3); + m_cam_fd3 = -1; + } + + m_flagCreate = 0; + } else + LOGI("%s : already deinitialized", __func__); + + return 0; +} + +void SecCamera::initParameters(int internalISP) +{ + memset(&m_streamparm, 0, sizeof(m_streamparm)); + m_params = (struct sec_cam_parm*)&m_streamparm.parm.raw_data; + struct v4l2_captureparm capture; + + m_params->capture.timeperframe.numerator = 1; + m_params->capture.timeperframe.denominator = FRAME_RATE_AUTO; + m_params->flash_mode = FLASH_MODE_AUTO; + m_params->iso = ISO_AUTO; + m_params->metering = METERING_CENTER; + m_params->saturation = SATURATION_DEFAULT; + m_params->scene_mode = SCENE_MODE_NONE; + m_params->sharpness = SHARPNESS_DEFAULT; + m_params->white_balance = WHITE_BALANCE_AUTO; + m_params->anti_banding = ANTI_BANDING_OFF; + m_params->effects = IMAGE_EFFECT_NONE; + m_params->focus_mode = FOCUS_MODE_AUTO; + + if (internalISP) { + m_params->contrast = IS_CONTRAST_DEFAULT; + m_params->brightness = IS_BRIGHTNESS_DEFAULT; + m_params->exposure = IS_EXPOSURE_DEFAULT; + m_params->hue = IS_HUE_DEFAULT; + m_params->aeawb_mode = AE_UNLOCK_AWB_UNLOCK; + } else { + m_params->contrast = CONTRAST_DEFAULT; + m_params->brightness = EV_DEFAULT; + m_params->exposure = EV_DEFAULT; + m_params->hue = -1; + m_params->aeawb_mode = -1; + } +} + +int SecCamera::setMode(int recording_en) +{ + LOGV("%s :", __func__); + int mode; + + m_recording_en = recording_en; + + if (m_camera_use_ISP) { + if (!recording_en) + mode = IS_MODE_PREVIEW_STILL; + else + mode = IS_MODE_PREVIEW_VIDEO; + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_S_FORMAT_SCENARIO, mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_S_FORMAT_SCENARIO", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::getCameraFd(enum CAM_MODE mode) +{ + int ret = -1; + + switch (mode) { + case PREVIEW: + ret = m_cam_fd; + break; + case PICTURE: + ret = m_cap_fd; + break; + default: + ret = m_cam_fd; + break; + } + + return ret; +} + +int SecCamera::startPreview(void) +{ + v4l2_streamparm streamparm; + struct sec_cam_parm *parms; + parms = (struct sec_cam_parm*)&streamparm.parm.raw_data; + LOGV("%s :", __func__); + + // aleady started + if (m_flag_camera_start > 0) { + LOGE("ERR(%s):Preview was already started", __func__); + return 0; + } + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_cam_fd; + m_events_c.events = POLLIN | POLLERR; + + /* enum_fmt, s_fmt sample */ + int ret = fimc_v4l2_enum_fmt(m_cam_fd,m_preview_v4lformat); + CHECK(ret); + + LOGV("m_camera_use_ISP(%d), %s", m_camera_use_ISP, (const char*)getCameraSensorName()); + + if (m_camera_use_ISP) { + if (!m_recording_en) + fimc_v4l2_s_fmt_is(m_cam_fd, m_videosnapshot_width, m_videosnapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + else + fimc_v4l2_s_fmt_is(m_cam_fd, m_videosnapshot_width, m_videosnapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_VIDEO); + } + + ret = fimc_v4l2_s_fmt(m_cam_fd, m_preview_width, m_preview_height, m_preview_v4lformat, V4L2_FIELD_ANY, PREVIEW_NUM_PLANE); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + if (!m_camera_use_ISP) { + fimc_v4l2_s_fmt_is(m_cam_fd, m_preview_width, m_preview_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + } +#endif + + if (m_camera_use_ISP) { + if (!m_recording_en) + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL); + else + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_VIDEO); + } + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CACHEABLE, 1); + CHECK(ret); +#endif + + ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE, MAX_BUFFERS); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_querybuf(m_cam_fd, m_buffers_preview, V4L2_BUF_TYPE, MAX_BUFFERS, PREVIEW_NUM_PLANE); + CHECK(ret); +#endif + + LOGV("%s : m_preview_width: %d m_preview_height: %d m_angle: %d", + __func__, m_preview_width, m_preview_height, m_angle); + + LOGV("m_camera_id : %d", m_camera_id); + + /* start with all buffers in queue */ + for (int i = 0; i < MAX_BUFFERS; i++) { + ret = fimc_v4l2_qbuf(m_cam_fd, m_preview_width, m_preview_height, m_buffers_preview, i, PREVIEW_NUM_PLANE, PREVIEW_MODE); + CHECK(ret); + } + + ret = fimc_v4l2_streamon(m_cam_fd); + CHECK(ret); + +#ifdef USE_FACE_DETECTION + if (m_camera_use_ISP) { + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_START); + CHECK(ret); + } +#endif + +#ifdef ZERO_SHUTTER_LAG + if (m_camera_use_ISP && !m_recording_en) { + stopSnapshot(); + startSnapshot(NULL); + } +#endif + + m_flag_camera_start = 1; + + LOGV("%s: got the first frame of the preview", __func__); + + return 0; +} + +int SecCamera::stopPreview(void) +{ + int ret; + + LOGV("%s :", __func__); + + if (m_flag_camera_start == 0) { + LOGW("%s: doing nothing because m_flag_camera_start is zero", __func__); + return 0; + } + +#ifdef ZERO_SHUTTER_LAG + if (m_camera_use_ISP && !m_recording_en) + stopSnapshot(); +#endif + + if (m_params->flash_mode == FLASH_MODE_TORCH) + setFlashMode(FLASH_MODE_OFF); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } +#ifdef USE_FACE_DETECTION + if (m_camera_use_ISP) { + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_STOP); + CHECK(ret); + } +#endif + /* TODO : This code is temporary implementation. */ + /* Because streamoff is failed when ae lock or awb lock state */ + if (m_camera_use_ISP && m_params->aeawb_mode) { + if (m_params->aeawb_mode & 0x1) { + if (setAutoExposureLock(0) < 0) { + LOGE("ERR(%s): Fail on setAutoExposureLock()"); + return -1; + } + } + if (m_params->aeawb_mode & (0x1 << 1)) { + if (setAutoWhiteBalanceLock(0) < 0) { + LOGE("ERR(%s): Fail on setAutoWhiteBalnaceLock()"); + return -1; + } + } + m_params->aeawb_mode = 0; + } + + ret = fimc_v4l2_streamoff(m_cam_fd); + CHECK(ret); + + close_buffers(m_buffers_preview, MAX_BUFFERS); + + fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE, 0); + + m_flag_camera_start = 0; + + return ret; +} + +int SecCamera::startSnapshot(SecBuffer *yuv_buf) +{ + LOGV("%s :", __func__); + + // already started + if (m_snapshot_state) { + LOGI("%s: Doing nothing because snapshot is already started!", __func__); + return 0; + } + + if (m_cap_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + m_snapshot_state = 1; + + memset(&m_events_c2, 0, sizeof(m_events_c2)); + m_events_c2.fd = m_cap_fd; + m_events_c2.events = POLLIN | POLLERR; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV420"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12T"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV21"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV422P"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUYV"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) + LOGV("SnapshotFormat:V4L2_PIX_FMT_UYVY"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) + LOGV("SnapshotFormat:V4L2_PIX_FMT_RGB565"); + else + LOGV("SnapshotFormat:UnknownFormat"); +#endif + + int ret = fimc_v4l2_enum_fmt(m_cap_fd, m_snapshot_v4lformat); + CHECK(ret); + + if (m_camera_use_ISP) { + fimc_v4l2_s_fmt_is(m_cap_fd, m_videosnapshot_width, m_videosnapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + } + + if (!m_recording_en) + ret = fimc_v4l2_s_fmt_cap(m_cap_fd, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + else + ret = fimc_v4l2_s_fmt_cap(m_cap_fd, m_videosnapshot_width, m_videosnapshot_height, m_snapshot_v4lformat); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + if (!m_camera_use_ISP) + if (!m_recording_en) + fimc_v4l2_s_fmt_is(m_cap_fd, m_snapshot_width, m_snapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + else + fimc_v4l2_s_fmt_is(m_cap_fd, m_videosnapshot_width, m_videosnapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_VIDEO); +#endif + +#ifndef ZERO_SHUTTER_LAG + if (m_camera_use_ISP) + ret = fimc_v4l2_s_ctrl(m_cap_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL); + CHECK(ret); +#endif + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_s_ctrl(m_cap_fd, V4L2_CID_CACHEABLE, 1); + CHECK(ret); +#endif + + ret = fimc_v4l2_reqbufs(m_cap_fd, V4L2_BUF_TYPE, m_num_capbuf); + CHECK(ret); + +#ifdef BOARD_USE_V4L2_ION +#ifndef ZERO_SHUTTER_LAG + m_capture_buf[0].virt.p = (char *)yuv_buf->virt.p; +#endif +#else + ret = fimc_v4l2_querybuf(m_cap_fd, m_capture_buf, V4L2_BUF_TYPE, m_num_capbuf, 1); + CHECK(ret); +#endif + + /* start with all buffers in queue */ + for (int i = 0; i < m_num_capbuf; i++) { + ret = fimc_v4l2_qbuf(m_cap_fd, m_snapshot_width, m_snapshot_height, m_capture_buf, i, 1, CAPTURE_MODE); + CHECK(ret); + } + + ret = fimc_v4l2_streamon(m_cap_fd); + CHECK(ret); + + return 0; +} + +int SecCamera::stopSnapshot(void) +{ + int ret; + + LOGV("%s :", __func__); + + if (!m_snapshot_state) { + LOGI("%s: Doing nothing because snapshot is not started!", __func__); + return 0; + } + + if (m_cap_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + ret = fimc_v4l2_streamoff(m_cap_fd); + CHECK(ret); + + endSnapshot(); + + m_snapshot_state = 0; + + return ret; +} + +//Recording +int SecCamera::startRecord(bool recordHint) +{ + int ret, i; + + LOGV("%s :", __func__); + + // aleady started + if (m_flag_record_start > 0) { + LOGE("ERR(%s):Preview was already started", __func__); + return 0; + } + + if (m_rec_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + /* enum_fmt, s_fmt sample */ + ret = fimc_v4l2_enum_fmt(m_rec_fd, RECORD_PIX_FMT); + CHECK(ret); + + LOGI("%s: m_recording_width = %d, m_recording_height = %d", + __func__, m_recording_width, m_recording_height); + + LOGV("m_camera_use_ISP(%d), %s", m_camera_use_ISP, (const char*)getCameraSensorName()); + + if (m_camera_use_ISP) { + fimc_v4l2_s_fmt_is(m_rec_fd, m_videosnapshot_width, m_videosnapshot_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_CAPTURE_VIDEO); + + ret = fimc_v4l2_s_fmt(m_rec_fd, m_recording_width, + m_recording_height, RECORD_PIX_FMT, V4L2_FIELD_ANY, RECORD_NUM_PLANE); + CHECK(ret); + } else { + ret = fimc_v4l2_s_fmt(m_rec_fd, m_preview_width, + m_preview_height, RECORD_PIX_FMT, V4L2_FIELD_ANY, RECORD_NUM_PLANE); + CHECK(ret); +#ifndef BOARD_USE_V4L2_ION + fimc_v4l2_s_fmt_is(m_rec_fd, m_preview_width, m_preview_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_CAPTURE_VIDEO); +#endif + } + + if (!m_camera_use_ISP) { + ret = fimc_v4l2_s_ctrl(m_rec_fd, V4L2_CID_CAMERA_BUSFREQ_LOCK, 267160); + CHECK(ret); + } + + ret = fimc_v4l2_reqbufs(m_rec_fd, V4L2_BUF_TYPE, MAX_BUFFERS); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_querybuf(m_rec_fd, m_buffers_record, V4L2_BUF_TYPE, MAX_BUFFERS, RECORD_NUM_PLANE); + CHECK(ret); +#endif + + /* start with all buffers in queue */ + for (i = 0; i < MAX_BUFFERS; i++) { + ret = fimc_v4l2_qbuf(m_rec_fd, m_recording_width, m_recording_height, m_buffers_record, i, RECORD_NUM_PLANE, RECORD_MODE); + CHECK(ret); + } + + // Get and throw away the first frame since it is often garbled. + memset(&m_events_c3, 0, sizeof(m_events_c3)); + m_events_c3.fd = m_rec_fd; + m_events_c3.events = POLLIN | POLLERR; + + m_record_hint = recordHint; +#ifdef VIDEO_SNAPSHOT + if (m_camera_use_ISP && m_record_hint) { + stopSnapshot(); + startSnapshot(NULL); + } +#endif + + ret = fimc_v4l2_streamon(m_rec_fd); + CHECK(ret); + + m_flag_record_start = 1; + + return 0; +} + +int SecCamera::stopRecord(void) +{ + int ret; + + LOGV("%s :", __func__); + + if (m_flag_record_start == 0) { + LOGW("%s: doing nothing because m_flag_record_start is zero", __func__); + return 0; + } + +#ifdef VIDEO_SNAPSHOT + if (m_camera_use_ISP && m_record_hint) + stopSnapshot(); +#endif + + if (m_rec_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + m_flag_record_start = 0; + + if (!m_camera_use_ISP) { + ret = fimc_v4l2_s_ctrl(m_rec_fd, V4L2_CID_CAMERA_BUSFREQ_UNLOCK, 0); + CHECK(ret); + } + + ret = fimc_v4l2_streamoff(m_rec_fd); + CHECK(ret); + + close_buffers(m_buffers_record, MAX_BUFFERS); + + fimc_v4l2_reqbufs(m_rec_fd, V4L2_BUF_TYPE, 0); + + return 0; +} + +int SecCamera::getRecordAddr(int index, SecBuffer *buffer) +{ +#ifdef BOARD_USE_V4L2 + buffer->phys.extP[0] = (unsigned int)m_buffers_record[index].phys.extP[0]; + buffer->phys.extP[1] = (unsigned int)(m_buffers_record[index].phys.extP[0] + (m_recording_width * m_recording_height)); +#else + buffer->phys.extP[0] = fimc_v4l2_s_ctrl(m_rec_fd, V4L2_CID_PADDR_Y, index); + CHECK((int)buffer->phys.extP[0]); + buffer->phys.extP[1] = fimc_v4l2_s_ctrl(m_rec_fd, V4L2_CID_PADDR_CBCR, index); + CHECK((int)buffer->phys.extP[1]); +#endif + return 0; +} + +int SecCamera::getPreviewAddr(int index, SecBuffer *buffer) +{ +#ifdef BOARD_USE_V4L2 + buffer->phys.extP[0] = (unsigned int)m_buffers_preview[index].phys.extP[0]; + buffer->phys.extP[1] = (unsigned int)m_buffers_preview[index].phys.extP[1]; + buffer->virt.extP[0] = m_buffers_preview[index].virt.extP[0]; +#else + buffer->phys.extP[0] = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_PADDR_Y, index); + CHECK((int)buffer->phys.extP[0]); + buffer->phys.extP[1] = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_PADDR_CBCR, index); + CHECK((int)buffer->phys.extP[1]); +#endif + return 0; +} + +int SecCamera::getCaptureAddr(int index, SecBuffer *buffer) +{ + buffer->virt.extP[0] = m_capture_buf[index].virt.extP[0]; + CHECK((int)buffer->virt.extP[0]); + return 0; +} + +#ifdef BOARD_USE_V4L2_ION +void SecCamera::setUserBufferAddr(void *ptr, int index, int mode) +{ + if (mode == PREVIEW_MODE) { + m_buffers_preview[index].virt.extP[0] = (char *)((unsigned int *)ptr)[0]; + m_buffers_preview[index].virt.extP[1] = (char *)((unsigned int *)ptr)[1]; + m_buffers_preview[index].virt.extP[2] = (char *)((unsigned int *)ptr)[2]; + } else if (mode == CAPTURE_MODE) { + m_capture_buf[index].virt.extP[0] = (char *)ptr; + } else if (mode == RECORD_MODE) { + m_buffers_record[index].virt.extP[0] = (char *)ptr; + m_buffers_record[index].virt.extP[1] = (char *)ptr + (ALIGN((ALIGN(m_recording_width, 16) * ALIGN(m_recording_height, 16)), 2048)); + } else + LOGE("%s: Invalid fd!!!", __func__); +} +#endif + +int SecCamera::getPreview(camera_frame_metadata_t *facedata) +{ + int index; + int ret; + + if (m_flag_camera_start == 0 || fimc_poll(&m_events_c) == 0) { + LOGE("ERR(%s):Start Camera Device Reset", __func__); + /* + * When there is no data for more than 1 second from the camera we inform + * the FIMC driver by calling fimc_v4l2_s_input() with a special value = 1000 + * FIMC driver identify that there is something wrong with the camera + * and it restarts the sensor. + */ + stopPreview(); + /* Reset Only Camera Device */ + ret = fimc_v4l2_querycap(m_cam_fd); + CHECK(ret); + if (fimc_v4l2_enuminput(m_cam_fd, m_camera_id)) + return -1; + ret = fimc_v4l2_s_input(m_cam_fd, 1000); + CHECK(ret); +#ifdef BOARD_USE_V4L2_ION + m_preview_state = 0; + return -1; +#endif + ret = startPreview(); + if (ret < 0) { + LOGE("ERR(%s): startPreview() return %d", __func__, ret); + return 0; + } + } + + index = fimc_v4l2_dqbuf(m_cam_fd, PREVIEW_NUM_PLANE); + if (!(0 <= index && index < MAX_BUFFERS)) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return -1; + } + +#ifdef USE_FACE_DETECTION + if (m_camera_use_ISP) { + fimc_v4l2_s_ext_ctrl_face_detection(m_cam_fd, 0, facedata); + } +#endif + + return index; +} + +int SecCamera::setPreviewFrame(int index) +{ + int ret; + ret = fimc_v4l2_qbuf(m_cam_fd, m_preview_width, m_preview_height, m_buffers_preview, index, PREVIEW_NUM_PLANE, PREVIEW_MODE); + CHECK(ret); + + return ret; +} + +int SecCamera::getSnapshot() +{ + int index; + int ret; + + if (m_snapshot_state) { + fimc_poll(&m_events_c2); + + index = fimc_v4l2_dqbuf(m_cap_fd, 1); + if (!(0 <= index && index < m_num_capbuf)) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return -1; + } + return index; + } + + return -1; +} + +int SecCamera::setSnapshotFrame(int index) +{ + int ret; + ret = fimc_v4l2_qbuf(m_cap_fd, m_snapshot_width, m_snapshot_height, m_capture_buf, index, PREVIEW_NUM_PLANE, CAPTURE_MODE); + CHECK(ret); + + return ret; +} + +int SecCamera::getRecordFrame() +{ + if (m_flag_record_start == 0) { + LOGE("%s: m_flag_record_start is 0", __func__); + return -1; + } + + fimc_poll(&m_events_c3); + int index = fimc_v4l2_dqbuf(m_rec_fd, RECORD_NUM_PLANE); + if (!(0 <= index && index < MAX_BUFFERS)) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return -1; + } + + return index; +} + +int SecCamera::releaseRecordFrame(int index) +{ + if (!m_flag_record_start) { + /* this can happen when recording frames are returned after + * the recording is stopped at the driver level. we don't + * need to return the buffers in this case and we've seen + * cases where fimc could crash if we called qbuf and it + * wasn't expecting it. + */ + LOGI("%s: recording not in progress, ignoring", __func__); + return 0; + } + + return fimc_v4l2_qbuf(m_rec_fd, m_recording_width, m_recording_height, m_buffers_record, index, RECORD_NUM_PLANE, RECORD_MODE); +} + +int SecCamera::setPreviewSize(int width, int height, int pixel_format) +{ + LOGV("%s(width(%d), height(%d), format(%d))", __func__, width, height, pixel_format); + + int v4lpixelformat = pixel_format; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (v4lpixelformat == V4L2_PIX_FMT_YUV420) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUV420"); + else if (v4lpixelformat == V4L2_PIX_FMT_YVU420) + LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420"); + else if (v4lpixelformat == V4L2_PIX_FMT_YVU420M) + LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420M"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV12) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV12"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV12T) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV12T"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV21) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV21"); + else if (v4lpixelformat == V4L2_PIX_FMT_YUV422P) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUV422P"); + else if (v4lpixelformat == V4L2_PIX_FMT_YUYV) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUYV"); + else if (v4lpixelformat == V4L2_PIX_FMT_RGB565) + LOGV("PreviewFormat:V4L2_PIX_FMT_RGB565"); + else + LOGV("PreviewFormat:UnknownFormat"); +#endif + m_preview_width = width; + m_preview_height = height; + m_preview_v4lformat = v4lpixelformat; + + return 0; +} + +int SecCamera::getPreviewSize(int *width, int *height, int *frame_size) +{ + *width = m_preview_width; + *height = m_preview_height; + *frame_size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_preview_v4lformat), *width, *height); + return 0; +} + +int SecCamera::getPreviewMaxSize(int *width, int *height) +{ + *width = m_preview_max_width; + *height = m_preview_max_height; + + return 0; +} + +int SecCamera::getPreviewPixelFormat(void) +{ + return m_preview_v4lformat; +} + +/* + * Devide getJpeg() as two funcs, setSnapshotCmd() & getJpeg() because of the shutter sound timing. + * Here, just send the capture cmd to camera ISP to start JPEG capture. + */ +int SecCamera::setSnapshotCmd(void) +{ + LOGV("%s :", __func__); + + int ret = 0; + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return 0; + } + + if (m_flag_camera_start > 0) { + LOGW("WARN(%s):Camera was in preview, should have been stopped", __func__); + stopPreview(); + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_cam_fd; + m_events_c.events = POLLIN | POLLERR; + + int nframe = 1; + + ret = fimc_v4l2_enum_fmt(m_cam_fd,m_snapshot_v4lformat); + CHECK(ret); + ret = fimc_v4l2_s_fmt_cap(m_cam_fd, m_snapshot_width, m_snapshot_height, V4L2_PIX_FMT_JPEG); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + if (!m_camera_use_ISP) + if (!m_recording_en) + fimc_v4l2_s_fmt_is(m_cap_fd, m_snapshot_width, m_snapshot_height, + V4L2_PIX_FMT_JPEG, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + else + fimc_v4l2_s_fmt_is(m_cap_fd, m_videosnapshot_width, m_videosnapshot_height, + V4L2_PIX_FMT_JPEG, (enum v4l2_field) IS_MODE_PREVIEW_VIDEO); +#endif + + ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE, nframe); + CHECK(ret); + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_querybuf(m_cam_fd, m_capture_buf, V4L2_BUF_TYPE, 1, 1); + CHECK(ret); +#endif + + ret = fimc_v4l2_qbuf(m_cam_fd, m_snapshot_width, m_snapshot_height, m_capture_buf, 0, 1, CAPTURE_MODE); + CHECK(ret); + + ret = fimc_v4l2_streamon(m_cam_fd); + CHECK(ret); + + return 0; +} + +int SecCamera::endSnapshot(void) +{ + close_buffers(m_capture_buf, m_num_capbuf); + + fimc_v4l2_reqbufs(m_cap_fd, V4L2_BUF_TYPE, 0); + + return 0; +} + +/* + * Set Jpeg quality & exif info and get JPEG data from camera ISP + */ +unsigned char* SecCamera::getJpeg(int *jpeg_size, + int *thumb_size, + unsigned int *thumb_addr, + unsigned int *phyaddr) +{ + int index, ret = 0; + unsigned char *addr; + SecBuffer jpegAddr; + + // capture + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CAPTURE, 0); + CHECK_PTR(ret); + ret = fimc_poll(&m_events_c); + CHECK_PTR(ret); + index = fimc_v4l2_dqbuf(m_cam_fd, 1); + + if (index != 0) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return NULL; + } + + *jpeg_size = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_MAIN_SIZE); + CHECK_PTR(*jpeg_size); + + int main_offset = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_MAIN_OFFSET); + CHECK_PTR(main_offset); + + *thumb_size = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_THUMB_SIZE); + CHECK_PTR(*thumb_size); + + int thumb_offset = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_THUMB_OFFSET); + CHECK_PTR(thumb_offset); + + m_postview_offset = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET); + CHECK_PTR(m_postview_offset); + + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + + LOGV("\nsnapshot dqueued buffer = %d snapshot_width = %d snapshot_height = %d, size = %d", + index, m_snapshot_width, m_snapshot_height, *jpeg_size); + + addr = (unsigned char*)(m_capture_buf[0].virt.extP[0]) + main_offset; + + *thumb_addr = (unsigned int)(addr + thumb_offset); + + getPreviewAddr(index, &jpegAddr); + *phyaddr = jpegAddr.phys.extP[0] + m_postview_offset; + + ret = fimc_v4l2_streamoff(m_cam_fd); + CHECK_PTR(ret); + + return addr; +} + +int SecCamera::getExif(unsigned char *pExifDst, unsigned char *pThumbSrc, int thumbSize) +{ +#ifdef SAMSUNG_EXYNOS4210 + /* JPEG encode for smdkv310 */ + if (m_jpeg_fd > 0) { + if (api_jpeg_encode_deinit(m_jpeg_fd) != JPEG_OK) + LOGE("ERR(%s):Fail on api_jpeg_encode_deinit", __func__); + m_jpeg_fd = 0; + } + + m_jpeg_fd = api_jpeg_encode_init(); + LOGV("(%s):JPEG device open ID = %d", __func__, m_jpeg_fd); + + if (m_jpeg_fd <= 0) { + if (m_jpeg_fd < 0) { + m_jpeg_fd = 0; + LOGE("ERR(%s):Cannot open a jpeg device file", __func__); + return -1; + } + LOGE("ERR(%s):JPEG device was closed", __func__); + return -1; + } + + if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { + LOGE("ERR(%s):It doesn't support V4L2_PIX_FMT_RGB565", __func__); + return -1; + } + + struct jpeg_enc_param enc_param; + enum jpeg_frame_format inFormat = YUV_422; + enum jpeg_stream_format outFormat = JPEG_422; + + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + inFormat = YUV_420; + outFormat = JPEG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + default: + inFormat = YUV_422; + outFormat = JPEG_422; + break; + } + + // set encode parameters // + enc_param.width = m_jpeg_thumbnail_width; + enc_param.height = m_jpeg_thumbnail_width; + enc_param.in_fmt = inFormat; // YCBCR Only + enc_param.out_fmt = outFormat; + + if (m_jpeg_thumbnail_quality >= 90) + enc_param.quality = QUALITY_LEVEL_1; + else if (m_jpeg_thumbnail_quality >= 80) + enc_param.quality = QUALITY_LEVEL_2; + else if (m_jpeg_thumbnail_quality >= 70) + enc_param.quality = QUALITY_LEVEL_3; + else + enc_param.quality = QUALITY_LEVEL_4; + + api_jpeg_set_encode_param(&enc_param); + + unsigned int thumbnail_size = m_jpeg_thumbnail_width * m_jpeg_thumbnail_height * 2; + unsigned char *pInBuf = (unsigned char *)api_jpeg_get_encode_in_buf(m_jpeg_fd, thumbnail_size); + if (pInBuf == NULL) { + LOGE("ERR(%s):JPEG input buffer is NULL!!", __func__); + return -1; + } + + unsigned char *pOutBuf = (unsigned char *)api_jpeg_get_encode_out_buf(m_jpeg_fd); + if (pOutBuf == NULL) { + LOGE("ERR(%s):JPEG output buffer is NULL!!", __func__); + return -1; + } + + memcpy(pInBuf, pThumbSrc, thumbnail_size); + + enum jpeg_ret_type result = api_jpeg_encode_exe(m_jpeg_fd, &enc_param); + if (result != JPEG_ENCODE_OK) { + LOGE("ERR(%s):encode failed", __func__); + return -1; + } + + unsigned int outbuf_size = enc_param.size; + unsigned int exifSize; + + setExifChangedAttribute(); + + LOGV("%s: calling jpgEnc.makeExif, mExifInfo.width set to %d, height to %d", + __func__, mExifInfo.width, mExifInfo.height); + + LOGV("%s : enableThumb set to true", __func__); + mExifInfo.enableThumb = true; + + makeExif(pExifDst, pOutBuf, outbuf_size, &mExifInfo, &exifSize, true); +#endif + +#ifdef SAMSUNG_EXYNOS4x12 + /* JPEG encode for smdk4x12 */ + unsigned int exifSize; + + if (m_camera_use_ISP) { + LOGV("%s : m_jpeg_thumbnail_width = %d, height = %d", + __func__, m_jpeg_thumbnail_width, m_jpeg_thumbnail_height); + m_jpeg_fd = jpeghal_enc_init(); + LOGV("(%s):JPEG device open ID = %d", __func__, m_jpeg_fd); + + if (m_jpeg_fd <= 0) { + if (m_jpeg_fd < 0) { + m_jpeg_fd = 0; + LOGE("ERR(%s):Cannot open a jpeg device file", __func__); + return -1; + } + LOGE("ERR(%s):JPEG device was closed", __func__); + return -1; + } + + if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { + LOGE("ERR(%s):It doesn't support V4L2_PIX_FMT_RGB565", __func__); + return -1; + } + + struct jpeg_config enc_config; + int outFormat; + + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + outFormat = V4L2_PIX_FMT_JPEG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + default: + outFormat = V4L2_PIX_FMT_JPEG_422; + break; + } + + // set encode parameters // + enc_config.mode = JPEG_ENCODE; + + if (m_jpeg_thumbnail_quality >= 90) + enc_config.enc_qual = QUALITY_LEVEL_1; + else if (m_jpeg_thumbnail_quality >= 80) + enc_config.enc_qual = QUALITY_LEVEL_2; + else if (m_jpeg_thumbnail_quality >= 70) + enc_config.enc_qual = QUALITY_LEVEL_3; + else + enc_config.enc_qual = QUALITY_LEVEL_4; + + enc_config.width = m_jpeg_thumbnail_width; + enc_config.height = m_jpeg_thumbnail_height; + enc_config.pix.enc_fmt.in_fmt = m_snapshot_v4lformat; + enc_config.pix.enc_fmt.out_fmt = outFormat; + + jpeghal_enc_setconfig(m_jpeg_fd, &enc_config); + + jpeghal_s_ctrl(m_jpeg_fd, V4L2_CID_CACHEABLE, 1); + + struct jpeg_buf m_jpeg_inbuf; + m_jpeg_inbuf.memory = V4L2_MEMORY_MMAP; + m_jpeg_inbuf.num_planes = 1; + + if (jpeghal_set_inbuf(m_jpeg_fd, &m_jpeg_inbuf) < 0) { + LOGE("ERR(%s):Fail to JPEG input buffer!!", __func__); + return -1; + } + + struct jpeg_buf m_jpeg_outbuf; + m_jpeg_outbuf.memory = V4L2_MEMORY_MMAP; + m_jpeg_outbuf.num_planes = 1; + + if (jpeghal_set_outbuf(m_jpeg_fd, &m_jpeg_outbuf) < 0) { + LOGE("ERR(%s):Fail to JPEG output buffer!!", __func__); + return -1; + } + + memcpy(m_jpeg_inbuf.start[0], pThumbSrc, m_jpeg_inbuf.length[0]); + + if (jpeghal_enc_exe(m_jpeg_fd, &m_jpeg_inbuf, &m_jpeg_outbuf) < 0) { + LOGE("ERR(%s):encode failed", __func__); + return -1; + } + + int outbuf_size = jpeghal_g_ctrl(m_jpeg_fd, V4L2_CID_CAM_JPEG_ENCODEDSIZE); + if (outbuf_size < 0) { + LOGE("ERR(%s): jpeghal_g_ctrl fail on V4L2_CID_CAM_JPEG_ENCODEDSIZE", __func__); + return -1; + } + + setExifChangedAttribute(); + + LOGV("%s: calling jpgEnc.makeExif, mExifInfo.width set to %d, height to %d", + __func__, mExifInfo.width, mExifInfo.height); + + LOGV("%s : enableThumb set to true", __func__); + mExifInfo.enableThumb = true; + + makeExif(pExifDst, (unsigned char *)m_jpeg_outbuf.start[0], (unsigned int)outbuf_size, &mExifInfo, &exifSize, true); + + if (m_jpeg_fd > 0) { + if (jpeghal_deinit(m_jpeg_fd, &m_jpeg_inbuf, &m_jpeg_outbuf) < 0) + LOGE("ERR(%s):Fail on api_jpeg_encode_deinit", __func__); + m_jpeg_fd = 0; + } + } else { + setExifChangedAttribute(); + mExifInfo.enableThumb = true; + makeExif(pExifDst, pThumbSrc, (unsigned int)thumbSize, &mExifInfo, &exifSize, true); + } +#endif + + return exifSize; +} + +void SecCamera::getPostViewConfig(int *width, int *height, int *size) +{ + *width = m_snapshot_width; + *height = m_snapshot_height; + *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); + LOGV("[5B] m_preview_width : %d, mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d", + m_preview_width, *width, *height, *size); +} + +void SecCamera::getThumbnailConfig(int *width, int *height, int *size) +{ + *width = m_jpeg_thumbnail_width; + *height = m_jpeg_thumbnail_height; + *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); +} + +int SecCamera::getPostViewOffset(void) +{ + return m_postview_offset; +} + +int SecCamera::getSnapshotAndJpeg(SecBuffer *yuv_buf, int index, unsigned char *jpeg_buf, + int *output_size) +{ + LOGV("%s :", __func__); + + int ret = 0; + int i; + +#ifdef ZERO_SHUTTER_LAG + if (!m_camera_use_ISP){ + startSnapshot(yuv_buf); + + index = getSnapshot(); + if (index < 0) { + LOGE("ERR(%s): Invalid index!", __func__); + return -1; + } + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_s_ctrl(m_cap_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + LOGV("snapshot dequeued buffer = %d snapshot_width = %d snapshot_height = %d", + index, m_snapshot_width, m_snapshot_height); + + getCaptureAddr(index, yuv_buf); +#endif + + if (yuv_buf->virt.extP[0] == NULL) { + LOGE("ERR(%s):Fail on SecCamera getCaptureAddr = %0x ", + __func__, yuv_buf->virt.extP[0]); + return UNKNOWN_ERROR; + } + } +#else + startSnapshot(yuv_buf); + + index = getSnapshot(); + if (index < 0) { + LOGE("ERR(%s): Invalid index!", __func__); + return -1; + } + +#ifndef BOARD_USE_V4L2_ION + ret = fimc_v4l2_s_ctrl(m_cap_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + LOGV("snapshot dequeued buffer = %d snapshot_width = %d snapshot_height = %d", + index, m_snapshot_width, m_snapshot_height); + + getCaptureAddr(index, yuv_buf); +#endif + + if (yuv_buf->virt.extP[0] == NULL) { + LOGE("ERR(%s):Fail on SecCamera getCaptureAddr = %0x ", + __func__, yuv_buf->virt.extP[0]); + return UNKNOWN_ERROR; + } +#endif + +#ifdef SAMSUNG_EXYNOS4210 + /* JPEG encode for smdkv310 */ + if (m_jpeg_fd > 0) { + if (api_jpeg_encode_deinit(m_jpeg_fd) != JPEG_OK) + LOGE("ERR(%s):Fail on api_jpeg_encode_deinit", __func__); + m_jpeg_fd = 0; + } + + m_jpeg_fd = api_jpeg_encode_init(); + LOGV("(%s):JPEG device open ID = %d", __func__, m_jpeg_fd); + + if (m_jpeg_fd <= 0) { + if (m_jpeg_fd < 0) { + m_jpeg_fd = 0; + LOGE("ERR(%s):Cannot open a jpeg device file", __func__); + return -1; + } + LOGE("ERR(%s):JPEG device was closed", __func__); + return -1; + } + + if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { + LOGE("ERR(%s):It doesn't support V4L2_PIX_FMT_RGB565", __func__); + return -1; + } + + struct jpeg_enc_param enc_param; + enum jpeg_frame_format inFormat = YUV_422; + enum jpeg_stream_format outFormat = JPEG_422; + + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + inFormat = YUV_420; + outFormat = JPEG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + default: + inFormat = YUV_422; + outFormat = JPEG_422; + break; + } + + // set encode parameters // + enc_param.width = m_snapshot_width; + enc_param.height = m_snapshot_height; + enc_param.in_fmt = inFormat; // YCBCR Only + enc_param.out_fmt = outFormat; + + if (m_jpeg_quality >= 90) + enc_param.quality = QUALITY_LEVEL_1; + else if (m_jpeg_quality >= 80) + enc_param.quality = QUALITY_LEVEL_2; + else if (m_jpeg_quality >= 70) + enc_param.quality = QUALITY_LEVEL_3; + else + enc_param.quality = QUALITY_LEVEL_4; + + api_jpeg_set_encode_param(&enc_param); + + unsigned int snapshot_size = m_snapshot_width * m_snapshot_height * 2; + unsigned char *pInBuf = (unsigned char *)api_jpeg_get_encode_in_buf(m_jpeg_fd, snapshot_size); + if (pInBuf == NULL) { + LOGE("ERR(%s):JPEG input buffer is NULL!!", __func__); + return -1; + } + + unsigned char *pOutBuf = (unsigned char *)api_jpeg_get_encode_out_buf(m_jpeg_fd); + if (pOutBuf == NULL) { + LOGE("ERR(%s):JPEG output buffer is NULL!!", __func__); + return -1; + } + + memcpy(pInBuf, yuv_buf->virt.extP[0], snapshot_size); + + enum jpeg_ret_type result = api_jpeg_encode_exe(m_jpeg_fd, &enc_param); + if (result != JPEG_ENCODE_OK) { + LOGE("ERR(%s):encode failed", __func__); + return -1; + } + + *output_size = enc_param.size; + memcpy(jpeg_buf, pOutBuf, *output_size); +#endif + +#ifdef SAMSUNG_EXYNOS4x12 + /* JPEG encode for smdk4x12 */ + m_jpeg_fd = jpeghal_enc_init(); + LOGV("(%s):JPEG device open ID = %d", __func__, m_jpeg_fd); + + if (m_jpeg_fd <= 0) { + if (m_jpeg_fd < 0) { + m_jpeg_fd = 0; + LOGE("ERR(%s):Cannot open a jpeg device file", __func__); + return -1; + } + LOGE("ERR(%s):JPEG device was closed", __func__); + return -1; + } + + if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { + LOGE("ERR(%s):It doesn't support V4L2_PIX_FMT_RGB565", __func__); + return -1; + } + + struct jpeg_config enc_config; + int outFormat; + + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + outFormat = V4L2_PIX_FMT_JPEG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + default: + outFormat = V4L2_PIX_FMT_JPEG_422; + break; + } + + // set encode parameters // + enc_config.mode = JPEG_ENCODE; + + if (m_jpeg_quality >= 90) + enc_config.enc_qual = QUALITY_LEVEL_1; + else if (m_jpeg_quality >= 80) + enc_config.enc_qual = QUALITY_LEVEL_2; + else if (m_jpeg_quality >= 70) + enc_config.enc_qual = QUALITY_LEVEL_3; + else + enc_config.enc_qual = QUALITY_LEVEL_4; + + if (!m_recording_en) { + enc_config.width = m_snapshot_width; + enc_config.height = m_snapshot_height; + } else { + enc_config.width = m_videosnapshot_width; + enc_config.height = m_videosnapshot_height; + } + enc_config.pix.enc_fmt.in_fmt = m_snapshot_v4lformat; + enc_config.pix.enc_fmt.out_fmt = outFormat; + + jpeghal_enc_setconfig(m_jpeg_fd, &enc_config); + + ret = jpeghal_s_ctrl(m_jpeg_fd, V4L2_CID_CACHEABLE, 3); + CHECK(ret); + + struct jpeg_buf m_jpeg_inbuf; +#ifdef BOARD_USE_V4L2_ION + m_jpeg_inbuf.memory = V4L2_MEMORY_MMAP; + m_jpeg_inbuf.num_planes = 1; +#else + m_jpeg_inbuf.start[0] = (void *)fimc_v4l2_s_ctrl(m_cap_fd, V4L2_CID_PADDR_Y, index); + m_jpeg_inbuf.length[0] = m_capture_buf[index].size.extS[0]; + m_jpeg_inbuf.memory = V4L2_MEMORY_USERPTR; + m_jpeg_inbuf.num_planes = 1; +#endif + + if (jpeghal_set_inbuf(m_jpeg_fd, &m_jpeg_inbuf) < 0) { + LOGE("ERR(%s):Fail to JPEG input buffer!!", __func__); + return -1; + } + + for (i = 0; i < m_jpeg_inbuf.num_planes; i++) { + if ((unsigned int)m_jpeg_inbuf.start[i] & (SIZE_4K - 1)) { + LOGE("ERR(%s): JPEG start address should be aligned to 4 Kbytes", __func__); + return -1; + } else if ((unsigned int)enc_config.width & (16 - 1)) { + LOGE("ERR(%s): Image width should be multiple of 16", __func__); + return -1; + } + } + + struct jpeg_buf m_jpeg_outbuf; + m_jpeg_outbuf.memory = V4L2_MEMORY_MMAP; + m_jpeg_outbuf.num_planes = 1; + + if (jpeghal_set_outbuf(m_jpeg_fd, &m_jpeg_outbuf) < 0) { + LOGE("ERR(%s):Fail to JPEG output buffer!!", __func__); + return -1; + } + +#ifdef BOARD_USE_V4L2_ION + memcpy(m_jpeg_inbuf.start[0], yuv_buf->virt.extP[0], m_jpeg_inbuf.length[0]); +#endif + + if (jpeghal_enc_exe(m_jpeg_fd, &m_jpeg_inbuf, &m_jpeg_outbuf) < 0) { + LOGE("ERR(%s):encode failed", __func__); + return -1; + } + + ret = jpeghal_g_ctrl(m_jpeg_fd, V4L2_CID_CAM_JPEG_ENCODEDSIZE); + if (ret < 0) { + LOGE("ERR(%s): jpeghal_g_ctrl fail on V4L2_CID_CAM_JPEG_ENCODEDSIZE", __func__); + return -1; + } else { + *output_size = (unsigned int)ret; + } + + memcpy(jpeg_buf, m_jpeg_outbuf.start[0], *output_size); + + if (m_jpeg_fd > 0) { + if (jpeghal_deinit(m_jpeg_fd, &m_jpeg_inbuf, &m_jpeg_outbuf) < 0) + LOGE("ERR(%s):Fail on api_jpeg_encode_deinit", __func__); + m_jpeg_fd = 0; + } +#endif + + return 0; +} + +int SecCamera::setVideosnapshotSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_videosnapshot_width = width; + m_videosnapshot_height = height; + + return 0; +} + +int SecCamera::getVideosnapshotSize(int *width, int *height, int *frame_size) +{ + *width = m_videosnapshot_width; + *height = m_videosnapshot_height; + + int frame = 0; + + frame = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); + + // set it big. + if (frame == 0) + frame = m_videosnapshot_width * m_videosnapshot_height * BPP; + + *frame_size = frame; + + return 0; +} + +int SecCamera::setSnapshotSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_snapshot_width = width; + m_snapshot_height = height; + + return 0; +} + +int SecCamera::getSnapshotSize(int *width, int *height, int *frame_size) +{ + *width = m_snapshot_width; + *height = m_snapshot_height; + + int frame = 0; + + frame = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); + + // set it big. + if (frame == 0) + frame = m_snapshot_width * m_snapshot_height * BPP; + + *frame_size = frame; + + return 0; +} + +int SecCamera::getSnapshotMaxSize(int *width, int *height) +{ + *width = m_snapshot_max_width; + *height = m_snapshot_max_height; + + return 0; +} + +int SecCamera::setSnapshotPixelFormat(int pixel_format) +{ + int v4lpixelformat = pixel_format; + + if (m_snapshot_v4lformat != v4lpixelformat) { + m_snapshot_v4lformat = v4lpixelformat; + } + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) + LOGE("%s : SnapshotFormat:V4L2_PIX_FMT_YUV420", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12T", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV21", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUV422P", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUYV", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_UYVY", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_RGB565", __func__); + else + LOGD("SnapshotFormat:UnknownFormat"); +#endif + return 0; +} + +int SecCamera::getSnapshotPixelFormat(void) +{ + return m_snapshot_v4lformat; +} + +int SecCamera::getCameraId(void) +{ + return m_camera_id; +} + +int SecCamera::initSetParams(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ISO, ISO_AUTO) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ISO", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_METERING, METERING_CENTER) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_METERING", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SATURATION, SATURATION_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SCENE_MODE, SCENE_MODE_NONE) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SCENE_MODE", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SHARPNESS, SHARPNESS_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WHITE_BALANCE, WHITE_BALANCE_AUTO) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WHITE_BALANCE", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_BANDING, ANTI_BANDING_OFF) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_BANDING", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_CONTRAST, IS_CONTRAST_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_CONTRAST", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EFFECT, IMAGE_EFFECT_NONE) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_EFFECT", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_BRIGHTNESS, IS_BRIGHTNESS_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_BRIGHTNESS", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_EXPOSURE, IS_EXPOSURE_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_EXPOSURE", __func__); + return -1; + } +/* TODO */ +/* This code is temporary implementation because * + * hue value tuning was not complete */ +#ifdef USE_HUE + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_HUE, IS_HUE_DEFAULT) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_HUE", __func__); + return -1; + } +#endif + + initParameters(m_camera_use_ISP); + + return 0; +} + +int SecCamera::setAutofocus(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__); + return -1; + } + + m_auto_focus_state = 1; + + return 0; +} + +int SecCamera::setTouchAF(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_TOUCH) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __func__); + return -1; + } + + return 0; +} + +int SecCamera::getAutoFocusResult(void) +{ + int af_result; + + af_result = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT); + + LOGV("%s : returning %d", __func__, af_result); + + return af_result; +} + +int SecCamera::cancelAutofocus(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + +#ifndef BOARD_USE_V4L2 + if (m_flag_camera_start && m_auto_focus_state) { + if (m_params->focus_mode == FOCUS_MODE_AUTO || m_params->focus_mode == FOCUS_MODE_MACRO) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__); + return -1; + } + } + m_auto_focus_state = 0; + } +#endif + + return 0; +} + +int SecCamera::SetRotate(int angle) +{ + LOGE("%s(angle(%d))", __func__, angle); + + if (m_angle != angle) { + switch (angle) { + case -360: + case 0: + case 360: + m_angle = 0; + break; + + case -270: + case 90: + m_angle = 90; + break; + + case -180: + case 180: + m_angle = 180; + break; + + case -90: + case 270: + m_angle = 270; + break; + + default: + LOGE("ERR(%s):Invalid angle(%d)", __func__, angle); + return -1; + } + + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_ROTATION, angle) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_ROTATION", __func__); + return -1; + } + m_angle = angle; + } + } + + return 0; +} + +int SecCamera::getRotate(void) +{ + LOGV("%s : angle(%d)", __func__, m_angle); + return m_angle; +} + +int SecCamera::setFrameRate(int frame_rate) +{ + LOGV("%s(FrameRate(%d))", __func__, frame_rate); + + if (frame_rate < FRAME_RATE_AUTO || FRAME_RATE_MAX < frame_rate ) { + LOGE("ERR(%s):Invalid frame_rate(%d)", __func__, frame_rate); + return -1; + } + + if (m_params->capture.timeperframe.denominator != frame_rate) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FRAME_RATE, frame_rate) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FRAME_RATE", __func__); + return -1; + } + m_params->capture.timeperframe.denominator = frame_rate; + } + } + + return 0; +} + +int SecCamera::setVerticalMirror(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_VFLIP, 0) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_VFLIP", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setHorizontalMirror(void) +{ + LOGV("%s :", __func__); + + if (m_cam_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_HFLIP, 0) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_HFLIP", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setWhiteBalance(int white_balance) +{ + LOGV("%s(white_balance(%d))", __func__, white_balance); + + if (white_balance <= WHITE_BALANCE_BASE || WHITE_BALANCE_MAX <= white_balance) { + LOGE("ERR(%s):Invalid white_balance(%d)", __func__, white_balance); + return -1; + } + + if (m_params->white_balance != white_balance) { + if (m_flag_camera_create) { + LOGE("%s(white_balance(%d))", __func__, white_balance); + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WHITE_BALANCE, white_balance) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WHITE_BALANCE", __func__); + return -1; + } + m_params->white_balance = white_balance; + } + } + + return 0; +} + +int SecCamera::getWhiteBalance(void) +{ + LOGV("%s : white_balance(%d)", __func__, m_params->white_balance); + return m_params->white_balance; +} + +int SecCamera::setBrightness(int brightness) +{ + LOGV("%s(brightness(%d))", __func__, brightness); + + if (m_camera_use_ISP) { + brightness += IS_BRIGHTNESS_DEFAULT; + if (brightness < IS_BRIGHTNESS_MINUS_2 || IS_BRIGHTNESS_PLUS_2 < brightness) { + LOGE("ERR(%s):Invalid brightness(%d)", __func__, brightness); + return -1; + } + } else { + LOGW("WARN(%s):Not supported brightness setting", __func__); + return 0; + } + + if (m_params->brightness != brightness) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_BRIGHTNESS, brightness) < EV_MINUS_4) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_BRIGHTNESS", __func__); + return -1; + } + m_params->brightness = brightness; + } + } + + return 0; +} + +int SecCamera::getBrightness(void) +{ + LOGV("%s : brightness(%d)", __func__, m_params->brightness); + return m_params->brightness; +} + +int SecCamera::setExposure(int exposure) +{ + LOGV("%s(exposure(%d))", __func__, exposure); + + if (m_camera_use_ISP) { + exposure += IS_EXPOSURE_DEFAULT; + if (exposure < IS_EXPOSURE_MINUS_4 || IS_EXPOSURE_PLUS_4 < exposure) { + LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure); + return -1; + } + } else { + exposure += EV_DEFAULT; + if (exposure < EV_MINUS_4 || EV_PLUS_4 < exposure) { + LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure); + return -1; + } + } + + if (m_params->exposure != exposure) { + if (m_flag_camera_create) { + if (m_camera_use_ISP) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_EXPOSURE, exposure) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_EXPOSURE", __func__); + return -1; + } + } else { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BRIGHTNESS, exposure) < EV_MINUS_4) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BRIGHTNESS", __func__); + return -1; + } + } + m_params->exposure = exposure; + } + } + + return 0; +} + +int SecCamera::getExposure(void) +{ + LOGV("%s : exposure(%d)", __func__, m_params->exposure); + return m_params->exposure; +} + +int SecCamera::setImageEffect(int image_effect) +{ + LOGV("%s(image_effect(%d))", __func__, image_effect); + + if (image_effect <= IMAGE_EFFECT_BASE || IMAGE_EFFECT_MAX <= image_effect) { + LOGE("ERR(%s):Invalid image_effect(%d)", __func__, image_effect); + return -1; + } + + if (m_params->effects != image_effect) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EFFECT, image_effect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_EFFECT", __func__); + return -1; + } + m_params->effects = image_effect; + } + } + + return 0; +} + +int SecCamera::getImageEffect(void) +{ + LOGV("%s : image_effect(%d)", __func__, m_params->effects); + return m_params->effects; +} + +int SecCamera::setAntiBanding(int anti_banding) +{ + LOGV("%s(anti_banding(%d))", __func__, anti_banding); + + if (anti_banding < ANTI_BANDING_AUTO || ANTI_BANDING_OFF < anti_banding) { + LOGE("ERR(%s):Invalid anti_banding (%d)", __func__, anti_banding); + return -1; + } + + if (m_params->anti_banding != anti_banding) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_BANDING, anti_banding) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_BANDING", __func__); + return -1; + } + m_params->anti_banding = anti_banding; + } + } + + return 0; +} + +int SecCamera::setSceneMode(int scene_mode) +{ + LOGV("%s(scene_mode(%d))", __func__, scene_mode); + + if (scene_mode <= SCENE_MODE_BASE || SCENE_MODE_MAX <= scene_mode) { + LOGE("ERR(%s):Invalid scene_mode (%d)", __func__, scene_mode); + return -1; + } + + if (m_params->scene_mode != scene_mode) { + if (m_flag_camera_create) { + LOGE("%s(scene_mode(%d))", __func__, scene_mode); + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SCENE_MODE, scene_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SCENE_MODE", __func__); + return -1; + } + m_params->scene_mode = scene_mode; + } + } + + return 0; +} + +int SecCamera::getSceneMode(void) +{ + return m_params->scene_mode; +} + +int SecCamera::setFlashMode(int flash_mode) +{ + LOGV("%s(flash_mode(%d))", __func__, flash_mode); + + if (flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) { + LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode); + return -1; + } + + if (m_params->flash_mode != flash_mode) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __func__); + return -1; + } + m_params->flash_mode = flash_mode; + } + } + + return 0; +} + +int SecCamera::getFlashMode(void) +{ + return m_params->flash_mode; +} + +int SecCamera::setAutoExposureLock(int toggle) +{ + LOGV("%s(toggle value(%d))", __func__, toggle); + + int aeawb_mode = m_params->aeawb_mode; + + if (m_flag_camera_create) { + if (toggle ^ aeawb_mode) { + aeawb_mode = aeawb_mode ^ 0x1; + m_params->aeawb_mode = aeawb_mode; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, aeawb_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK", __func__); + return -1; + } + } + } + return 0; +} + +int SecCamera::setAutoWhiteBalanceLock(int toggle) +{ + LOGV("%s(toggle value(%d))", __func__, toggle); + + int aeawb_mode = m_params->aeawb_mode; + + if (m_flag_camera_create) { + if (toggle ^ (aeawb_mode >> 1)) { + aeawb_mode = aeawb_mode ^ (0x1 << 1); + m_params->aeawb_mode = aeawb_mode; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, aeawb_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK", __func__); + return -1; + } + } + } + return 0; +} + +int SecCamera::setISO(int iso_value) +{ + LOGV("%s(iso_value(%d))", __func__, iso_value); + + if (iso_value < ISO_AUTO || ISO_MAX <= iso_value) { + LOGE("ERR(%s):Invalid iso_value (%d)", __func__, iso_value); + return -1; + } + + if (m_params->iso != iso_value) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ISO, iso_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ISO", __func__); + return -1; + } + m_params->iso = iso_value; + } + } + + return 0; +} + +int SecCamera::getISO(void) +{ + return m_params->iso; +} + +int SecCamera::setContrast(int contrast_value) +{ + LOGV("%s(contrast_value(%d))", __func__, contrast_value); + + if (m_camera_use_ISP) { + if (contrast_value < IS_CONTRAST_AUTO || IS_CONTRAST_MAX <= contrast_value) { + LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value); + return -1; + } + } else { + if (contrast_value < CONTRAST_MINUS_2 || CONTRAST_MAX <= contrast_value) { + LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value); + return -1; + } + } + + if (m_params->contrast != contrast_value) { + if (m_flag_camera_create) { + if (m_camera_use_ISP) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_CONTRAST, contrast_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_CONTRAST", __func__); + return -1; + } + } else { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CONTRAST, contrast_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CONTRAST", __func__); + return -1; + } + } + m_params->contrast = contrast_value; + } + } + + return 0; +} + +int SecCamera::getContrast(void) +{ + return m_params->contrast; +} + +int SecCamera::setSaturation(int saturation_value) +{ + LOGV("%s(saturation_value(%d))", __func__, saturation_value); + + saturation_value += SATURATION_DEFAULT; + if (saturation_value < SATURATION_MINUS_2 || SATURATION_MAX <= saturation_value) { + LOGE("ERR(%s):Invalid saturation_value (%d)", __func__, saturation_value); + return -1; + } + + if (m_params->saturation != saturation_value) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SATURATION, saturation_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__); + return -1; + } + m_params->saturation = saturation_value; + } + } + + return 0; +} + +int SecCamera::getSaturation(void) +{ + return m_params->saturation; +} + +int SecCamera::setSharpness(int sharpness_value) +{ + LOGV("%s(sharpness_value(%d))", __func__, sharpness_value); + + sharpness_value += SHARPNESS_DEFAULT; + if (sharpness_value < SHARPNESS_MINUS_2 || SHARPNESS_MAX <= sharpness_value) { + LOGE("ERR(%s):Invalid sharpness_value (%d)", __func__, sharpness_value); + return -1; + } + + if (m_params->sharpness != sharpness_value) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SHARPNESS, sharpness_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__); + return -1; + } + m_params->sharpness = sharpness_value; + } + } + + return 0; +} + +int SecCamera::getSharpness(void) +{ + return m_params->sharpness; +} + +int SecCamera::setHue(int hue_value) +{ + LOGV("%s(hue_value(%d))", __func__, hue_value); + +/* TODO */ +/* This code is temporary implementation because * + * hue value tuning was not complete */ +#ifdef USE_HUE + if (m_camera_use_ISP) { + hue_value += IS_HUE_DEFAULT; + if (hue_value < IS_HUE_MINUS_2 || IS_HUE_MAX <= hue_value) { + LOGE("ERR(%s):Invalid hue_value (%d)", __func__, hue_value); + return -1; + } + } else { + LOGW("WARN(%s):Not supported hue setting", __func__); + return 0; + } + + if (m_params->hue != hue_value) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_HUE, hue_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_HUE", __func__); + return -1; + } + m_params->hue = hue_value; + } + } +#endif + + return 0; +} + +int SecCamera::getHue(void) +{ + return m_params->hue; +} + +int SecCamera::setWDR(int wdr_value) +{ + LOGV("%s(wdr_value(%d))", __func__, wdr_value); + + if (m_camera_use_ISP) { + if (wdr_value < IS_DRC_BYPASS_DISABLE || IS_DRC_BYPASS_MAX <= wdr_value) { + LOGE("ERR(%s):Invalid drc_value (%d)", __func__, wdr_value); + return -1; + } + } else { + if (wdr_value < WDR_OFF || WDR_MAX <= wdr_value) { + LOGE("ERR(%s):Invalid wdr_value (%d)", __func__, wdr_value); + return -1; + } + } + + if (m_wdr != wdr_value) { + if (m_flag_camera_create) { + if (m_camera_use_ISP) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_SET_DRC, wdr_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_SET_DRC", __func__); + return -1; + } + } else { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WDR, wdr_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WDR", __func__); + return -1; + } + } + m_wdr = wdr_value; + } + } + + return 0; +} + +int SecCamera::getWDR(void) +{ + return m_wdr; +} + +int SecCamera::setAntiShake(int anti_shake) +{ + LOGV("%s(anti_shake(%d))", __func__, anti_shake); + + if (anti_shake < ANTI_SHAKE_OFF || ANTI_SHAKE_MAX <= anti_shake) { + LOGE("ERR(%s):Invalid anti_shake (%d)", __func__, anti_shake); + return -1; + } + + if (m_anti_shake != anti_shake) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_SHAKE, anti_shake) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_SHAKE", __func__); + return -1; + } + m_anti_shake = anti_shake; + } + } + + return 0; +} + +int SecCamera::getAntiShake(void) +{ + return m_anti_shake; +} + +int SecCamera::setMetering(int metering_value) +{ + LOGV("%s(metering (%d))", __func__, metering_value); + + if (metering_value <= METERING_BASE || METERING_MAX <= metering_value) { + LOGE("ERR(%s):Invalid metering_value (%d)", __func__, metering_value); + return -1; + } + + if (m_params->metering != metering_value) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_METERING, metering_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_METERING", __func__); + return -1; + } + m_params->metering = metering_value; + } + } + + return 0; +} + +int SecCamera::getMetering(void) +{ + return m_params->metering; +} + +int SecCamera::setJpegQuality(int jpeg_quality) +{ + LOGV("%s(jpeg_quality (%d))", __func__, jpeg_quality); + + if (jpeg_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_quality) { + LOGE("ERR(%s):Invalid jpeg_quality (%d)", __func__, jpeg_quality); + return -1; + } + + if (m_jpeg_quality != jpeg_quality) { + m_jpeg_quality = jpeg_quality; + if (m_flag_camera_create && !m_camera_use_ISP) { + jpeg_quality -= 5; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAM_JPEG_QUALITY", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getJpegQuality(void) +{ + return m_jpeg_quality; +} + +int SecCamera::setZoom(int zoom_level) +{ + LOGV("%s(zoom_level (%d))", __func__, zoom_level); + + if (zoom_level < ZOOM_LEVEL_0 || ZOOM_LEVEL_MAX <= zoom_level) { + LOGE("ERR(%s):Invalid zoom_level (%d)", __func__, zoom_level); + return -1; + } + + if (m_zoom_level != zoom_level) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ZOOM, zoom_level) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ZOOM", __func__); + return -1; + } + m_zoom_level = zoom_level; + } + } + + return 0; +} + +int SecCamera::getZoom(void) +{ + return m_zoom_level; +} + +int SecCamera::setObjectTracking(int object_tracking) +{ + LOGV("%s(object_tracking (%d))", __func__, object_tracking); + + if (object_tracking < OBJECT_TRACKING_OFF || OBJECT_TRACKING_MAX <= object_tracking) { + LOGE("ERR(%s):Invalid object_tracking (%d)", __func__, object_tracking); + return -1; + } + + if (m_object_tracking != object_tracking) + m_object_tracking = object_tracking; + + return 0; +} + +int SecCamera::getObjectTracking(void) +{ + return m_object_tracking; +} + +int SecCamera::getObjectTrackingStatus(void) +{ + int obj_status = 0; + obj_status = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJ_TRACKING_STATUS); + return obj_status; +} + +int SecCamera::setObjectTrackingStartStop(int start_stop) +{ + LOGV("%s(object_tracking_start_stop (%d))", __func__, start_stop); + + if (m_object_tracking_start_stop != start_stop) { + m_object_tracking_start_stop = start_stop; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP, start_stop) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setTouchAFStartStop(int start_stop) +{ + LOGV("%s(touch_af_start_stop (%d))", __func__, start_stop); + + if (m_touch_af_start_stop != start_stop) { + m_touch_af_start_stop = start_stop; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_TOUCH_AF_START_STOP, start_stop) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_TOUCH_AF_START_STOP", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setSmartAuto(int smart_auto) +{ + LOGV("%s(smart_auto (%d))", __func__, smart_auto); + + if (smart_auto < SMART_AUTO_OFF || SMART_AUTO_MAX <= smart_auto) { + LOGE("ERR(%s):Invalid smart_auto (%d)", __func__, smart_auto); + return -1; + } + + if (m_smart_auto != smart_auto) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SMART_AUTO, smart_auto) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SMART_AUTO", __func__); + return -1; + } + m_smart_auto = smart_auto; + } + } + + return 0; +} + +int SecCamera::getSmartAuto(void) +{ + return m_smart_auto; +} + +int SecCamera::getAutosceneStatus(void) +{ + int autoscene_status = -1; + + if (getSmartAuto() == SMART_AUTO_ON) { + autoscene_status = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_SMART_AUTO_STATUS); + + if ((autoscene_status < SMART_AUTO_STATUS_AUTO) || (autoscene_status > SMART_AUTO_STATUS_MAX)) { + LOGE("ERR(%s):Invalid getAutosceneStatus (%d)", __func__, autoscene_status); + return -1; + } + } + return autoscene_status; +} + +int SecCamera::setBeautyShot(int beauty_shot) +{ + LOGV("%s(beauty_shot (%d))", __func__, beauty_shot); + + if (beauty_shot < BEAUTY_SHOT_OFF || BEAUTY_SHOT_MAX <= beauty_shot) { + LOGE("ERR(%s):Invalid beauty_shot (%d)", __func__, beauty_shot); + return -1; + } + + if (m_beauty_shot != beauty_shot) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BEAUTY_SHOT, beauty_shot) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BEAUTY_SHOT", __func__); + return -1; + } + m_beauty_shot = beauty_shot; + } + + setFaceDetect(FACE_DETECTION_ON_BEAUTY); + } + + return 0; +} + +int SecCamera::getBeautyShot(void) +{ + return m_beauty_shot; +} + +int SecCamera::setVintageMode(int vintage_mode) +{ + LOGV("%s(vintage_mode(%d))", __func__, vintage_mode); + + if (vintage_mode <= VINTAGE_MODE_BASE || VINTAGE_MODE_MAX <= vintage_mode) { + LOGE("ERR(%s):Invalid vintage_mode (%d)", __func__, vintage_mode); + return -1; + } + + if (m_vintage_mode != vintage_mode) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_VINTAGE_MODE, vintage_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_VINTAGE_MODE", __func__); + return -1; + } + m_vintage_mode = vintage_mode; + } + } + + return 0; +} + +int SecCamera::getVintageMode(void) +{ + return m_vintage_mode; +} + +int SecCamera::setFocusMode(int focus_mode) +{ + LOGV("%s(focus_mode(%d))", __func__, focus_mode); + + if (FOCUS_MODE_MAX <= focus_mode) { + LOGE("ERR(%s):Invalid focus_mode (%d)", __func__, focus_mode); + return -1; + } + + if (m_params->focus_mode != focus_mode) { + if (m_flag_camera_create) { + if (m_params->focus_mode == FOCUS_MODE_AUTO || m_params->focus_mode == FOCUS_MODE_MACRO) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__); + return -1; + } + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __func__); + return -1; + } + if (!m_camera_use_ISP) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__); + return -1; + } + } + m_params->focus_mode = focus_mode; + } + } + + return 0; +} + +int SecCamera::getFocusMode(void) +{ + return m_params->focus_mode; +} + +int SecCamera::setFaceDetect(int face_detect) +{ + LOGV("%s(face_detect(%d))", __func__, face_detect); + if (m_camera_use_ISP) { + if (face_detect < IS_FD_COMMAND_STOP || IS_FD_COMMAND_MAX <= face_detect) { + LOGE("ERR(%s):Invalid face_detect value (%d)", __func__, face_detect); + return -1; + } + } else { + if (face_detect < FACE_DETECTION_OFF || FACE_DETECTION_MAX <= face_detect) { + LOGE("ERR(%s):Invalid face_detect value (%d)", __func__, face_detect); + return -1; + } + } + + if (m_face_detect != face_detect) { + if (m_flag_camera_create) { + if (m_camera_use_ISP) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_IS_CMD_FD, face_detect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CMD_FD", __func__); + return -1; + } + } else { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FACE_DETECTION, face_detect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACE_DETECTION", __func__); + return -1; + } + } + m_face_detect = face_detect; + } + } + + return 0; +} + +int SecCamera::getFaceDetect(void) +{ + return m_face_detect; +} + +int SecCamera::setGPSLatitude(const char *gps_latitude) +{ + double conveted_latitude = 0; + LOGV("%s(gps_latitude(%s))", __func__, gps_latitude); + if (gps_latitude == NULL) + m_gps_latitude = 0; + else { + conveted_latitude = atof(gps_latitude); + m_gps_latitude = (long)(conveted_latitude * 10000 / 1); + } + + LOGV("%s(m_gps_latitude(%ld))", __func__, m_gps_latitude); + return 0; +} + +int SecCamera::setGPSLongitude(const char *gps_longitude) +{ + double conveted_longitude = 0; + LOGV("%s(gps_longitude(%s))", __func__, gps_longitude); + if (gps_longitude == NULL) + m_gps_longitude = 0; + else { + conveted_longitude = atof(gps_longitude); + m_gps_longitude = (long)(conveted_longitude * 10000 / 1); + } + + LOGV("%s(m_gps_longitude(%ld))", __func__, m_gps_longitude); + return 0; +} + +int SecCamera::setGPSAltitude(const char *gps_altitude) +{ + double conveted_altitude = 0; + LOGV("%s(gps_altitude(%s))", __func__, gps_altitude); + if (gps_altitude == NULL) + m_gps_altitude = 0; + else { + conveted_altitude = atof(gps_altitude); + m_gps_altitude = (long)(conveted_altitude * 100 / 1); + } + + LOGV("%s(m_gps_altitude(%ld))", __func__, m_gps_altitude); + return 0; +} + +int SecCamera::setGPSTimeStamp(const char *gps_timestamp) +{ + LOGV("%s(gps_timestamp(%s))", __func__, gps_timestamp); + if (gps_timestamp == NULL) + m_gps_timestamp = 0; + else + m_gps_timestamp = atol(gps_timestamp); + + LOGV("%s(m_gps_timestamp(%ld))", __func__, m_gps_timestamp); + return 0; +} + +int SecCamera::setGPSProcessingMethod(const char *gps_processing_method) +{ + LOGV("%s(gps_processing_method(%s))", __func__, gps_processing_method); + memset(mExifInfo.gps_processing_method, 0, sizeof(mExifInfo.gps_processing_method)); + if (gps_processing_method != NULL) { + size_t len = strlen(gps_processing_method); + if (len > sizeof(mExifInfo.gps_processing_method)) { + len = sizeof(mExifInfo.gps_processing_method); + } + memcpy(mExifInfo.gps_processing_method, gps_processing_method, len); + } + return 0; +} + +int SecCamera::setFaceDetectLockUnlock(int facedetect_lockunlock) +{ + LOGV("%s(facedetect_lockunlock(%d))", __func__, facedetect_lockunlock); + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, facedetect_lockunlock) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setObjectPosition(int x, int y) +{ + LOGV("%s(setObjectPosition(x=%d, y=%d))", __func__, x, y); + + if (m_flag_camera_start) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, x) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_X", __func__); + return -1; + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, y) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_Y", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setGamma(int gamma) +{ + LOGV("%s(gamma(%d))", __func__, gamma); + + if (gamma < GAMMA_OFF || GAMMA_MAX <= gamma) { + LOGE("ERR(%s):Invalid gamma (%d)", __func__, gamma); + return -1; + } + + if (m_video_gamma != gamma) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_GAMMA, gamma) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_GAMMA", __func__); + return -1; + } + m_video_gamma = gamma; + } + } + + return 0; +} + +int SecCamera::setSlowAE(int slow_ae) +{ + LOGV("%s(slow_ae(%d))", __func__, slow_ae); + + if (slow_ae < GAMMA_OFF || GAMMA_MAX <= slow_ae) { + LOGE("ERR(%s):Invalid slow_ae (%d)", __func__, slow_ae); + return -1; + } + + if (m_slow_ae!= slow_ae) { + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_SLOW_AE, slow_ae) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_SLOW_AE", __func__); + return -1; + } + m_slow_ae = slow_ae; + } + } + + return 0; +} + +int SecCamera::setRecordingSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_recording_width = width; + m_recording_height = height; + + return 0; +} + +int SecCamera::getRecordingSize(int *width, int *height) +{ + *width = m_recording_width; + *height = m_recording_height; + + return 0; +} + +int SecCamera::setExifOrientationInfo(int orientationInfo) +{ + LOGV("%s(orientationInfo(%d))", __func__, orientationInfo); + + if (orientationInfo < 0) { + LOGE("ERR(%s):Invalid orientationInfo (%d)", __func__, orientationInfo); + return -1; + } + m_exif_orientation = orientationInfo; + + return 0; +} + +int SecCamera::setBatchReflection() +{ + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BATCH_REFLECTION, 1) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BATCH_REFLECTION", __func__); + return -1; + } + } + + return 0; +} + +/* Camcorder fix fps */ +int SecCamera::setSensorMode(int sensor_mode) +{ + LOGV("%s(sensor_mode (%d))", __func__, sensor_mode); + + if (sensor_mode < SENSOR_MODE_CAMERA || SENSOR_MODE_MOVIE < sensor_mode) { + LOGE("ERR(%s):Invalid sensor mode (%d)", __func__, sensor_mode); + return -1; + } + + if (m_sensor_mode != sensor_mode) + m_sensor_mode = sensor_mode; + + return 0; +} + +/* Shot mode */ +/* SINGLE = 0 +* CONTINUOUS = 1 +* PANORAMA = 2 +* SMILE = 3 +* SELF = 6 +*/ +int SecCamera::setShotMode(int shot_mode) +{ + LOGV("%s(shot_mode (%d))", __func__, shot_mode); + if (shot_mode < SHOT_MODE_SINGLE || SHOT_MODE_SELF < shot_mode) { + LOGE("ERR(%s):Invalid shot_mode (%d)", __func__, shot_mode); + return -1; + } + m_shot_mode = shot_mode; + + return 0; +} + +int SecCamera::setDataLineCheck(int chk_dataline) +{ + LOGV("%s(chk_dataline (%d))", __func__, chk_dataline); + + if (chk_dataline < CHK_DATALINE_OFF || CHK_DATALINE_MAX <= chk_dataline) { + LOGE("ERR(%s):Invalid chk_dataline (%d)", __func__, chk_dataline); + return -1; + } + + m_chk_dataline = chk_dataline; + + return 0; +} + +int SecCamera::getDataLineCheck(void) +{ + return m_chk_dataline; +} + +int SecCamera::setDataLineCheckStop(void) +{ + LOGV("%s", __func__); + + if (m_flag_camera_create) { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CHECK_DATALINE_STOP, 1) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CHECK_DATALINE_STOP", __func__); + return -1; + } + } + return 0; +} + +const __u8* SecCamera::getCameraSensorName(void) +{ + LOGV("%s", __func__); + + return fimc_v4l2_enuminput(m_cam_fd, getCameraId()); +} + +bool SecCamera::getUseInternalISP(void) +{ + LOGV("%s", __func__); + int ret = 0; + +/*TODO*/ + if (!strncmp((const char*)getCameraSensorName(), "ISP Camera", 10)) + return true; + else if(!strncmp((const char*)getCameraSensorName(), "S5K3H2", 10)) + return true; + else if(!strncmp((const char*)getCameraSensorName(), "S5K3H7", 10)) + return true; + else if(!strncmp((const char*)getCameraSensorName(), "S5K4E5", 10)) + return true; + else if(!strncmp((const char*)getCameraSensorName(), "S5K6A3", 10)) + return true; + else + return false; +} + +#ifdef ENABLE_ESD_PREVIEW_CHECK +int SecCamera::getCameraSensorESDStatus(void) +{ + LOGV("%s", __func__); + + // 0 : normal operation, 1 : abnormal operation + int status = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_ESD_INT); + + return status; +} +#endif // ENABLE_ESD_PREVIEW_CHECK + +int SecCamera::setJpegThumbnailSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_jpeg_thumbnail_width = width; + m_jpeg_thumbnail_height = height; + + return 0; +} + +int SecCamera::getJpegThumbnailSize(int *width, int *height) +{ + if (width) + *width = m_jpeg_thumbnail_width; + if (height) + *height = m_jpeg_thumbnail_height; + + return 0; +} + +int SecCamera::setJpegThumbnailQuality(int jpeg_thumbnail_quality) +{ + LOGV("%s(jpeg_thumbnail_quality (%d))", __func__, jpeg_thumbnail_quality); + + if (jpeg_thumbnail_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_thumbnail_quality) { + LOGE("ERR(%s):Invalid jpeg_thumbnail_quality (%d)", __func__, jpeg_thumbnail_quality); + return -1; + } + + if (m_jpeg_thumbnail_quality != jpeg_thumbnail_quality) { + m_jpeg_thumbnail_quality = jpeg_thumbnail_quality; + } + + return 0; +} + +int SecCamera::getJpegThumbnailQuality(void) +{ + return m_jpeg_thumbnail_quality; +} + +void SecCamera::setExifFixedAttribute() +{ + char property[PROPERTY_VALUE_MAX]; + + //2 0th IFD TIFF Tags + //3 Maker + property_get("ro.product.brand", property, EXIF_DEF_MAKER); + strncpy((char *)mExifInfo.maker, property, + sizeof(mExifInfo.maker) - 1); + mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0'; + //3 Model + property_get("ro.product.model", property, EXIF_DEF_MODEL); + strncpy((char *)mExifInfo.model, property, + sizeof(mExifInfo.model) - 1); + mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0'; + //3 Software + property_get("ro.build.id", property, EXIF_DEF_SOFTWARE); + strncpy((char *)mExifInfo.software, property, + sizeof(mExifInfo.software) - 1); + mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0'; + + //3 YCbCr Positioning + mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING; + + //2 0th IFD Exif Private Tags + //3 F Number + mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM; + mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN; + //3 Exposure Program + mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM; + //3 Exif Version + memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version)); + //3 Aperture + uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); + mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN; + mExifInfo.aperture.den = EXIF_DEF_APEX_DEN; + //3 Maximum lens aperture + mExifInfo.max_aperture.num = mExifInfo.aperture.num; + mExifInfo.max_aperture.den = mExifInfo.aperture.den; + //3 Lens Focal Length + if (m_camera_id == CAMERA_ID_BACK) + mExifInfo.focal_length.num = BACK_CAMERA_FOCAL_LENGTH; + else + mExifInfo.focal_length.num = FRONT_CAMERA_FOCAL_LENGTH; + + mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; + //3 User Comments + strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS); + //3 Color Space information + mExifInfo.color_space = EXIF_DEF_COLOR_SPACE; + //3 Exposure Mode + mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE; + + //2 0th IFD GPS Info Tags + unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 }; + memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version)); + + //2 1th IFD TIFF Tags + mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION; + mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT; +} + +void SecCamera::setExifChangedAttribute() +{ + //2 0th IFD TIFF Tags + //3 Width + mExifInfo.width = m_snapshot_width; + //3 Height + mExifInfo.height = m_snapshot_height; + //3 Orientation + switch (m_exif_orientation) { + case 90: + mExifInfo.orientation = EXIF_ORIENTATION_90; + break; + case 180: + mExifInfo.orientation = EXIF_ORIENTATION_180; + break; + case 270: + mExifInfo.orientation = EXIF_ORIENTATION_270; + break; + case 0: + default: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + } + //3 Date time + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo); + + //2 0th IFD Exif Private Tags + //3 Exposure Time + int shutterSpeed = 100; + if (m_camera_use_ISP) { + shutterSpeed = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_EXIF_SHUTTERSPEED); + if (shutterSpeed <= 0) { + LOGE("%s: error %d getting shutterSpeed, camera_id = %d, using 100", + __func__, shutterSpeed, m_camera_id); + shutterSpeed = 100; + } + } else { + shutterSpeed = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_TV); + if (shutterSpeed <= 0) { + LOGE("%s: error %d getting shutterSpeed, camera_id = %d, using 100", + __func__, shutterSpeed, m_camera_id); + shutterSpeed = 100; + } + } + + /* TODO : external isp is not shuppoting exptime now. */ + int exptime = 100; + if (m_camera_use_ISP) { + exptime = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_EXPTIME); + if (exptime <= 0) { + LOGE("%s: error %d getting exposure time, camera_id = %d, using 100", + __func__, exptime, m_camera_id); + exptime = 100; + } + } + mExifInfo.exposure_time.num = 1; + mExifInfo.exposure_time.den = (uint32_t)exptime; + + /* TODO : Normaly exposure time and shutter speed is same. But we need to */ + /* calculate exactly value. */ + shutterSpeed = exptime; + + //3 ISO Speed Rating + int iso; + if (m_camera_use_ISP) + iso = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_IS_CAMERA_EXIF_ISO); + else + iso = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_ISO); + if (iso < 0) { + LOGE("%s: error %d getting iso, camera_id = %d, using 100", + __func__, iso, m_camera_id); + iso = 0; + } + mExifInfo.iso_speed_rating = iso; + + uint32_t av, tv, bv, sv, ev; + if (m_camera_use_ISP) { + av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num / mExifInfo.fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double)mExifInfo.exposure_time.num / mExifInfo.exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(mExifInfo.iso_speed_rating); + bv = av + tv - sv; + ev = m_params->exposure - IS_EXPOSURE_DEFAULT; + } else { + av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num / mExifInfo.fnumber.den); + tv = shutterSpeed; + sv = APEX_ISO_TO_FILMSENSITIVITY(mExifInfo.iso_speed_rating); + bv = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_BV); + ev = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_EBV); + } + LOGD("Shutter speed=1/%d s, iso=%d", shutterSpeed, mExifInfo.iso_speed_rating); + LOGD("AV=%d, TV=%d, SV=%d, BV=%d, EV=%d", av, tv, sv, bv, ev); + + //3 Shutter Speed + mExifInfo.shutter_speed.num = 1; + mExifInfo.shutter_speed.den = shutterSpeed; + //3 Brightness + mExifInfo.brightness.num = bv*EXIF_DEF_APEX_DEN; + mExifInfo.brightness.den = EXIF_DEF_APEX_DEN; + //3 Exposure Bias + if (m_params->scene_mode == SCENE_MODE_BEACH_SNOW) { + mExifInfo.exposure_bias.num = EXIF_DEF_APEX_DEN; + mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN; + } else { + mExifInfo.exposure_bias.num = ev*EXIF_DEF_APEX_DEN; + mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN; + } + //3 Metering Mode + switch (m_params->metering) { + case METERING_SPOT: + mExifInfo.metering_mode = EXIF_METERING_SPOT; + break; + case METERING_MATRIX: + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + case METERING_CENTER: + mExifInfo.metering_mode = EXIF_METERING_CENTER; + break; + default : + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + } + + //3 Flash + int flash = m_params->flash_mode; + //int flash = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_GET_FLASH_ONOFF); + if (flash < 0) + mExifInfo.flash = EXIF_DEF_FLASH; + else + mExifInfo.flash = flash; + + //3 White Balance + if (m_params->white_balance == WHITE_BALANCE_AUTO || m_params->white_balance == IS_AWB_AUTO) + mExifInfo.white_balance = EXIF_WB_AUTO; + else + mExifInfo.white_balance = EXIF_WB_MANUAL; + //3 Scene Capture Type + switch (m_params->scene_mode) { + case SCENE_MODE_PORTRAIT: + mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT; + break; + case SCENE_MODE_LANDSCAPE: + mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE; + break; + case SCENE_MODE_NIGHTSHOT: + mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT; + break; + default: + mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD; + break; + } + + //2 0th IFD GPS Info Tags + if (m_gps_latitude != 0 && m_gps_longitude != 0) { + if (m_gps_latitude > 0) + strcpy((char *)mExifInfo.gps_latitude_ref, "N"); + else + strcpy((char *)mExifInfo.gps_latitude_ref, "S"); + + if (m_gps_longitude > 0) + strcpy((char *)mExifInfo.gps_longitude_ref, "E"); + else + strcpy((char *)mExifInfo.gps_longitude_ref, "W"); + + if (m_gps_altitude > 0) + mExifInfo.gps_altitude_ref = 0; + else + mExifInfo.gps_altitude_ref = 1; + + double latitude = fabs(m_gps_latitude / 10000.0); + double longitude = fabs(m_gps_longitude / 10000.0); + double altitude = fabs(m_gps_altitude / 100.0); + + mExifInfo.gps_latitude[0].num = (uint32_t)latitude; + mExifInfo.gps_latitude[0].den = 1; + mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60); + mExifInfo.gps_latitude[1].den = 1; + mExifInfo.gps_latitude[2].num = (uint32_t)((((latitude - mExifInfo.gps_latitude[0].num) * 60) + - mExifInfo.gps_latitude[1].num) * 60); + mExifInfo.gps_latitude[2].den = 1; + + mExifInfo.gps_longitude[0].num = (uint32_t)longitude; + mExifInfo.gps_longitude[0].den = 1; + mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60); + mExifInfo.gps_longitude[1].den = 1; + mExifInfo.gps_longitude[2].num = (uint32_t)((((longitude - mExifInfo.gps_longitude[0].num) * 60) + - mExifInfo.gps_longitude[1].num) * 60); + mExifInfo.gps_longitude[2].den = 1; + + mExifInfo.gps_altitude.num = (uint32_t)altitude; + mExifInfo.gps_altitude.den = 1; + + struct tm tm_data; + gmtime_r(&m_gps_timestamp, &tm_data); + mExifInfo.gps_timestamp[0].num = tm_data.tm_hour; + mExifInfo.gps_timestamp[0].den = 1; + mExifInfo.gps_timestamp[1].num = tm_data.tm_min; + mExifInfo.gps_timestamp[1].den = 1; + mExifInfo.gps_timestamp[2].num = tm_data.tm_sec; + mExifInfo.gps_timestamp[2].den = 1; + snprintf((char*)mExifInfo.gps_datestamp, sizeof(mExifInfo.gps_datestamp), + "%04d:%02d:%02d", tm_data.tm_year + 1900, tm_data.tm_mon + 1, tm_data.tm_mday); + + mExifInfo.enableGps = true; + } else { + mExifInfo.enableGps = false; + } + + //2 1th IFD TIFF Tags + mExifInfo.widthThumb = m_jpeg_thumbnail_width; + mExifInfo.heightThumb = m_jpeg_thumbnail_height; +} + +int SecCamera::makeExif (unsigned char *exifOut, + unsigned char *thumb_buf, + unsigned int thumb_size, + exif_attribute_t *exifInfo, + unsigned int *size, + bool useMainbufForThumb) +{ + unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset; + unsigned int tmp, LongerTagOffest = 0; + pApp1Start = pCur = exifOut; + + //2 Exif Identifier Code & TIFF Header + pCur += 4; // Skip 4 Byte for APP1 marker and length + unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + memcpy(pCur, ExifIdentifierCode, 6); + pCur += 6; + + /* Byte Order - little endian, Offset of IFD - 0x00000008.H */ + unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 }; + memcpy(pCur, TiffHeader, 8); + pIfdStart = pCur; + pCur += 8; + + //2 0th IFD TIFF Tags + if (exifInfo->enableGps) + tmp = NUM_0TH_IFD_TIFF; + else + tmp = NUM_0TH_IFD_TIFF - 1; + + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT, + 1, exifInfo->ycbcr_positioning); + writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); + if (exifInfo->enableGps) { + pGpsIfdPtr = pCur; + pCur += IFD_SIZE; // Skip a ifd size for gps IFD pointer + } + + pNextIfdOffset = pCur; // Skip a offset size for next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD Exif Private Tags + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_0TH_IFD_EXIF; + memcpy(pCur, &tmp , NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL, + 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL, + 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT, + 1, exifInfo->exposure_program); + writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT, + 1, exifInfo->iso_speed_rating); + writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED, + 4, exifInfo->exif_version); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT, + 1, exifInfo->metering_mode); + writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT, + 1, exifInfo->flash); + writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL, + 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart); + char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 }; + int commentsLen = strlen((char *)exifInfo->user_comment) + 1; + memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen); + memcpy(exifInfo->user_comment, code, sizeof(code)); + writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED, + commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT, + 1, exifInfo->color_space); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG, + 1, exifInfo->exposure_mode); + writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG, + 1, exifInfo->white_balance); + writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG, + 1, exifInfo->scene_capture_type); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD GPS Info Tags + if (exifInfo->enableGps) { + writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + if (exifInfo->gps_processing_method[0] == 0) { + // don't create GPS_PROCESSING_METHOD tag if there isn't any + tmp = NUM_0TH_IFD_GPS - 1; + } else { + tmp = NUM_0TH_IFD_GPS; + } + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE, + 4, exifInfo->gps_version_id); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_latitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_longitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE, + 1, exifInfo->gps_altitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart); + tmp = strlen((char*)exifInfo->gps_processing_method); + if (tmp > 0) { + if (tmp > 100) { + tmp = 100; + } + static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; + unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)]; + memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix)); + memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp); + writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED, + tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart); + } + writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII, + 11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + } + + //2 1th IFD TIFF Tags + + unsigned char *thumbBuf = thumb_buf; + unsigned int thumbSize = thumb_size; + + if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize > 0)) { + tmp = LongerTagOffest; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_1TH_IFD_TIFF; + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->widthThumb); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->heightThumb); + writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT, + 1, exifInfo->compression_scheme); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT, + 1, exifInfo->resolution_unit); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG, + 1, LongerTagOffest); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG, + 1, thumbSize); + + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + memcpy(pIfdStart + LongerTagOffest, thumbBuf, thumbSize); + LongerTagOffest += thumbSize; + } else { + tmp = 0; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + } + + unsigned char App1Marker[2] = { 0xff, 0xe1 }; + memcpy(pApp1Start, App1Marker, 2); + pApp1Start += 2; + + *size = 10 + LongerTagOffest; + tmp = *size - 2; // APP1 Maker isn't counted + unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF}; + memcpy(pApp1Start, size_mm, 2); + + LOGD("makeExif X"); + + return 0; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + uint32_t value) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, &value, 4); + *pCur += 4; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue) +{ + char buf[4] = { 0,}; + + memcpy(buf, pValue, count); + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, buf, 4); + *pCur += 4; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, count); + *offset += count; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, 8 * count); + *offset += 8 * count; +} + +status_t SecCamera::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + snprintf(buffer, 255, "dump(%d)\n", fd); + result.append(buffer); + ::write(fd, result.string(), result.size()); + return NO_ERROR; +} + +double SecCamera::jpeg_ratio = 0.7; +int SecCamera::interleaveDataSize = 5242880; +int SecCamera::jpegLineLength = 636; + +}; // namespace android diff --git a/exynos4/hal/libcamera/SecCamera.h b/exynos4/hal/libcamera/SecCamera.h new file mode 100644 index 0000000..fc30fc4 --- /dev/null +++ b/exynos4/hal/libcamera/SecCamera.h @@ -0,0 +1,695 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_SEC_H +#define ANDROID_HARDWARE_CAMERA_SEC_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "sec_utils_v4l2.h" + +#include "SecBuffer.h" + +#include + +#ifdef SAMSUNG_EXYNOS4210 +#include "jpeg_api.h" +#endif + +#ifdef SAMSUNG_EXYNOS4x12 +#include "jpeg_hal.h" +#endif + +#include "Exif.h" +namespace android { + +//#define ENABLE_ESD_PREVIEW_CHECK +//#define ZERO_SHUTTER_LAG +#define VIDEO_SNAPSHOT + +#if defined VIDEO_SNAPSHOT +#define ZERO_SHUTTER_LAG +#endif + +#define USE_FACE_DETECTION +//#define USE_TOUCH_AF + +#if defined(LOG_NDEBUG) && (LOG_NDEBUG == 0) +#define LOG_CAMERA LOGD +#define LOG_CAMERA_PREVIEW LOGD + +#define LOG_TIME_DEFINE(n) \ + struct timeval time_start_##n, time_stop_##n; unsigned long log_time_##n = 0; + +#define LOG_TIME_START(n) \ + gettimeofday(&time_start_##n, NULL); + +#define LOG_TIME_END(n) \ + gettimeofday(&time_stop_##n, NULL); log_time_##n = measure_time_camera(&time_start_##n, &time_stop_##n); + +#define LOG_TIME(n) \ + log_time_##n + +#else +#define LOG_CAMERA(...) +#define LOG_CAMERA_PREVIEW(...) +#define LOG_TIME_DEFINE(n) +#define LOG_TIME_START(n) +#define LOG_TIME_END(n) +#define LOG_TIME(n) +#endif + +#define FRM_RATIO(w, h) ((w)*10/(h)) +#define SIZE_4K (1 << 12) + +#define JOIN(x, y) JOIN_AGAIN(x, y) +#define JOIN_AGAIN(x, y) x ## y + +#define FRONT_CAM S5K6A3 +#define BACK_CAM M5MO + +#if !defined (FRONT_CAM) || !defined(BACK_CAM) +#error "Please define the Camera module" +#endif + +#define M5MO_PREVIEW_WIDTH 640 +#define M5MO_PREVIEW_HEIGHT 480 +#define M5MO_SNAPSHOT_WIDTH 3264 +#define M5MO_SNAPSHOT_HEIGHT 2448 + +#define M5MO_THUMBNAIL_WIDTH 320 +#define M5MO_THUMBNAIL_HEIGHT 240 +#define M5MO_THUMBNAIL_BPP 16 + +#define M5MO_FPS 30 + +/* focal length of 3.43mm */ +#define M5MO_FOCAL_LENGTH 343 + +#define S5K6A3_PREVIEW_WIDTH 480 +#define S5K6A3_PREVIEW_HEIGHT 480 +#define S5K6A3_SNAPSHOT_WIDTH 1392 +#define S5K6A3_SNAPSHOT_HEIGHT 1392 + +#define S5K6A3_THUMBNAIL_WIDTH 160 +#define S5K6A3_THUMBNAIL_HEIGHT 120 +#define S5K6A3_THUMBNAIL_BPP 16 + +#define S5K6A3_FPS 30 + +/* focal length of 0.9mm */ +#define S5K6A3_FOCAL_LENGTH 90 + +#define MAX_BACK_CAMERA_PREVIEW_WIDTH JOIN(BACK_CAM,_PREVIEW_WIDTH) +#define MAX_BACK_CAMERA_PREVIEW_HEIGHT JOIN(BACK_CAM,_PREVIEW_HEIGHT) +#define MAX_BACK_CAMERA_SNAPSHOT_WIDTH JOIN(BACK_CAM,_SNAPSHOT_WIDTH) +#define MAX_BACK_CAMERA_SNAPSHOT_HEIGHT JOIN(BACK_CAM,_SNAPSHOT_HEIGHT) + +#define BACK_CAMERA_THUMBNAIL_WIDTH JOIN(BACK_CAM,_THUMBNAIL_WIDTH) +#define BACK_CAMERA_THUMBNAIL_HEIGHT JOIN(BACK_CAM,_THUMBNAIL_HEIGHT) +#define BACK_CAMERA_THUMBNAIL_BPP JOIN(BACK_CAM,_THUMBNAIL_BPP) + +#define BACK_CAMERA_FPS JOIN(BACK_CAM,_FPS) + +#define BACK_CAMERA_FOCAL_LENGTH JOIN(BACK_CAM,_FOCAL_LENGTH) + +#define MAX_FRONT_CAMERA_PREVIEW_WIDTH JOIN(FRONT_CAM,_PREVIEW_WIDTH) +#define MAX_FRONT_CAMERA_PREVIEW_HEIGHT JOIN(FRONT_CAM,_PREVIEW_HEIGHT) +#define MAX_FRONT_CAMERA_SNAPSHOT_WIDTH JOIN(FRONT_CAM,_SNAPSHOT_WIDTH) +#define MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT JOIN(FRONT_CAM,_SNAPSHOT_HEIGHT) + +#define FRONT_CAMERA_THUMBNAIL_WIDTH JOIN(FRONT_CAM,_THUMBNAIL_WIDTH) +#define FRONT_CAMERA_THUMBNAIL_HEIGHT JOIN(FRONT_CAM,_THUMBNAIL_HEIGHT) +#define FRONT_CAMERA_THUMBNAIL_BPP JOIN(FRONT_CAM,_THUMBNAIL_BPP) + +#define FRONT_CAMERA_FPS JOIN(FRONT_CAM,_FPS) + +#define FRONT_CAMERA_FOCAL_LENGTH JOIN(FRONT_CAM,_FOCAL_LENGTH) + +#define DEFAULT_JPEG_THUMBNAIL_WIDTH 256 +#define DEFAULT_JPEG_THUMBNAIL_HEIGHT 192 + +#ifdef BOARD_USE_V4L2 +#define CAMERA_DEV_NAME "/dev/video1" +#else +#define CAMERA_DEV_NAME "/dev/video0" +#endif + +#ifdef SAMSUNG_EXYNOS4210 +#define CAMERA_DEV_NAME3 "/dev/video2" +#endif + +#ifdef SAMSUNG_EXYNOS4x12 +#ifdef BOARD_USE_V4L2 +#define CAMERA_DEV_NAME3 "/dev/video3" +#else +#define CAMERA_DEV_NAME3 "/dev/video1" +#endif +#ifdef ZERO_SHUTTER_LAG +#define CAMERA_DEV_NAME2 "/dev/video2" +#endif +#endif + +#define CAMERA_DEV_NAME_TEMP "/data/videotmp_000" +#define CAMERA_DEV_NAME2_TEMP "/data/videotemp_002" + + +#define BPP 2 +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX_BUFFERS 8 + +#ifdef ZERO_SHUTTER_LAG +#define CAP_BUFFERS 8 +#else +#define CAP_BUFFERS 1 +#endif + +#ifdef BOARD_USE_V4L2 +#define MAX_PLANES (3) +#define V4L2_BUF_TYPE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE +#else +#define MAX_PLANES (1) +#define V4L2_BUF_TYPE V4L2_BUF_TYPE_VIDEO_CAPTURE +#endif + +#ifdef BOARD_USE_V4L2_ION +#define V4L2_MEMORY_TYPE V4L2_MEMORY_USERPTR +#define RECORD_PIX_FMT V4L2_PIX_FMT_NV12M +#define PREVIEW_NUM_PLANE (3) +#define RECORD_NUM_PLANE (2) +#else +#define V4L2_MEMORY_TYPE V4L2_MEMORY_MMAP +#define RECORD_PIX_FMT V4L2_PIX_FMT_NV12 +#define PREVIEW_NUM_PLANE (1) +#define RECORD_NUM_PLANE (1) +#endif + +/* + * V 4 L 2 F I M C E X T E N S I O N S + * + */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) + +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) + +#define TPATTERN_COLORBAR 1 +#define TPATTERN_HORIZONTAL 2 +#define TPATTERN_VERTICAL 3 + +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + +/* FOURCC for FIMC specific */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') +/* + * U S E R D E F I N E D T Y P E S + * + */ +#define PREVIEW_MODE 1 +#define CAPTURE_MODE 2 +#define RECORD_MODE 3 + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int depth; + int planes; +}; + +struct camsensor_date_info { + unsigned int year; + unsigned int month; + unsigned int date; +}; + +class SecCamera : public virtual RefBase { +public: + + enum CAMERA_ID { + CAMERA_ID_BACK = 0, + CAMERA_ID_FRONT = 1, + }; + + enum JPEG_QUALITY { + JPEG_QUALITY_ECONOMY = 0, + JPEG_QUALITY_NORMAL = 50, + JPEG_QUALITY_SUPERFINE = 100, + JPEG_QUALITY_MAX, + }; + + enum OBJECT_TRACKING { + OBJECT_TRACKING_OFF, + OBJECT_TRACKING_ON, + OBJECT_TRACKING_MAX, + }; + + /*VT call*/ + enum VT_MODE { + VT_MODE_OFF, + VT_MODE_ON, + VT_MODE_MAX, + }; + + /*Camera sensor mode - Camcorder fix fps*/ + enum SENSOR_MODE { + SENSOR_MODE_CAMERA, + SENSOR_MODE_MOVIE, + }; + + /*Camera Shot mode*/ + enum SHOT_MODE { + SHOT_MODE_SINGLE = 0, + SHOT_MODE_CONTINUOUS = 1, + SHOT_MODE_PANORAMA = 2, + SHOT_MODE_SMILE = 3, + SHOT_MODE_SELF = 6, + }; + + enum CHK_DATALINE { + CHK_DATALINE_OFF, + CHK_DATALINE_ON, + CHK_DATALINE_MAX, + }; + + enum CAM_MODE { + PREVIEW = 0, + PICTURE = 1, + RECORDING = 2, + }; + + int m_touch_af_start_stop; + + SecCamera(); + virtual ~SecCamera(); + + static SecCamera* createInstance(void) + { + static SecCamera singleton; + return &singleton; + } + status_t dump(int fd); + + bool CreateCamera(int index); + bool DestroyCamera(void); + int getCameraId(void); + void initParameters(int index); + int setMode(int recording_en); + + int startPreview(void); + int stopPreview(void); + int getPreviewState(void) + { + return m_preview_state; + } + void clearPreviewState(void) + { + m_preview_state = 0; + } + + int startSnapshot(SecBuffer *yuv_buf); + int stopSnapshot(void); + int getSnapshot(void); + int setSnapshotFrame(int index); + + int startRecord(bool recordHint); + int stopRecord(void); + int setPreviewFrame(int index); + int getRecordFrame(void); + int releaseRecordFrame(int index); + int getRecordAddr(int index, SecBuffer *buffer); + + int getPreview(camera_frame_metadata_t *facedata); + int setPreviewSize(int width, int height, int pixel_format); + int getPreviewSize(int *width, int *height, int *frame_size); + int getPreviewMaxSize(int *width, int *height); + int getPreviewPixelFormat(void); + int setPreviewImage(int index, unsigned char *buffer, int size); + + int setVideosnapshotSize(int width, int height); + int getVideosnapshotSize(int *width, int *height, int *frame_size); + int setSnapshotSize(int width, int height); + int getSnapshotSize(int *width, int *height, int *frame_size); + int getSnapshotMaxSize(int *width, int *height); + int setSnapshotPixelFormat(int pixel_format); + int getSnapshotPixelFormat(void); + + unsigned char* getJpeg(unsigned char *snapshot_data, int snapshot_size, int *size); + unsigned char* yuv2Jpeg(unsigned char *raw_data, int raw_size, + int *jpeg_size, + int width, int height, int pixel_format); + + int setJpegThumbnailSize(int width, int height); + int getJpegThumbnailSize(int *width, int *height); + + int setJpegThumbnailQuality(int jpeg_thumbnail_quality); + int getJpegThumbnailQuality(void); + + int initSetParams(void); + + int setAutofocus(void); + int setTouchAF(void); + + int SetRotate(int angle); + int getRotate(void); + + int setVerticalMirror(void); + int setHorizontalMirror(void); + + int setWhiteBalance(int white_balance); + int getWhiteBalance(void); + + int setBrightness(int brightness); + int getBrightness(void); + + int setExposure(int exposure); + int getExposure(void); + + int setImageEffect(int image_effect); + int getImageEffect(void); + + int setSceneMode(int scene_mode); + int getSceneMode(void); + + int setFlashMode(int flash_mode); + int getFlashMode(void); + + int setMetering(int metering_value); + int getMetering(void); + + int setAutoExposureLock(int toggle); + int setAutoWhiteBalanceLock(int toggle); + + int setISO(int iso_value); + int getISO(void); + + int setContrast(int contrast_value); + int getContrast(void); + + int setSaturation(int saturation_value); + int getSaturation(void); + + int setSharpness(int sharpness_value); + int getSharpness(void); + + int setHue(int hue_value); + int getHue(void); + + int setWDR(int wdr_value); + int getWDR(void); + + int setAntiShake(int anti_shake); + int getAntiShake(void); + + int setJpegQuality(int jpeg_qality); + int getJpegQuality(void); + + int setZoom(int zoom_level); + int getZoom(void); + + int setObjectTracking(int object_tracking); + int getObjectTracking(void); + int getObjectTrackingStatus(void); + + int setSmartAuto(int smart_auto); + int getSmartAuto(void); + int getAutosceneStatus(void); + + int setBeautyShot(int beauty_shot); + int getBeautyShot(void); + + int setVintageMode(int vintage_mode); + int getVintageMode(void); + + int setFocusMode(int focus_mode); + int getFocusMode(void); + + int setFaceDetect(int face_detect); + int getFaceDetect(void); + + int setGPSLatitude(const char *gps_latitude); + int setGPSLongitude(const char *gps_longitude); + int setGPSAltitude(const char *gps_altitude); + int setGPSTimeStamp(const char *gps_timestamp); + int setGPSProcessingMethod(const char *gps_timestamp); + int cancelAutofocus(void); + int setFaceDetectLockUnlock(int facedetect_lockunlock); + int setObjectPosition(int x, int y); + int setObjectTrackingStartStop(int start_stop); + int setTouchAFStartStop(int start_stop); + int setCAFStatus(int on_off); + int getAutoFocusResult(void); + int setAntiBanding(int anti_banding); + int getPostview(void); + int setRecordingSize(int width, int height); + int getRecordingSize(int *width, int *height); + int setGamma(int gamma); + int setSlowAE(int slow_ae); + int setExifOrientationInfo(int orientationInfo); + int setBatchReflection(void); + int setSnapshotCmd(void); + int endSnapshot(void); + int setCameraSensorReset(void); + int setSensorMode(int sensor_mode); /* Camcorder fix fps */ + int setShotMode(int shot_mode); /* Shot mode */ + int setDataLineCheck(int chk_dataline); + int getDataLineCheck(void); + int setDataLineCheckStop(void); + int setDefultIMEI(int imei); + int getDefultIMEI(void); + const __u8* getCameraSensorName(void); + bool getUseInternalISP(void); +#ifdef ENABLE_ESD_PREVIEW_CHECK + int getCameraSensorESDStatus(void); +#endif // ENABLE_ESD_PREVIEW_CHECK + + int setFrameRate(int frame_rate); + unsigned char* getJpeg(int *jpeg_size, + int *thumb_size, + unsigned int *thumb_addr, + unsigned int *phyaddr); + int getSnapshotAndJpeg(SecBuffer *yuv_buf, + int index, + unsigned char *jpeg_buf, + int *output_size); + int getExif(unsigned char *pExifDst, unsigned char *pThumbSrc, int thumbSize); + + void getPostViewConfig(int*, int*, int*); + void getThumbnailConfig(int *width, int *height, int *size); + + int getPostViewOffset(void); + int getCameraFd(enum CAM_MODE); + int getJpegFd(void); + void SetJpgAddr(unsigned char *addr); + int getPreviewAddr(int index, SecBuffer *buffer); + int getCaptureAddr(int index, SecBuffer *buffer); +#ifdef BOARD_USE_V4L2_ION + void setUserBufferAddr(void *ptr, int index, int mode); +#endif + static void setJpegRatio(double ratio) + { + if((ratio < 0) || (ratio > 1)) + return; + + jpeg_ratio = ratio; + } + + static double getJpegRatio() + { + return jpeg_ratio; + } + + static void setInterleaveDataSize(int x) + { + interleaveDataSize = x; + } + + static int getInterleaveDataSize() + { + return interleaveDataSize; + } + + static void setJpegLineLength(int x) + { + jpegLineLength = x; + } + + static int getJpegLineLength() + { + return jpegLineLength; + } + +private: + v4l2_streamparm m_streamparm; + struct sec_cam_parm *m_params; + int m_flagCreate; + int m_preview_state; + int m_snapshot_state; + int m_camera_id; + bool m_camera_use_ISP; + + int m_cam_fd; + struct pollfd m_events_c; + + int m_cam_fd2; + int m_cap_fd; + struct pollfd m_events_c2; + + int m_cam_fd3; + int m_rec_fd; + struct pollfd m_events_c3; + int m_flag_record_start; + + int m_preview_v4lformat; + int m_preview_width; + int m_preview_height; + int m_preview_max_width; + int m_preview_max_height; + + int m_snapshot_v4lformat; + int m_snapshot_width; + int m_snapshot_height; + int m_snapshot_max_width; + int m_snapshot_max_height; + + int m_num_capbuf; + int m_videosnapshot_width; + int m_videosnapshot_height; + + int m_angle; + int m_anti_banding; + int m_wdr; + int m_anti_shake; + int m_zoom_level; + int m_object_tracking; + int m_smart_auto; + int m_beauty_shot; + int m_vintage_mode; + int m_face_detect; + int m_object_tracking_start_stop; + int m_recording_en; + bool m_record_hint; + int m_recording_width; + int m_recording_height; + long m_gps_latitude; + long m_gps_longitude; + long m_gps_altitude; + long m_gps_timestamp; + int m_sensor_mode; /*Camcorder fix fps */ + int m_shot_mode; /* Shot mode */ + int m_exif_orientation; + int m_chk_dataline; + int m_video_gamma; + int m_slow_ae; + int m_camera_af_flag; + int m_auto_focus_state; + + int m_flag_camera_create; + int m_flag_camera_start; + + int m_jpeg_fd; + int m_jpeg_thumbnail_width; + int m_jpeg_thumbnail_height; + int m_jpeg_thumbnail_quality; + int m_jpeg_quality; + + int m_postview_offset; + +#ifdef ENABLE_ESD_PREVIEW_CHECK + int m_esd_check_count; +#endif // ENABLE_ESD_PREVIEW_CHECK + + exif_attribute_t mExifInfo; + + struct SecBuffer m_capture_buf[CAP_BUFFERS]; + struct SecBuffer m_buffers_preview[MAX_BUFFERS]; + struct SecBuffer m_buffers_record[MAX_BUFFERS]; + + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + uint32_t value); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start); + + void setExifChangedAttribute(); + void setExifFixedAttribute(); + int makeExif (unsigned char *exifOut, + unsigned char *thumb_buf, + unsigned int thumb_size, + exif_attribute_t *exifInfo, + unsigned int *size, + bool useMainbufForThumb); + void resetCamera(); + + static double jpeg_ratio; + static int interleaveDataSize; + static int jpegLineLength; +}; + +extern unsigned long measure_time_camera(struct timeval *start, struct timeval *stop); + +}; // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_SEC_H diff --git a/exynos4/hal/libcamera/SecCameraHWInterface.cpp b/exynos4/hal/libcamera/SecCameraHWInterface.cpp new file mode 100644 index 0000000..c50ec8d --- /dev/null +++ b/exynos4/hal/libcamera/SecCameraHWInterface.cpp @@ -0,0 +1,3410 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +//#define LOG_NDEBUG 0 +#define LOG_TAG "CameraHardwareSec" +#include + +#include "SecCameraHWInterface.h" +#include +#include +#include +#include +#include + +#define VIDEO_COMMENT_MARKER_H 0xFFBE +#define VIDEO_COMMENT_MARKER_L 0xFFBF +#define VIDEO_COMMENT_MARKER_LENGTH 4 +#define JPEG_EOI_MARKER 0xFFD9 +#define HIBYTE(x) (((x) >> 8) & 0xFF) +#define LOBYTE(x) ((x) & 0xFF) + +#define BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR "0.10,1.20,Infinity" +#define BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR "0.10,0.20,Infinity" +#define BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR "0.10,1.20,Infinity" +#define FRONT_CAMERA_FOCUS_DISTANCES_STR "0.20,0.25,Infinity" +#define USE_EGL + +// This hack does two things: +// -- it sets preview to NV21 (YUV420SP) +// -- it sets gralloc to YV12 +// +// The reason being: the samsung encoder understands only yuv420sp, and gralloc +// does yv12 and rgb565. So what we do is we break up the interleaved UV in +// separate V and U planes, which makes preview look good, and enabled the +// encoder as well. +// +// FIXME: Samsung needs to enable support for proper yv12 coming out of the +// camera, and to fix their video encoder to work with yv12. +// FIXME: It also seems like either Samsung's YUV420SP (NV21) or img's YV12 has +// the color planes switched. We need to figure which side is doing it +// wrong and have the respective party fix it. + +namespace android { + +struct addrs { + uint32_t type; // make sure that this is 4 byte. + unsigned int addr_y; + unsigned int addr_cbcr; + unsigned int buf_index; + unsigned int reserved; +}; + +struct addrs_cap { + unsigned int addr_y; + unsigned int width; + unsigned int height; +}; + +static const int INITIAL_SKIP_FRAME = 3; +static const int EFFECT_SKIP_FRAME = 1; + +gralloc_module_t const* CameraHardwareSec::mGrallocHal; + +CameraHardwareSec::CameraHardwareSec(int cameraId, camera_device_t *dev) + : + mCaptureInProgress(false), + mParameters(), + mFrameSizeDelta(0), + mCameraSensorName(NULL), + mUseInternalISP(false), + mSkipFrame(0), + mNotifyCb(0), + mDataCb(0), + mDataCbTimestamp(0), + mCallbackCookie(0), + mMsgEnabled(CAMERA_MSG_RAW_IMAGE), + mRecordRunning(false), + mPostViewWidth(0), + mPostViewHeight(0), + mPostViewSize(0), + mCapIndex(0), + mRecordHint(false), + mTouched(0), + mHalDevice(dev) +{ + LOGV("%s :", __func__); + memset(&mCapBuffer, 0, sizeof(struct SecBuffer)); + int ret = 0; + + mPreviewWindow = NULL; + mSecCamera = SecCamera::createInstance(); + + mRawHeap = NULL; + mPreviewHeap = NULL; + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) + mRecordHeap[i] = NULL; + + if (!mGrallocHal) { + ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal); + if (ret) + LOGE("ERR(%s):Fail on loading gralloc HAL", __func__); + } + + ret = mSecCamera->CreateCamera(cameraId); + if (ret < 0) { + LOGE("ERR(%s):Fail on mSecCamera init", __func__); + mSecCamera->DestroyCamera(); + } + + initDefaultParameters(cameraId); + + mExitAutoFocusThread = false; + mExitPreviewThread = false; + /* whether the PreviewThread is active in preview or stopped. we + * create the thread but it is initially in stopped state. + */ + mPreviewRunning = false; + mPreviewStartDeferred = false; + mPreviewThread = new PreviewThread(this); + mAutoFocusThread = new AutoFocusThread(this); + mPictureThread = new PictureThread(this); +} + +int CameraHardwareSec::getCameraId() const +{ + return mSecCamera->getCameraId(); +} + +void CameraHardwareSec::initDefaultParameters(int cameraId) +{ + if (mSecCamera == NULL) { + LOGE("ERR(%s):mSecCamera object is NULL", __func__); + return; + } + + CameraParameters p; + CameraParameters ip; + + mCameraSensorName = mSecCamera->getCameraSensorName(); + if (mCameraSensorName == NULL) { + LOGE("ERR(%s):mCameraSensorName is NULL", __func__); + return; + } + LOGV("CameraSensorName: %s", mCameraSensorName); + + int preview_max_width = 0; + int preview_max_height = 0; + int snapshot_max_width = 0; + int snapshot_max_height = 0; + + mCameraID = cameraId; + mUseInternalISP = mSecCamera->getUseInternalISP(); + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + if (mUseInternalISP) { + //3H2 + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + "720x480,640x384,640x360,640x480,320x240,528x432,176x144"); + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + "3248x2436,3216x2144,3200x1920,3072x1728,2592x1944,1920x1080,1440x1080,1280x720,1232x1008,800x480,720x480,640x480"); + p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, + "1920x1080,1280x720,640x480,176x144"); + } else { + //M5MO + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + "3264x2448,1920x1080,1280x720,800x480,720x480,640x480,320x240,528x432,176x144"); + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + "3264x2448,3264x1968,2048x1536,2048x1232,800x480,640x480"); + } + } else { + if (mUseInternalISP) { + //6A3 + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + "640x480,640x360,480x480,352x288,320x240,176x144"); + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + "1392x1392,1280x960,1280x720,880x720,640x480"); + p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, + "1280x720,640x480,176x144"); + } + } + + p.getSupportedPreviewSizes(mSupportedPreviewSizes); + + String8 parameterString; + + // If these fail, then we are using an invalid cameraId and we'll leave the + // sizes at zero to catch the error. + if (mSecCamera->getPreviewMaxSize(&preview_max_width, + &preview_max_height) < 0) + LOGE("getPreviewMaxSize fail (%d / %d)", + preview_max_width, preview_max_height); + if (mSecCamera->getSnapshotMaxSize(&snapshot_max_width, + &snapshot_max_height) < 0) + LOGE("getSnapshotMaxSize fail (%d / %d)", + snapshot_max_width, snapshot_max_height); + + parameterString = CameraParameters::PIXEL_FORMAT_YUV420P; + parameterString.append(","); + parameterString.append(CameraParameters::PIXEL_FORMAT_YUV420SP); + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, parameterString); + p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420P); + mFrameSizeDelta = 16; + p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420SP); + p.setPreviewSize(preview_max_width, preview_max_height); + + p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG); + p.setPictureSize(snapshot_max_width, snapshot_max_height); + p.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // maximum quality + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, + CameraParameters::PIXEL_FORMAT_JPEG); + + p.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1280x720"); + +#ifdef USE_FACE_DETECTION + if (mUseInternalISP) { + p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "5"); + } else { + p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "0"); + } +#endif + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + parameterString = CameraParameters::FOCUS_MODE_AUTO; + /* TODO : sensor will be support this mode */ + //parameterString.append(","); + //parameterString.append(CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO); + if (mUseInternalISP) { + parameterString.append(","); + parameterString.append(CameraParameters::FOCUS_MODE_INFINITY); + parameterString.append(","); + parameterString.append(CameraParameters::FOCUS_MODE_MACRO); + parameterString.append(","); + parameterString.append(CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE); + } + p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_FOCUS_MODE, + CameraParameters::FOCUS_MODE_AUTO); + p.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR); +#ifdef USE_TOUCH_AF + if (mUseInternalISP) + p.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1"); +#endif + p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, + "320x240,0x0"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240"); + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30"); + p.setPreviewFrameRate(30); + } else { + p.set(CameraParameters::KEY_FOCUS_MODE, NULL); + p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, + "160x120,0x0"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "160"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "120"); + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, + "7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,50,60"); + p.setPreviewFrameRate(30); + } + + parameterString = CameraParameters::EFFECT_NONE; + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_MONO); + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_NEGATIVE); + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_SEPIA); + p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, parameterString.string()); + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + parameterString = CameraParameters::FLASH_MODE_ON; + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_OFF); + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_AUTO); + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_TORCH); + p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_FLASH_MODE, + CameraParameters::FLASH_MODE_OFF); + + /* we have two ranges, 4-30fps for night mode and + * 15-30fps for all others + */ + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)"); + p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000"); + + p.set(CameraParameters::KEY_FOCAL_LENGTH, "3.43"); + } else { + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(7500,30000)"); + p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "7500,30000"); + + p.set(CameraParameters::KEY_FOCAL_LENGTH, "0.9"); + } + parameterString = CameraParameters::SCENE_MODE_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_PORTRAIT); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_LANDSCAPE); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_BEACH); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_SNOW); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_FIREWORKS); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_SPORTS); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_PARTY); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_CANDLELIGHT); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_NIGHT); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_SUNSET); + p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_SCENE_MODE, + CameraParameters::SCENE_MODE_AUTO); + + parameterString = CameraParameters::WHITE_BALANCE_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_INCANDESCENT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_FLUORESCENT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_DAYLIGHT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT); + p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, + parameterString.string()); + + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "100"); + + p.set(CameraParameters::KEY_ROTATION, 0); + p.set(CameraParameters::KEY_WHITE_BALANCE, CameraParameters::WHITE_BALANCE_AUTO); + + p.set(CameraParameters::KEY_EFFECT, CameraParameters::EFFECT_NONE); + + p.set("contrast", 0); + p.set("iso", "auto"); + p.set("metering", "center"); + p.set("wdr", 0); + + ip.set("chk_dataline", 0); + if (cameraId == SecCamera::CAMERA_ID_FRONT) { + ip.set("vtmode", 0); + ip.set("blur", 0); + } + + p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "51.2"); + p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "39.4"); + + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); + p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "4"); + p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-4"); + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "1"); + + p.set("brightness", 0); + p.set("brightness-max", 2); + p.set("brightness-min", -2); + + p.set("saturation", 0); + p.set("saturation-max", 2); + p.set("saturation-min", -2); + + p.set("sharpness", 0); + p.set("sharpness-max", 2); + p.set("sharpness-min", -2); + + p.set("hue", 0); + p.set("hue-max", 2); + p.set("hue-min", -2); + + parameterString = CameraParameters::ANTIBANDING_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_50HZ); + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_60HZ); + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_OFF); + p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, + parameterString.string()); + + p.set(CameraParameters::KEY_ANTIBANDING, CameraParameters::ANTIBANDING_OFF); + + if (mUseInternalISP) { + p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true"); + p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, "false"); + } + + if (mUseInternalISP) { + p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true"); + p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, "false"); + } + + p.set(CameraParameters::KEY_RECORDING_HINT, "false"); + +#ifdef VIDEO_SNAPSHOT + if (mUseInternalISP) + p.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, "true"); +#endif + + if (!mUseInternalISP) { + p.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true"); + p.set(CameraParameters::KEY_MAX_ZOOM, ZOOM_LEVEL_MAX - 1); + p.set(CameraParameters::KEY_ZOOM_RATIOS, "31,4.0"); + } + + mPreviewRunning = false; + mParameters = p; + mInternalParameters = ip; + + /* make sure mSecCamera has all the settings we do. applications + * aren't required to call setParameters themselves (only if they + * want to change something. + */ + setParameters(p); +} + +CameraHardwareSec::~CameraHardwareSec() +{ + LOGV("%s", __func__); + mSecCamera->DestroyCamera(); +} + +status_t CameraHardwareSec::setPreviewWindow(preview_stream_ops *w) +{ + int min_bufs; + + mPreviewWindow = w; + LOGV("%s: mPreviewWindow %p", __func__, mPreviewWindow); + + if (!w) { + LOGE("preview window is NULL!"); + return OK; + } + + mPreviewLock.lock(); + + if (mPreviewRunning && !mPreviewStartDeferred) { + LOGI("stop preview (window change)"); + stopPreviewInternal(); + } + + if (w->get_min_undequeued_buffer_count(w, &min_bufs)) { + LOGE("%s: could not retrieve min undequeued buffer count", __func__); + return INVALID_OPERATION; + } + + if (min_bufs >= BUFFER_COUNT_FOR_GRALLOC) { + LOGE("%s: min undequeued buffer count %d is too high (expecting at most %d)", __func__, + min_bufs, BUFFER_COUNT_FOR_GRALLOC - 1); + } + + LOGV("%s: setting buffer count to %d", __func__, BUFFER_COUNT_FOR_GRALLOC); + if (w->set_buffer_count(w, BUFFER_COUNT_FOR_GRALLOC)) { + LOGE("%s: could not set buffer count", __func__); + return INVALID_OPERATION; + } + + int preview_width; + int preview_height; + mParameters.getPreviewSize(&preview_width, &preview_height); + + int hal_pixel_format; + + const char *str_preview_format = mParameters.getPreviewFormat(); + LOGV("%s: preview format %s", __func__, str_preview_format); + mFrameSizeDelta = 16; + + hal_pixel_format = HAL_PIXEL_FORMAT_YV12; // default + + if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_RGB565)) { + hal_pixel_format = HAL_PIXEL_FORMAT_RGB_565; + mFrameSizeDelta = 0; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_RGBA8888)) { + hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888; + mFrameSizeDelta = 0; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420SP)) { + hal_pixel_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420P)) + hal_pixel_format = HAL_PIXEL_FORMAT_YV12; // HACK + +#ifdef USE_EGL +#ifdef BOARD_USE_V4L2_ION + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_ION)) { +#else + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN)) { +#endif + LOGE("%s: could not set usage on gralloc buffer", __func__); + return INVALID_OPERATION; + } +#else +#ifdef BOARD_USE_V4L2_ION + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN + | GRALLOC_USAGE_HWC_HWOVERLAY | GRALLOC_USAGE_HW_ION)) { +#else + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN + | GRALLOC_USAGE_HW_FIMC1 | GRALLOC_USAGE_HWC_HWOVERLAY)) { +#endif + LOGE("%s: could not set usage on gralloc buffer", __func__); + return INVALID_OPERATION; + } +#endif + + if (w->set_buffers_geometry(w, + preview_width, preview_height, + hal_pixel_format)) { + LOGE("%s: could not set buffers geometry to %s", + __func__, str_preview_format); + return INVALID_OPERATION; + } + +#ifdef BOARD_USE_V4L2_ION + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) + if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) { + LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i); + return INVALID_OPERATION; + } +#endif + + if (mPreviewRunning && mPreviewStartDeferred) { + LOGV("start/resume preview"); + status_t ret = startPreviewInternal(); + if (ret == OK) { + mPreviewStartDeferred = false; + mPreviewCondition.signal(); + } + } + mPreviewLock.unlock(); + + return OK; +} + +void CameraHardwareSec::setCallbacks(camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user) +{ + mNotifyCb = notify_cb; + mDataCb = data_cb; + mDataCbTimestamp = data_cb_timestamp; + mGetMemoryCb = get_memory; + mCallbackCookie = user; +} + +void CameraHardwareSec::enableMsgType(int32_t msgType) +{ + LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x", + __func__, msgType, mMsgEnabled); + mMsgEnabled |= msgType; + + mPreviewLock.lock(); + if ((msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_VIDEO_FRAME)) && + mPreviewRunning && mPreviewStartDeferred) { + LOGV("%s: starting deferred preview", __func__); + if (startPreviewInternal() == OK) { + mPreviewStartDeferred = false; + mPreviewCondition.signal(); + } + } + mPreviewLock.unlock(); + + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); +} + +void CameraHardwareSec::disableMsgType(int32_t msgType) +{ + LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x", + __func__, msgType, mMsgEnabled); + mMsgEnabled &= ~msgType; + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); +} + +bool CameraHardwareSec::msgTypeEnabled(int32_t msgType) +{ + return (mMsgEnabled & msgType); +} + +void CameraHardwareSec::setSkipFrame(int frame) +{ + Mutex::Autolock lock(mSkipFrameLock); + if (frame < mSkipFrame) + return; + + mSkipFrame = frame; +} + +int CameraHardwareSec::previewThreadWrapper() +{ + LOGI("%s: starting", __func__); + while (1) { + mPreviewLock.lock(); + while (!mPreviewRunning) { + LOGI("%s: calling mSecCamera->stopPreview() and waiting", __func__); + mSecCamera->stopPreview(); + /* signal that we're stopping */ + mPreviewStoppedCondition.signal(); + mPreviewCondition.wait(mPreviewLock); + LOGI("%s: return from wait", __func__); + } + mPreviewLock.unlock(); + + if (mExitPreviewThread) { + LOGI("%s: exiting", __func__); + mSecCamera->stopPreview(); + return 0; + } + + previewThread(); + } +} + +int CameraHardwareSec::previewThread() +{ + int index; + nsecs_t timestamp; + SecBuffer previewAddr, recordAddr; + static int numArray = 0; + void *virAddr[3]; + camera_frame_metadata_t fdmeta; + camera_face_t caface[5]; + +#ifdef BOARD_USE_V4L2_ION + private_handle_t *hnd = NULL; +#else + struct addrs *addrs; +#endif + + fdmeta.faces = caface; + index = mSecCamera->getPreview(&fdmeta); + + mFaceData = &fdmeta; + + if (index < 0) { + LOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__); +#ifdef BOARD_USE_V4L2_ION + if (mSecCamera->getPreviewState()) { + stopPreview(); + startPreview(); + mSecCamera->clearPreviewState(); + } +#endif + return UNKNOWN_ERROR; + } + +#ifdef ZERO_SHUTTER_LAG + if (mUseInternalISP && !mRecordHint) { + mCapIndex = mSecCamera->getSnapshot(); + + if (mCapIndex >= 0) { + if (mSecCamera->setSnapshotFrame(mCapIndex) < 0) { + LOGE("%s: Fail qbuf, index(%d)", __func__, mCapIndex); + return INVALID_OPERATION; + } + } + } +#endif + + mSkipFrameLock.lock(); + if (mSkipFrame > 0) { + mSkipFrame--; + mSkipFrameLock.unlock(); + LOGV("%s: index %d skipping frame", __func__, index); + if (mSecCamera->setPreviewFrame(index) < 0) { + LOGE("%s: Could not qbuff[%d]!!", __func__, index); + return UNKNOWN_ERROR; + } + return NO_ERROR; + } + mSkipFrameLock.unlock(); + + timestamp = systemTime(SYSTEM_TIME_MONOTONIC); + + int width, height, frame_size, offset; + + mSecCamera->getPreviewSize(&width, &height, &frame_size); + + offset = frame_size * index; + + if (mPreviewWindow && mGrallocHal && mPreviewRunning) { +#ifdef BOARD_USE_V4L2_ION + hnd = (private_handle_t*)*mBufferHandle[index]; + + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + + mPreviewHeap = mGetMemoryCb(hnd->fd, frame_size, 1, 0); + + hnd = NULL; + + mGrallocHal->unlock(mGrallocHal, *mBufferHandle[index]); + if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[index])) { + LOGE("%s: Could not enqueue gralloc buffer[%d]!!", __func__, index); + goto callbacks; + } else { + mBufferHandle[index] = NULL; + mStride[index] = NULL; + } + + numArray = index; +#endif + + if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[numArray], &mStride[numArray])) { + LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, numArray); + goto callbacks; + } + + if (!mGrallocHal->lock(mGrallocHal, + *mBufferHandle[numArray], + GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR, + 0, 0, width, height, virAddr)) { +#ifdef BOARD_USE_V4L2 + mSecCamera->getPreviewAddr(index, &previewAddr); + char *frame = (char *)previewAddr.virt.extP[0]; +#else + char *frame = ((char *)mPreviewHeap->data) + offset; +#endif + +#ifdef BOARD_USE_V4L2_ION + mSecCamera->setUserBufferAddr(virAddr, index, PREVIEW_MODE); +#else + int total = frame_size + mFrameSizeDelta; + int h = 0; + char *src = frame; + + /* TODO : Need to fix size of planes for supported color fmt. + Currnetly we support only YV12(3 plane) and NV21(2 plane)*/ + // Y + memcpy(virAddr[0],src, width * height); + src += width * height; + + if (mPreviewFmtPlane == PREVIEW_FMT_2_PLANE) { + memcpy(virAddr[1], src, width * height / 2); + } else if (mPreviewFmtPlane == PREVIEW_FMT_3_PLANE) { + // U + memcpy(virAddr[1], src, width * height / 4); + src += width * height / 4; + + // V + memcpy(virAddr[2], src, width * height / 4); + } + + mGrallocHal->unlock(mGrallocHal, **mBufferHandle); +#endif + } + else + LOGE("%s: could not obtain gralloc buffer", __func__); + + if (mSecCamera->setPreviewFrame(index) < 0) { + LOGE("%s: Fail qbuf, index(%d)", __func__, index); + goto callbacks; + } + + index = 0; +#ifndef BOARD_USE_V4L2_ION + if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, *mBufferHandle)) { + LOGE("Could not enqueue gralloc buffer!"); + goto callbacks; + } +#endif + } + +callbacks: + // Notify the client of a new frame. + if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME && mPreviewRunning) + mDataCb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap, index, NULL, mCallbackCookie); + +#ifdef USE_FACE_DETECTION + if (mUseInternalISP && (mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA) && mPreviewRunning) + mDataCb(CAMERA_MSG_PREVIEW_METADATA, mFaceDataHeap, 0, mFaceData, mCallbackCookie); +#endif + + Mutex::Autolock lock(mRecordLock); + if (mRecordRunning == true) { + int recordingIndex = 0; + + index = mSecCamera->getRecordFrame(); + if (index < 0) { + LOGE("ERR(%s):Fail on SecCamera->getRecordFrame()", __func__); + return UNKNOWN_ERROR; + } + +#ifdef VIDEO_SNAPSHOT + if (mUseInternalISP && mRecordHint) { + mCapIndex = mSecCamera->getSnapshot(); + + if (mSecCamera->setSnapshotFrame(mCapIndex) < 0) { + LOGE("%s: Fail qbuf, index(%d)", __func__, mCapIndex); + return INVALID_OPERATION; + } + } +#endif + +#ifdef BOARD_USE_V4L2_ION + numArray = index; +#else + recordingIndex = index; + mSecCamera->getRecordAddr(index, &recordAddr); + + LOGV("record PhyY(0x%08x) phyC(0x%08x) ", recordAddr.phys.extP[0], recordAddr.phys.extP[1]); + + if (recordAddr.phys.extP[0] == 0xffffffff || recordAddr.phys.extP[1] == 0xffffffff) { + LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __func__, + recordAddr.phys.extP[0], recordAddr.phys.extP[1]); + return UNKNOWN_ERROR; + } + + addrs = (struct addrs *)(*mRecordHeap)->data; + + addrs[index].type = kMetadataBufferTypeCameraSource; + addrs[index].addr_y = recordAddr.phys.extP[0]; + addrs[index].addr_cbcr = recordAddr.phys.extP[1]; + addrs[index].buf_index = index; +#endif + + // Notify the client of a new frame. + if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) + mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, + mRecordHeap[numArray], recordingIndex, mCallbackCookie); + else + mSecCamera->releaseRecordFrame(index); + } + + return NO_ERROR; +} + +status_t CameraHardwareSec::startPreview() +{ + int ret = 0; + + LOGV("%s :", __func__); + + Mutex::Autolock lock(mStateLock); + if (mCaptureInProgress) { + LOGE("%s : capture in progress, not allowed", __func__); + return INVALID_OPERATION; + } + + mPreviewLock.lock(); + if (mPreviewRunning) { + // already running + LOGE("%s : preview thread already running", __func__); + mPreviewLock.unlock(); + return INVALID_OPERATION; + } + + mPreviewRunning = true; + mPreviewStartDeferred = false; + + if (!mPreviewWindow && + !(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) && + !(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) { + LOGI("%s : deferring", __func__); + mPreviewStartDeferred = true; + mPreviewLock.unlock(); + return NO_ERROR; + } + + ret = startPreviewInternal(); + if (ret == OK) + mPreviewCondition.signal(); + + mPreviewLock.unlock(); + return ret; +} + +status_t CameraHardwareSec::startPreviewInternal() +{ + LOGV("%s", __func__); + int width, height, frame_size; + + mSecCamera->getPreviewSize(&width, &height, &frame_size); + LOGD("mPreviewHeap(fd(%d), size(%d), width(%d), height(%d))", + mSecCamera->getCameraFd(SecCamera::PREVIEW), frame_size + mFrameSizeDelta, width, height); + +#ifdef BOARD_USE_V4L2_ION +#ifdef ZERO_SHUTTER_LAG +/*TODO*/ + int mPostViewWidth, mPostViewHeight, mPostViewSize; + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + for(int i = 0; i < CAP_BUFFERS; i++) { + mPostviewHeap[i] = new MemoryHeapBaseIon(mPostViewSize); + mSecCamera->setUserBufferAddr(mPostviewHeap[i]->base(), i, CAPTURE_MODE); + } +#endif + void *vaddr[3]; + + for (int i = 0; i < MAX_BUFFERS; i++) { + if (mBufferHandle[i] == NULL) { + if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) { + LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i); + return INVALID_OPERATION; + } + } + if (mGrallocHal->lock(mGrallocHal, + *mBufferHandle[i], + GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR, + 0, 0, width, height, vaddr)) { + LOGE("ERR(%s): Could not get virtual address!!, index = %d", __func__, i); + return UNKNOWN_ERROR; + } + mSecCamera->setUserBufferAddr(vaddr, i, PREVIEW_MODE); + } +#endif + + int ret = mSecCamera->startPreview(); + LOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret); + + if (ret < 0) { + LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__); + return UNKNOWN_ERROR; + } + + setSkipFrame(INITIAL_SKIP_FRAME); + + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + + for(int i=0; irelease(mRecordHeap[i]); + mRecordHeap[i] = 0; + } + } + +#ifndef BOARD_USE_V4L2 + mPreviewHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(SecCamera::PREVIEW), + frame_size + mFrameSizeDelta, + MAX_BUFFERS, + 0); // no cookie +#endif + + mFaceDataHeap = mGetMemoryCb(-1, 1, 1, 0); + + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + LOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d", + mPostViewWidth,mPostViewHeight,mPostViewSize); + + return NO_ERROR; +} + +void CameraHardwareSec::stopPreviewInternal() +{ + LOGV("%s :", __func__); + + /* request that the preview thread stop. */ + if (mPreviewRunning) { + mPreviewRunning = false; + if (!mPreviewStartDeferred) { + mPreviewCondition.signal(); + /* wait until preview thread is stopped */ + mPreviewStoppedCondition.wait(mPreviewLock); + +#ifdef BOARD_USE_V4L2_ION + for (int i = 0; i < MAX_BUFFERS; i++) { + if (mBufferHandle[i] != NULL) { + if (0 != mPreviewWindow->cancel_buffer(mPreviewWindow, mBufferHandle[i])) { + LOGE("%s: Fail to cancel buffer[%d]", __func__, i); + } else { + mBufferHandle[i] = NULL; + mStride[i] = NULL; + } + } + } +#endif + } + else + LOGV("%s : preview running but deferred, doing nothing", __func__); + } else + LOGI("%s : preview not running, doing nothing", __func__); +} + +void CameraHardwareSec::stopPreview() +{ + LOGV("%s :", __func__); + + /* request that the preview thread stop. */ + mPreviewLock.lock(); + stopPreviewInternal(); + mPreviewLock.unlock(); +} + +bool CameraHardwareSec::previewEnabled() +{ + Mutex::Autolock lock(mPreviewLock); + LOGV("%s : %d", __func__, mPreviewRunning); + return mPreviewRunning; +} + +status_t CameraHardwareSec::startRecording() +{ + LOGV("%s :", __func__); + + Mutex::Autolock lock(mRecordLock); + + for(int i = 0; irelease(mRecordHeap[i]); + mRecordHeap[i] = 0; + } + +#ifdef BOARD_USE_V4L2_ION + int width, height; + + mSecCamera->getRecordingSize(&width, &height); + + mRecordHeap[i] = mGetMemoryCb(-1, (ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048)), 1, NULL); + + mSecCamera->setUserBufferAddr((void *)(mRecordHeap[i]->data), i, RECORD_MODE); +#else + mRecordHeap[i] = mGetMemoryCb(-1, sizeof(struct addrs), MAX_BUFFERS, NULL); +#endif + if (!mRecordHeap[i]) { + LOGE("ERR(%s): Record heap[%d] creation fail", __func__, i); + return UNKNOWN_ERROR; + } + } + + LOGV("mRecordHeaps alloc done"); + + if (mRecordRunning == false) { + if (mSecCamera->startRecord(mRecordHint) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__); + return UNKNOWN_ERROR; + } + mRecordRunning = true; + } + return NO_ERROR; +} + +void CameraHardwareSec::stopRecording() +{ + LOGV("%s :", __func__); + + Mutex::Autolock lock(mRecordLock); + + if (mRecordRunning == true) { + if (mSecCamera->stopRecord() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __func__); + return; + } + mRecordRunning = false; + } +} + +bool CameraHardwareSec::recordingEnabled() +{ + LOGV("%s :", __func__); + LOGV("%s : %d", __func__, mPreviewRunning); + + return mRecordRunning; +} + +void CameraHardwareSec::releaseRecordingFrame(const void *opaque) +{ +#ifdef BOARD_USE_V4L2_ION + int i; + for (i = 0; i < MAX_BUFFERS; i++) + if ((char *)mRecordHeap[i]->data == (char *)opaque) + break; + + mSecCamera->releaseRecordFrame(i); +#else + struct addrs *addrs = (struct addrs *)opaque; + mSecCamera->releaseRecordFrame(addrs->buf_index); +#endif +} + +int CameraHardwareSec::autoFocusThread() +{ + int count =0; + int af_status =0 ; + + LOGV("%s : starting", __func__); + + /* block until we're told to start. we don't want to use + * a restartable thread and requestExitAndWait() in cancelAutoFocus() + * because it would cause deadlock between our callbacks and the + * caller of cancelAutoFocus() which both want to grab the same lock + * in CameraServices layer. + */ + mFocusLock.lock(); + /* check early exit request */ + if (mExitAutoFocusThread) { + mFocusLock.unlock(); + LOGV("%s : exiting on request0", __func__); + return NO_ERROR; + } + mFocusCondition.wait(mFocusLock); + /* check early exit request */ + if (mExitAutoFocusThread) { + mFocusLock.unlock(); + LOGV("%s : exiting on request1", __func__); + return NO_ERROR; + } + mFocusLock.unlock(); + + /* TODO : Currently only possible auto focus at BACK caemra + We need to modify to check that sensor can support auto focus */ + if (mCameraID == SecCamera::CAMERA_ID_BACK) { + LOGV("%s : calling setAutoFocus", __func__); + if (mTouched == 0) { + if (mSecCamera->setAutofocus() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__); + return UNKNOWN_ERROR; + } + } else { + if (mSecCamera->setTouchAF() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__); + return UNKNOWN_ERROR; + } + } + } + + /* TODO */ + /* This is temperary implementation. + When camera support AF blocking mode, this code will be removed + Continous AutoFocus is not need to success */ + const char *focusModeStr = mParameters.get(CameraParameters::KEY_FOCUS_MODE); + int isContinousAF = !strncmp(focusModeStr, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, 7); + if (mUseInternalISP && !isContinousAF) { + int i, err = -1; + for (i = 0; i < 400; i++) { + usleep(10000); + + af_status = mSecCamera->getAutoFocusResult(); + + if ((af_status & 0x2)) { + err = 0; + break; + } + } + } else { + af_status = mSecCamera->getAutoFocusResult(); + } + + if (af_status == 0x01) { + LOGV("%s : AF Cancelled !!", __func__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + } else if (af_status == 0x02) { + LOGV("%s : AF Success !!", __func__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) { + /* CAMERA_MSG_FOCUS only takes a bool. true for + * finished and false for failure. cancel is still + * considered a true result. + */ + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + } + } else { + LOGV("%s : AF Fail !!", __func__); + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); + } + + LOGV("%s : exiting with no error", __func__); + return NO_ERROR; +} + +status_t CameraHardwareSec::autoFocus() +{ + LOGV("%s :", __func__); + /* signal autoFocusThread to run once */ + mFocusCondition.signal(); + return NO_ERROR; +} + +status_t CameraHardwareSec::cancelAutoFocus() +{ + LOGV("%s :", __func__); + + if (mSecCamera->cancelAutofocus() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __func__); + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + +int CameraHardwareSec::save_jpeg( unsigned char *real_jpeg, int jpeg_size) +{ + FILE *yuv_fp = NULL; + char filename[100], *buffer = NULL; + + /* file create/open, note to "wb" */ + yuv_fp = fopen("/data/camera_dump.jpeg", "wb"); + if (yuv_fp == NULL) { + LOGE("Save jpeg file open error"); + return -1; + } + + LOGV("[BestIQ] real_jpeg size ========> %d", jpeg_size); + buffer = (char *) malloc(jpeg_size); + if (buffer == NULL) { + LOGE("Save YUV] buffer alloc failed"); + if (yuv_fp) + fclose(yuv_fp); + + return -1; + } + + memcpy(buffer, real_jpeg, jpeg_size); + + fflush(stdout); + + fwrite(buffer, 1, jpeg_size, yuv_fp); + + fflush(yuv_fp); + + if (yuv_fp) + fclose(yuv_fp); + if (buffer) + free(buffer); + + return 0; +} + +void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t size) +{ + int nw; + int cnt = 0; + uint32_t written = 0; + + LOGD("opening file [%s]", fname); + int fd = open(fname, O_RDWR | O_CREAT); + if (fd < 0) { + LOGE("failed to create file [%s]: %s", fname, strerror(errno)); + return; + } + + LOGD("writing %d bytes to file [%s]", size, fname); + while (written < size) { + nw = ::write(fd, buf + written, size - written); + if (nw < 0) { + LOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno)); + break; + } + written += nw; + cnt++; + } + LOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt); + ::close(fd); +} + +bool CameraHardwareSec::scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHeight, + char *dstBuf, uint32_t dstWidth, uint32_t dstHeight) +{ + int32_t step_x, step_y; + int32_t iXsrc, iXdst; + int32_t x, y, src_y_start_pos, dst_pos, src_pos; + + if (dstWidth % 2 != 0 || dstHeight % 2 != 0) { + LOGE("scale_down_yuv422: invalid width, height for scaling"); + return false; + } + + step_x = srcWidth / dstWidth; + step_y = srcHeight / dstHeight; + + dst_pos = 0; + for (uint32_t y = 0; y < dstHeight; y++) { + src_y_start_pos = (y * step_y * (srcWidth * 2)); + + for (uint32_t x = 0; x < dstWidth; x += 2) { + src_pos = src_y_start_pos + (x * (step_x * 2)); + + dstBuf[dst_pos++] = srcBuf[src_pos ]; + dstBuf[dst_pos++] = srcBuf[src_pos + 1]; + dstBuf[dst_pos++] = srcBuf[src_pos + 2]; + dstBuf[dst_pos++] = srcBuf[src_pos + 3]; + } + } + + return true; +} + +bool CameraHardwareSec::YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight) +{ + int32_t x, y, src_y_start_pos, dst_cbcr_pos, dst_pos, src_pos; + unsigned char *srcBufPointer = (unsigned char *)srcBuf; + unsigned char *dstBufPointer = (unsigned char *)dstBuf; + + dst_pos = 0; + dst_cbcr_pos = srcWidth*srcHeight; + for (uint32_t y = 0; y < srcHeight; y++) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 2) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_pos++] = srcBufPointer[src_pos]; + } + } + for (uint32_t y = 0; y < srcHeight; y += 2) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 4) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 3]; + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 1]; + } + } + + return true; +} + +int CameraHardwareSec::pictureThread() +{ + LOGV("%s :", __func__); + + int jpeg_size = 0; + int ret = NO_ERROR; + unsigned char *jpeg_data = NULL; + int postview_offset = 0; + unsigned char *postview_data = NULL; + + unsigned char *addr = NULL; + int mPostViewWidth, mPostViewHeight, mPostViewSize; + int mThumbWidth, mThumbHeight, mThumbSize; + int cap_width, cap_height, cap_frame_size; + + int JpegImageSize = 0; + + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + mSecCamera->getThumbnailConfig(&mThumbWidth, &mThumbHeight, &mThumbSize); + int postviewHeapSize = mPostViewSize; + if (!mRecordRunning) + mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); + else + mSecCamera->getVideosnapshotSize(&cap_width, &cap_height, &cap_frame_size); + int mJpegHeapSize; + if (!mUseInternalISP) + mJpegHeapSize = cap_frame_size * SecCamera::getJpegRatio(); + else + mJpegHeapSize = cap_frame_size; + + LOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight); + + camera_memory_t *JpegHeap = mGetMemoryCb(-1, mJpegHeapSize, 1, 0); +#ifdef BOARD_USE_V4L2_ION +#ifdef ZERO_SHUTTER_LAG + mThumbnailHeap = new MemoryHeapBaseIon(mThumbSize); +#else + mPostviewHeap[mCapIndex] = new MemoryHeapBaseIon(mPostViewSize); + mThumbnailHeap = new MemoryHeapBaseIon(mThumbSize); +#endif +#else + mThumbnailHeap = new MemoryHeapBase(mThumbSize); +#endif + + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { + int picture_size, picture_width, picture_height; + mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size); + int picture_format = mSecCamera->getSnapshotPixelFormat(); + + unsigned int thumb_addr, phyAddr; + + // Modified the shutter sound timing for Jpeg capture + if (!mUseInternalISP) { + mSecCamera->setSnapshotCmd(); + + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + + jpeg_data = mSecCamera->getJpeg(&JpegImageSize, &mThumbSize, &thumb_addr, &phyAddr); + if (jpeg_data == NULL) { + LOGE("ERR(%s):Fail on SecCamera->getJpeg()", __func__); + ret = UNKNOWN_ERROR; + } + + memcpy((unsigned char *)mThumbnailHeap->base(), (unsigned char *)thumb_addr, mThumbSize); + memcpy(JpegHeap->data, jpeg_data, JpegImageSize); + } else { + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + +#ifdef ZERO_SHUTTER_LAG + mSecCamera->getCaptureAddr(mCapIndex, &mCapBuffer); + + if (mCapBuffer.virt.extP[0] == NULL) { + LOGE("ERR(%s):Fail on SecCamera getCaptureAddr = %0x ", + __func__, mCapBuffer.virt.extP[0]); + return UNKNOWN_ERROR; + } + + scaleDownYuv422((char *)mCapBuffer.virt.extP[0], cap_width, cap_height, + (char *)mThumbnailHeap->base(), mThumbWidth, mThumbHeight); +#else +#ifdef BOARD_USE_V4L2_ION + mCapBuffer.virt.extP[0] = (char *)mPostviewHeap[mCapIndex]->base(); +#endif +#endif + + if (mSecCamera->getSnapshotAndJpeg(&mCapBuffer, mCapIndex, + (unsigned char*)JpegHeap->data, &JpegImageSize) < 0) { + mStateLock.lock(); + mCaptureInProgress = false; + mStateLock.unlock(); + JpegHeap->release(JpegHeap); + return UNKNOWN_ERROR; + } + LOGI("snapshotandjpeg done"); + +#ifdef ZERO_SHUTTER_LAG + if (!mRecordRunning) + stopPreview(); + memset(&mCapBuffer, 0, sizeof(struct SecBuffer)); +#else + scaleDownYuv422((char *)mCapBuffer.virt.extP[0], cap_width, cap_height, + (char *)mThumbnailHeap->base(), mThumbWidth, mThumbHeight); +#endif + } + } + +#ifndef BOARD_USE_V4L2_ION + int rawHeapSize = cap_frame_size; + LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize); +#ifdef BOARD_USE_V4L2_ION + mRawHeap = mGetMemoryCb(mPostviewHeap[mCapIndex]->getHeapID(), rawHeapSize, 1, 0); +#else + mRawHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(SecCamera::PICTURE), rawHeapSize, 1, 0); +#endif + if (!mRawHeap) + LOGE("ERR(%s): Raw heap creation fail", __func__); + + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) + mDataCb(CAMERA_MSG_RAW_IMAGE, mRawHeap, 0, NULL, mCallbackCookie); +#endif + mStateLock.lock(); + mCaptureInProgress = false; + mStateLock.unlock(); + + if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { + camera_memory_t *ExifHeap = + mGetMemoryCb(-1, EXIF_FILE_SIZE + mThumbSize, 1, 0); + + int JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data, + (unsigned char *)mThumbnailHeap->base(), + mThumbSize); + LOGV("JpegExifSize=%d", JpegExifSize); + + if (JpegExifSize < 0) { + ret = UNKNOWN_ERROR; + goto out; + } + + int mJpegHeapSize_out = JpegImageSize + JpegExifSize; + camera_memory_t *JpegHeap_out = mGetMemoryCb(-1, mJpegHeapSize_out, 1, 0); + + unsigned char *ExifStart = (unsigned char *)JpegHeap_out->data + 2; + unsigned char *ImageStart = ExifStart + JpegExifSize; + + memcpy(JpegHeap_out->data, JpegHeap->data, 2); + memcpy(ExifStart, ExifHeap->data, JpegExifSize); + memcpy(ImageStart, JpegHeap->data + 2, JpegImageSize - 2); + + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, JpegHeap_out, 0, NULL, mCallbackCookie); + + if (ExifHeap) { + ExifHeap->release(ExifHeap); + ExifHeap = 0; + } + + if (JpegHeap_out) { + JpegHeap_out->release(JpegHeap_out); + JpegHeap_out = 0; + } + } + + LOGV("%s : pictureThread end", __func__); + +out: + if (JpegHeap) { + JpegHeap->release(JpegHeap); + JpegHeap = 0; + } + + if (mRawHeap) { + mRawHeap->release(mRawHeap); + mRawHeap = 0; + } + + if (!mUseInternalISP && !mRecordRunning) + mSecCamera->endSnapshot(); + + return ret; +} + +status_t CameraHardwareSec::takePicture() +{ + LOGV("%s :", __func__); + +#ifdef ZERO_SHUTTER_LAG + if (!mUseInternalISP) { + stopPreview(); + } +#else + stopPreview(); +#endif + + Mutex::Autolock lock(mStateLock); + if (mCaptureInProgress) { + LOGE("%s : capture already in progress", __func__); + return INVALID_OPERATION; + } + + if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) { + LOGE("%s : couldn't run picture thread", __func__); + return INVALID_OPERATION; + } + mCaptureInProgress = true; + + return NO_ERROR; +} + +status_t CameraHardwareSec::cancelPicture() +{ + LOGV("%s", __func__); + + if (mPictureThread.get()) { + LOGV("%s: waiting for picture thread to exit", __func__); + mPictureThread->requestExitAndWait(); + LOGV("%s: picture thread has exited", __func__); + } + + return NO_ERROR; +} + +bool CameraHardwareSec::CheckVideoStartMarker(unsigned char *pBuf) +{ + if (!pBuf) { + LOGE("CheckVideoStartMarker() => pBuf is NULL"); + return false; + } + + if (HIBYTE(VIDEO_COMMENT_MARKER_H) == * pBuf && LOBYTE(VIDEO_COMMENT_MARKER_H) == *(pBuf + 1) && + HIBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 2) && LOBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 3)) + return true; + + return false; +} + +bool CameraHardwareSec::CheckEOIMarker(unsigned char *pBuf) +{ + if (!pBuf) { + LOGE("CheckEOIMarker() => pBuf is NULL"); + return false; + } + + // EOI marker [FF D9] + if (HIBYTE(JPEG_EOI_MARKER) == *pBuf && LOBYTE(JPEG_EOI_MARKER) == *(pBuf + 1)) + return true; + + return false; +} + +bool CameraHardwareSec::FindEOIMarkerInJPEG(unsigned char *pBuf, int dwBufSize, int *pnJPEGsize) +{ + if (NULL == pBuf || 0 >= dwBufSize) { + LOGE("FindEOIMarkerInJPEG() => There is no contents."); + return false; + } + + unsigned char *pBufEnd = pBuf + dwBufSize; + + while (pBuf < pBufEnd) { + if (CheckEOIMarker(pBuf++)) + return true; + + (*pnJPEGsize)++; + } + + return false; +} + +bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize, + int dwJPEGLineLength, int dwVideoLineLength, int dwVideoHeight, + void *pJPEG, int *pdwJPEGSize, + void *pVideo, int *pdwVideoSize) +{ + LOGV("===========SplitFrame Start=============="); + + if (NULL == pFrame || 0 >= dwSize) { + LOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize); + return false; + } + + if (0 == dwJPEGLineLength || 0 == dwVideoLineLength) { + LOGE("There in no input information for decoding interleaved jpeg"); + return false; + } + + unsigned char *pSrc = pFrame; + unsigned char *pSrcEnd = pFrame + dwSize; + + unsigned char *pJ = (unsigned char *)pJPEG; + int dwJSize = 0; + unsigned char *pV = (unsigned char *)pVideo; + int dwVSize = 0; + + bool bRet = false; + bool isFinishJpeg = false; + + while (pSrc < pSrcEnd) { + // Check video start marker + if (CheckVideoStartMarker(pSrc)) { + int copyLength; + + if (pSrc + dwVideoLineLength <= pSrcEnd) + copyLength = dwVideoLineLength; + else + copyLength = pSrcEnd - pSrc - VIDEO_COMMENT_MARKER_LENGTH; + + // Copy video data + if (pV) { + memcpy(pV, pSrc + VIDEO_COMMENT_MARKER_LENGTH, copyLength); + pV += copyLength; + dwVSize += copyLength; + } + + pSrc += copyLength + VIDEO_COMMENT_MARKER_LENGTH; + } else { + // Copy pure JPEG data + int size = 0; + int dwCopyBufLen = dwJPEGLineLength <= pSrcEnd-pSrc ? dwJPEGLineLength : pSrcEnd - pSrc; + + if (FindEOIMarkerInJPEG((unsigned char *)pSrc, dwCopyBufLen, &size)) { + isFinishJpeg = true; + size += 2; // to count EOF marker size + } else { + if ((dwCopyBufLen == 1) && (pJPEG < pJ)) { + unsigned char checkBuf[2] = { *(pJ - 1), *pSrc }; + + if (CheckEOIMarker(checkBuf)) + isFinishJpeg = true; + } + size = dwCopyBufLen; + } + + memcpy(pJ, pSrc, size); + + dwJSize += size; + + pJ += dwCopyBufLen; + pSrc += dwCopyBufLen; + } + if (isFinishJpeg) + break; + } + + if (isFinishJpeg) { + bRet = true; + if (pdwJPEGSize) + *pdwJPEGSize = dwJSize; + if (pdwVideoSize) + *pdwVideoSize = dwVSize; + } else { + LOGE("DecodeInterleaveJPEG_WithOutDT() => Can not find EOI"); + bRet = false; + if (pdwJPEGSize) + *pdwJPEGSize = 0; + if (pdwVideoSize) + *pdwVideoSize = 0; + } + LOGV("===========SplitFrame end=============="); + + return bRet; +} + +int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData) +{ + if (pInterleaveData == NULL) + return false; + + bool ret = true; + unsigned int *interleave_ptr = (unsigned int *)pInterleaveData; + unsigned char *jpeg_ptr = (unsigned char *)pJpegData; + unsigned char *yuv_ptr = (unsigned char *)pYuvData; + unsigned char *p; + int jpeg_size = 0; + int yuv_size = 0; + + int i = 0; + + LOGV("decodeInterleaveData Start~~~"); + while (i < interleaveDataSize) { + if ((*interleave_ptr == 0xFFFFFFFF) || (*interleave_ptr == 0x02FFFFFF) || + (*interleave_ptr == 0xFF02FFFF)) { + // Padding Data + interleave_ptr++; + i += 4; + } else if ((*interleave_ptr & 0xFFFF) == 0x05FF) { + // Start-code of YUV Data + p = (unsigned char *)interleave_ptr; + p += 2; + i += 2; + + // Extract YUV Data + if (pYuvData != NULL) { + memcpy(yuv_ptr, p, yuvWidth * 2); + yuv_ptr += yuvWidth * 2; + yuv_size += yuvWidth * 2; + } + p += yuvWidth * 2; + i += yuvWidth * 2; + + // Check End-code of YUV Data + if ((*p == 0xFF) && (*(p + 1) == 0x06)) { + interleave_ptr = (unsigned int *)(p + 2); + i += 2; + } else { + ret = false; + break; + } + } else { + // Extract JPEG Data + if (pJpegData != NULL) { + memcpy(jpeg_ptr, interleave_ptr, 4); + jpeg_ptr += 4; + jpeg_size += 4; + } + interleave_ptr++; + i += 4; + } + } + if (ret) { + if (pJpegData != NULL) { + // Remove Padding after EOI + for (i = 0; i < 3; i++) { + if (*(--jpeg_ptr) != 0xFF) { + break; + } + jpeg_size--; + } + *pJpegSize = jpeg_size; + + } + // Check YUV Data Size + if (pYuvData != NULL) { + if (yuv_size != (yuvWidth * yuvHeight * 2)) { + ret = false; + } + } + } + LOGV("decodeInterleaveData End~~~"); + return ret; +} + +status_t CameraHardwareSec::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + const Vector args; + + if (mSecCamera != 0) { + mSecCamera->dump(fd); + mParameters.dump(fd, args); + mInternalParameters.dump(fd, args); + snprintf(buffer, 255, " preview running(%s)\n", mPreviewRunning?"true": "false"); + result.append(buffer); + } else + result.append("No camera client yet.\n"); + write(fd, result.string(), result.size()); + return NO_ERROR; +} + +bool CameraHardwareSec::isSupportedPreviewSize(const int width, + const int height) const +{ + unsigned int i; + + for (i = 0; i < mSupportedPreviewSizes.size(); i++) { + if (mSupportedPreviewSizes[i].width == width && + mSupportedPreviewSizes[i].height == height) + return true; + } + + return false; +} + +bool CameraHardwareSec::getVideosnapshotSize(int *width, int *height) +{ + unsigned int i; + Vector pictureSizes, videoSizes; + int ratio = FRM_RATIO(*width, *height); + + mParameters.getSupportedPictureSizes(pictureSizes); + mParameters.getSupportedVideoSizes(videoSizes); + + for (i = 0; i < pictureSizes.size(); i++) { + if (FRM_RATIO(pictureSizes[i].width, pictureSizes[i].height) == ratio) { + if (mRecordHint) { + if (pictureSizes[i].width <= videoSizes[0].width) { + *width = pictureSizes[i].width; + *height = pictureSizes[i].height; + LOGV("%s(width(%d), height(%d))", __func__, *width, *height); + return true; + } + } else { + *width = pictureSizes[i].width; + *height = pictureSizes[i].height; + LOGV("%s(width(%d), height(%d))", __func__, *width, *height); + return true; + } + } + } + + return false; +} + +status_t CameraHardwareSec::setParameters(const CameraParameters& params) +{ + LOGV("%s :", __func__); + + status_t ret = NO_ERROR; + + const char *new_record_hint_str = params.get(CameraParameters::KEY_RECORDING_HINT); + const char *curr_record_hint_str = mParameters.get(CameraParameters::KEY_RECORDING_HINT); + LOGV("new_record_hint_str: %s", new_record_hint_str); + + if (new_record_hint_str) { + if (strncmp(new_record_hint_str, curr_record_hint_str, 5)) { + mRecordHint = !strncmp(new_record_hint_str, "true", 4); + if (mSecCamera->setMode(mRecordHint) < 0) { + LOGE("ERR(%s):fail on mSecCamera->setMode(%d)", __func__, mRecordHint); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_RECORDING_HINT, new_record_hint_str); + } + + if (mUseInternalISP) { + if (mSecCamera->initSetParams() < 0) { + LOGE("ERR(%s):fail on mSecCamera->initSetParams()", __func__); + ret = UNKNOWN_ERROR; + } + } + } + } + + /* if someone calls us while picture thread is running, it could screw + * up the sensor quite a bit so return error. we can't wait because + * that would cause deadlock with the callbacks + */ + mStateLock.lock(); + if (mCaptureInProgress) { + mStateLock.unlock(); + LOGE("%s : capture in progress, not allowed", __func__); + return UNKNOWN_ERROR; + } + mStateLock.unlock(); + + // preview size + int new_preview_width = 0; + int new_preview_height = 0; + int new_preview_format = 0; + + params.getPreviewSize(&new_preview_width, &new_preview_height); + + if (mUseInternalISP) { + int videosnapshot_width = new_preview_width; + int videosnapshot_height = new_preview_height; + + if (!getVideosnapshotSize(&videosnapshot_width, &videosnapshot_height)) { + LOGE("ERR(%s):fail on getVideosnapshotSize(width(%d), height(%d))", + __func__, videosnapshot_width, videosnapshot_height); + ret = UNKNOWN_ERROR; + } + + if (mSecCamera->setVideosnapshotSize(videosnapshot_width, videosnapshot_height) < 0) { + LOGE("ERR(%s):fail on mSecCamera->setVideosnapshotSize(width(%d), height(%d))", + __func__, videosnapshot_width, videosnapshot_height); + ret = UNKNOWN_ERROR; + } + } + + const char *new_str_preview_format = params.getPreviewFormat(); + LOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s", + __func__, new_preview_width, new_preview_height, new_str_preview_format); + + if (0 < new_preview_width && 0 < new_preview_height && + new_str_preview_format != NULL && + isSupportedPreviewSize(new_preview_width, new_preview_height)) { + + mFrameSizeDelta = 16; + if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_RGB565)) { + new_preview_format = V4L2_PIX_FMT_RGB565; + mFrameSizeDelta = 0; + } + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_RGBA8888)) { + new_preview_format = V4L2_PIX_FMT_RGB32; + mFrameSizeDelta = 0; + } + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420SP)) { + new_preview_format = V4L2_PIX_FMT_NV21; + mPreviewFmtPlane = PREVIEW_FMT_2_PLANE; + } + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420P)) { +#ifdef BOARD_USE_V4L2_ION + new_preview_format = V4L2_PIX_FMT_YVU420M; +#else + new_preview_format = V4L2_PIX_FMT_YVU420; +#endif + mPreviewFmtPlane = PREVIEW_FMT_3_PLANE; + } + else if (!strcmp(new_str_preview_format, "yuv420sp_custom")) + new_preview_format = V4L2_PIX_FMT_NV12T; + else if (!strcmp(new_str_preview_format, "yuv422i")) + new_preview_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_preview_format, "yuv422p")) + new_preview_format = V4L2_PIX_FMT_YUV422P; + else + new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party + + int current_preview_width, current_preview_height, current_frame_size; + mSecCamera->getPreviewSize(¤t_preview_width, + ¤t_preview_height, + ¤t_frame_size); + int current_pixel_format = mSecCamera->getPreviewPixelFormat(); + + if (current_preview_width != new_preview_width || + current_preview_height != new_preview_height || + current_pixel_format != new_preview_format) { + if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height, + new_preview_format) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))", + __func__, new_preview_width, new_preview_height, new_preview_format); + ret = UNKNOWN_ERROR; + } else { + if (mPreviewWindow) { + if (mPreviewRunning && !mPreviewStartDeferred) { + LOGE("ERR(%s): preview is running, cannot change size and format!", __func__); + ret = INVALID_OPERATION; + } + LOGV("%s: mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow); + LOGV("%s: mPreviewWindow->set_buffers_geometry (%p)", __func__, + mPreviewWindow->set_buffers_geometry); + mPreviewWindow->set_buffers_geometry(mPreviewWindow, + new_preview_width, new_preview_height, + V4L2_PIX_2_HAL_PIXEL_FORMAT(new_preview_format)); + LOGV("%s: DONE mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow); + } + mParameters.setPreviewSize(new_preview_width, new_preview_height); + mParameters.setPreviewFormat(new_str_preview_format); + } + } + } else { + LOGE("%s: Invalid preview size(%dx%d)", + __func__, new_preview_width, new_preview_height); + + ret = INVALID_OPERATION; + } + + // picture size + int new_picture_width = 0; + int new_picture_height = 0; + + params.getPictureSize(&new_picture_width, &new_picture_height); + LOGV("%s : new_picture_width x new_picture_height = %dx%d", __func__, new_picture_width, new_picture_height); + + int current_picture_width, current_picture_height, current_picture_size; + mSecCamera->getSnapshotSize(¤t_picture_width, ¤t_picture_height, ¤t_picture_size); + + if (new_picture_width != current_picture_width || + new_picture_height != current_picture_height) { + if (mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) { + LOGE("ERR(%s):fail on mSecCamera->setSnapshotSize(width(%d), height(%d))", + __func__, new_picture_width, new_picture_height); + ret = UNKNOWN_ERROR; + } else { +#ifdef ZERO_SHUTTER_LAG + mSecCamera->stopSnapshot(); + if (mUseInternalISP && !mRecordHint && mPreviewRunning){ + mSecCamera->startSnapshot(NULL); + } +#endif + mParameters.setPictureSize(new_picture_width, new_picture_height); + } + } + + // picture format + const char *new_str_picture_format = params.getPictureFormat(); + LOGV("%s : new_str_picture_format %s", __func__, new_str_picture_format); + if (new_str_picture_format != NULL) { + int new_picture_format = 0; + + if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGB565)) + new_picture_format = V4L2_PIX_FMT_RGB565; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGBA8888)) + new_picture_format = V4L2_PIX_FMT_RGB32; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_YUV420SP)) + new_picture_format = V4L2_PIX_FMT_NV21; + else if (!strcmp(new_str_picture_format, "yuv420sp_custom")) + new_picture_format = V4L2_PIX_FMT_NV12T; + else if (!strcmp(new_str_picture_format, "yuv420p")) + new_picture_format = V4L2_PIX_FMT_YUV420; + else if (!strcmp(new_str_picture_format, "yuv422i")) + new_picture_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_picture_format, "uyv422i_custom")) //Zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (!strcmp(new_str_picture_format, "uyv422i")) //Non-zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_JPEG)) + new_picture_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_picture_format, "yuv422p")) + new_picture_format = V4L2_PIX_FMT_YUV422P; + else + new_picture_format = V4L2_PIX_FMT_NV21; //for 3rd party + + if (mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __func__, new_picture_format); + ret = UNKNOWN_ERROR; + } else + mParameters.setPictureFormat(new_str_picture_format); + } + + // JPEG image quality + int new_jpeg_quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY); + LOGV("%s : new_jpeg_quality %d", __func__, new_jpeg_quality); + /* we ignore bad values */ + if (new_jpeg_quality >=1 && new_jpeg_quality <= 100) { + if (mSecCamera->setJpegQuality(new_jpeg_quality) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegQuality(quality(%d))", __func__, new_jpeg_quality); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_JPEG_QUALITY, new_jpeg_quality); + } + + // JPEG thumbnail size + int new_jpeg_thumbnail_width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); + int new_jpeg_thumbnail_height= params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); + if (0 <= new_jpeg_thumbnail_width && 0 <= new_jpeg_thumbnail_height) { + if (mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __func__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, new_jpeg_thumbnail_width); + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, new_jpeg_thumbnail_height); + } + } + + // JPEG thumbnail quality + int new_jpeg_thumbnail_quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); + LOGV("%s : new_jpeg_thumbnail_quality %d", __func__, new_jpeg_thumbnail_quality); + /* we ignore bad values */ + if (new_jpeg_thumbnail_quality >=1 && new_jpeg_thumbnail_quality <= 100) { + if (mSecCamera->setJpegThumbnailQuality(new_jpeg_thumbnail_quality) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailQuality(quality(%d))", + __func__, new_jpeg_thumbnail_quality); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, new_jpeg_thumbnail_quality); + } + + // frame rate + int new_frame_rate = params.getPreviewFrameRate(); + /* ignore any fps request, we're determine fps automatically based + * on scene mode. don't return an error because it causes CTS failure. + */ + if (mRecordHint) { + if (new_frame_rate) { + if (mUseInternalISP && (mSecCamera->setFrameRate(new_frame_rate) < 0)){ + LOGE("ERR(%s):Fail on mSecCamera->setFrameRate(%d)", __func__, new_frame_rate); + ret = UNKNOWN_ERROR; + } else { + mParameters.setPreviewFrameRate(new_frame_rate); + } + } + } + + // rotation + int new_rotation = params.getInt(CameraParameters::KEY_ROTATION); + LOGV("%s : new_rotation %d", __func__, new_rotation); + if (0 <= new_rotation) { + LOGV("%s : set orientation:%d", __func__, new_rotation); + if (mSecCamera->setExifOrientationInfo(new_rotation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_rotation); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_ROTATION, new_rotation); + } + + // zoom + int new_zoom = params.getInt(CameraParameters::KEY_ZOOM); + int current_zoom = mParameters.getInt(CameraParameters::KEY_ZOOM); + LOGV("%s : new_zoom %d", __func__, new_zoom); + if (0 <= new_zoom) { + if (new_zoom != current_zoom) { + if (mSecCamera->setZoom(new_zoom) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setZoom(zoom(%d))", __func__, new_zoom); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_ZOOM, new_zoom); + } + } + } + + // brightness + int new_brightness = params.getInt("brightness"); + int max_brightness = params.getInt("brightness-max"); + int min_brightness = params.getInt("brightness-min"); + LOGV("%s : new_brightness %d", __func__, new_brightness); + if ((min_brightness <= new_brightness) && + (max_brightness >= new_brightness)) { + if (mSecCamera->setBrightness(new_brightness) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_brightness); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("brightness", new_brightness); + } + } + + // saturation + int new_saturation = params.getInt("saturation"); + int max_saturation = params.getInt("saturation-max"); + int min_saturation = params.getInt("saturation-min"); + LOGV("%s : new_saturation %d", __func__, new_saturation); + if ((min_saturation <= new_saturation) && + (max_saturation >= new_saturation)) { + if (mSecCamera->setSaturation(new_saturation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSaturation(saturation(%d))", __func__, new_saturation); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("saturation", new_saturation); + } + } + + // sharpness + int new_sharpness = params.getInt("sharpness"); + int max_sharpness = params.getInt("sharpness-max"); + int min_sharpness = params.getInt("sharpness-min"); + LOGV("%s : new_sharpness %d", __func__, new_sharpness); + if ((min_sharpness <= new_sharpness) && + (max_sharpness >= new_sharpness)) { + if (mSecCamera->setSharpness(new_sharpness) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSharpness(sharpness(%d))", __func__, new_sharpness); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("sharpness", new_sharpness); + } + } + + // hue + int new_hue = params.getInt("hue"); + int max_hue = params.getInt("hue-max"); + int min_hue = params.getInt("hue-min"); + LOGV("%s : new_hue %d", __func__, new_hue); + if ((min_hue <= new_hue) && + (max_hue >= new_hue)) { + if (mSecCamera->setHue(new_hue) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setHue(hue(%d))", __func__, new_hue); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("hue", new_hue); + } + } + + // exposure + int new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); + int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); + int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); + LOGV("%s : new_exposure_compensation %d", __func__, new_exposure_compensation); + if ((min_exposure_compensation <= new_exposure_compensation) && + (max_exposure_compensation >= new_exposure_compensation)) { + if (mSecCamera->setExposure(new_exposure_compensation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExposure(exposure(%d))", __func__, new_exposure_compensation); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, new_exposure_compensation); + } + } + + const char *new_AE_lock = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK); + const char *old_AE_lock = mParameters.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK); + if ((new_AE_lock != NULL) && mUseInternalISP && mPreviewRunning) { + if (strncmp(new_AE_lock, old_AE_lock, 4)) { + int ae_value = !strncmp(new_AE_lock, "true", 4); + if (mSecCamera->setAutoExposureLock(ae_value) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExposureLock", __func__); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, new_AE_lock); + } + } + } + + // ISO + const char *new_iso_str = params.get("iso"); + LOGV("%s : new_iso_str %s", __func__, new_iso_str); + if (new_iso_str != NULL) { + int new_iso = -1; + + if (!strcmp(new_iso_str, "auto")) { + new_iso = ISO_AUTO; + } else if (!strcmp(new_iso_str, "50")) { + new_iso = ISO_50; + } else if (!strcmp(new_iso_str, "100")) { + new_iso = ISO_100; + } else if (!strcmp(new_iso_str, "200")) { + new_iso = ISO_200; + } else if (!strcmp(new_iso_str, "400")) { + new_iso = ISO_400; + } else if (!strcmp(new_iso_str, "800")) { + new_iso = ISO_800; + } else if (!strcmp(new_iso_str, "1600")) { + new_iso = ISO_1600; + } else { + LOGE("ERR(%s):Invalid iso value(%s)", __func__, new_iso_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_iso) { + if (mSecCamera->setISO(new_iso) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setISO(iso(%d))", __func__, new_iso); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("iso", new_iso_str); + } + } + } + + // Metering + const char *new_metering_str = params.get("metering"); + LOGV("%s : new_metering_str %s", __func__, new_metering_str); + if (new_metering_str != NULL) { + int new_metering = -1; + + if (!strcmp(new_metering_str, "center")) { + new_metering = METERING_CENTER; + } else if (!strcmp(new_metering_str, "spot")) { + new_metering = METERING_SPOT; + } else if (!strcmp(new_metering_str, "matrix")) { + new_metering = METERING_MATRIX; + } else { + LOGE("ERR(%s):Invalid metering value(%s)", __func__, new_metering_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_metering) { + if (mSecCamera->setMetering(new_metering) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setMetering(metering(%d))", __func__, new_metering); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("metering", new_metering_str); + } + } + } + + // AFC + const char *new_antibanding_str = params.get(CameraParameters::KEY_ANTIBANDING); + LOGV("%s : new_antibanding_str %s", __func__, new_antibanding_str); + if (new_antibanding_str != NULL) { + int new_antibanding = -1; + + if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_AUTO)) { + if (mUseInternalISP) + new_antibanding = IS_AFC_AUTO; + else + new_antibanding = ANTI_BANDING_AUTO; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_50HZ)) { + if (mUseInternalISP) + new_antibanding = IS_AFC_MANUAL_50HZ; + else + new_antibanding = ANTI_BANDING_50HZ; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_60HZ)) { + if (mUseInternalISP) + new_antibanding = IS_AFC_MANUAL_60HZ; + else + new_antibanding = ANTI_BANDING_60HZ; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_OFF)) { + if (mUseInternalISP) + new_antibanding = IS_AFC_DISABLE; + else + new_antibanding = ANTI_BANDING_OFF; + } else { + LOGE("ERR(%s):Invalid antibanding value(%s)", __func__, new_antibanding_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_antibanding) { + if (mSecCamera->setAntiBanding(new_antibanding) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setAntiBanding(antibanding(%d))", __func__, new_antibanding); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_ANTIBANDING, new_antibanding_str); + } + } + } + + // scene mode + const char *new_scene_mode_str = params.get(CameraParameters::KEY_SCENE_MODE); + const char *current_scene_mode_str = mParameters.get(CameraParameters::KEY_SCENE_MODE); + + // fps range + int new_min_fps = 0; + int new_max_fps = 0; + int current_min_fps, current_max_fps; + params.getPreviewFpsRange(&new_min_fps, &new_max_fps); + mParameters.getPreviewFpsRange(¤t_min_fps, ¤t_max_fps); + /* our fps range is determined by the sensor, reject any request + * that isn't exactly what we're already at. + * but the check is performed when requesting only changing fps range + */ + if (new_scene_mode_str && current_scene_mode_str) { + if (!strcmp(new_scene_mode_str, current_scene_mode_str)) { + if ((new_min_fps != current_min_fps) || (new_max_fps != current_max_fps)) { + LOGW("%s : requested new_min_fps = %d, new_max_fps = %d not allowed", + __func__, new_min_fps, new_max_fps); + /* TODO : We need policy for fps. */ + LOGW("%s : current_min_fps = %d, current_max_fps = %d", + __func__, current_min_fps, current_max_fps); + //ret = UNKNOWN_ERROR; + } + } + } else { + /* Check basic validation if scene mode is different */ + if ((new_min_fps > new_max_fps) || + (new_min_fps < 0) || (new_max_fps < 0)) + ret = UNKNOWN_ERROR; + } + + const char *new_flash_mode_str = params.get(CameraParameters::KEY_FLASH_MODE); + const char *new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE); + const char *new_white_str = params.get(CameraParameters::KEY_WHITE_BALANCE); + + // fps range is (15000,30000) by default. + mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)"); + mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000"); + + if ((new_scene_mode_str != NULL) && (current_scene_mode_str != NULL) && strncmp(new_scene_mode_str, current_scene_mode_str, 5)) { + int new_scene_mode = -1; + if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) { + new_scene_mode = SCENE_MODE_NONE; + } else { + // defaults for non-auto scene modes + new_focus_mode_str = CameraParameters::FOCUS_MODE_AUTO; + new_flash_mode_str = CameraParameters::FLASH_MODE_OFF; + new_white_str = CameraParameters::WHITE_BALANCE_AUTO; + mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str); + + if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_PORTRAIT)) { + new_scene_mode = SCENE_MODE_PORTRAIT; + if (mCameraID == SecCamera::CAMERA_ID_BACK) + new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_LANDSCAPE)) { + new_scene_mode = SCENE_MODE_LANDSCAPE; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SPORTS)) { + new_scene_mode = SCENE_MODE_SPORTS; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_PARTY)) { + new_scene_mode = SCENE_MODE_PARTY_INDOOR; + if (mCameraID == SecCamera::CAMERA_ID_BACK) + new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO; + } else if ((!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_BEACH)) || + (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SNOW))) { + new_scene_mode = SCENE_MODE_BEACH_SNOW; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_SUNSET)) { + new_scene_mode = SCENE_MODE_SUNSET; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_NIGHT)) { + new_scene_mode = SCENE_MODE_NIGHTSHOT; + mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(4000,30000)"); + mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "4000,30000"); + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_FIREWORKS)) { + new_scene_mode = SCENE_MODE_FIREWORKS; + } else if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_CANDLELIGHT)) { + new_scene_mode = SCENE_MODE_CANDLE_LIGHT; + } else { + LOGE("%s::unmatched scene_mode(%s)", + __func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto + ret = UNKNOWN_ERROR; + } + } + + if (0 <= new_scene_mode) { + if (mSecCamera->setSceneMode(new_scene_mode) < 0) { + LOGE("%s::mSecCamera->setSceneMode(%d) fail", __func__, new_scene_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_SCENE_MODE, new_scene_mode_str); + } + } + } + + // focus mode + /* TODO : currently only posible focus modes at BACK camera */ + if ((new_focus_mode_str != NULL) && (mCameraID == SecCamera::CAMERA_ID_BACK)) { + int new_focus_mode = -1; + + if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_AUTO)) { + new_focus_mode = FOCUS_MODE_AUTO; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR); + } else if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_MACRO)) { + new_focus_mode = FOCUS_MODE_MACRO; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR); + } else if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_INFINITY)) { + new_focus_mode = FOCUS_MODE_INFINITY; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR); + } else if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) || + !strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) { + new_focus_mode = FOCUS_MODE_CONTINOUS; + } else { + /* TODO */ + /* This is temperary implementation. + When camera support all AF mode, this code will be changing */ + LOGE("%s::unmatched focus_mode(%s)", __func__, new_focus_mode_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_focus_mode) { + if (mSecCamera->setFocusMode(new_focus_mode) < 0) { + LOGE("%s::mSecCamera->setFocusMode(%d) fail", __func__, new_focus_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_FOCUS_MODE, new_focus_mode_str); + } + } + } + + // flash.. + if (new_flash_mode_str != NULL) { + int new_flash_mode = -1; + + if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_OFF)) + new_flash_mode = FLASH_MODE_OFF; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_AUTO)) + new_flash_mode = FLASH_MODE_AUTO; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_ON)) + new_flash_mode = FLASH_MODE_ON; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_TORCH)) + new_flash_mode = FLASH_MODE_TORCH; + else { + LOGE("%s::unmatched flash_mode(%s)", __func__, new_flash_mode_str); //red-eye + ret = UNKNOWN_ERROR; + } + if (0 <= new_flash_mode) { + if (mSecCamera->setFlashMode(new_flash_mode) < 0) { + LOGE("%s::mSecCamera->setFlashMode(%d) fail", __func__, new_flash_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_FLASH_MODE, new_flash_mode_str); + } + } + } + + // whitebalance + LOGV("%s : new_white_str %s", __func__, new_white_str); + if ((new_scene_mode_str != NULL) && !strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) { + if (new_white_str != NULL) { + int new_white = -1; + + if (!strcmp(new_white_str, CameraParameters::WHITE_BALANCE_AUTO)) { + new_white = WHITE_BALANCE_AUTO; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_DAYLIGHT)) { + new_white = WHITE_BALANCE_SUNNY; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT)) { + new_white = WHITE_BALANCE_CLOUDY; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_FLUORESCENT)) { + new_white = WHITE_BALANCE_FLUORESCENT; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_INCANDESCENT)) { + new_white = WHITE_BALANCE_TUNGSTEN; + } else { + LOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); //twilight, shade, warm_flourescent + ret = UNKNOWN_ERROR; + } + + if (0 <= new_white) { + if (mSecCamera->setWhiteBalance(new_white) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str); + } + } + } + } + + const char *new_AWB_lock = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK); + const char *old_AWB_lock = mParameters.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK); + if (new_AWB_lock != NULL && mUseInternalISP && mPreviewRunning) { + if (strncmp(new_AWB_lock, old_AWB_lock, 4)) { + int awb_value = !strncmp(new_AWB_lock, "true", 4); + if (mSecCamera->setAutoWhiteBalanceLock(awb_value) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setoAutoWhiteBalanceLock()", __func__); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, new_AWB_lock); + } + } + } + + const char *new_touch_rect_str = params.get(CameraParameters::KEY_FOCUS_AREAS); + LOGV("Touched rect is '%s'", new_touch_rect_str); + + if (new_touch_rect_str != NULL) { + int left = 0, top = 0, right = 0, bottom = 0, touched = 0; + int objx, objy; + + char *end; + char delim = ','; + left = (int)strtol(new_touch_rect_str+1, &end, 10); + if (*end != delim) { + LOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str); + return -1; + } + top = (int)strtol(end+1, &end, 10); + if (*end != delim) { + LOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str); + return -1; + } + right = (int)strtol(end+1, &end, 10); + if (*end != delim) { + LOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str); + return -1; + } + bottom = (int)strtol(end+1, &end, 10); + if (*end != delim) { + LOGE("Cannot find '%c' in str=%s", delim, new_touch_rect_str); + return -1; + } + touched = (int)strtol(end+1, &end, 10); + if (*end != ')') { + LOGE("Cannot find ')' in str=%s", new_touch_rect_str); + return -1; + } + + /* TODO : Converting axis and Calcurating center of rect. Because driver need (x, y) point. */ + objx = (int)((1023 * (left + 1000)) / 2000) + 97; + objy = (int)((1023 * (top + 1000)) / 2000) + 128; + + mTouched = touched; + mSecCamera->setObjectPosition(objx, objy); + } + + // image effect + const char *new_image_effect_str = params.get(CameraParameters::KEY_EFFECT); + if (new_image_effect_str != NULL) { + + int new_image_effect = -1; + + if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NONE)) { + new_image_effect = IMAGE_EFFECT_NONE; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_MONO)) { + new_image_effect = IMAGE_EFFECT_BNW; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_SEPIA)) { + new_image_effect = IMAGE_EFFECT_SEPIA; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_AQUA)) + new_image_effect = IMAGE_EFFECT_AQUA; + else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NEGATIVE)) { + new_image_effect = IMAGE_EFFECT_NEGATIVE; + } else { + //posterize, whiteboard, blackboard, solarize + LOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str); + ret = UNKNOWN_ERROR; + } + + if (new_image_effect >= 0) { + if (mSecCamera->setImageEffect(new_image_effect) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect); + ret = UNKNOWN_ERROR; + } else { + const char *old_image_effect_str = mParameters.get(CameraParameters::KEY_EFFECT); + + if (old_image_effect_str) { + if (strcmp(old_image_effect_str, new_image_effect_str)) { + setSkipFrame(EFFECT_SKIP_FRAME); + } + } + + mParameters.set(CameraParameters::KEY_EFFECT, new_image_effect_str); + } + } + } + + //contrast + const char *new_contrast_str = params.get("contrast"); + LOGV("%s : new_contrast_str %s", __func__, new_contrast_str); + if (new_contrast_str != NULL) { + int new_contrast = -1; + + if (!strcmp(new_contrast_str, "auto")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_AUTO; + else + LOGW("WARN(%s):Invalid contrast value (%s)", __func__, new_contrast_str); + } else if (!strcmp(new_contrast_str, "-2")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_MINUS_2; + else + new_contrast = CONTRAST_MINUS_2; + } else if (!strcmp(new_contrast_str, "-1")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_MINUS_1; + else + new_contrast = CONTRAST_MINUS_1; + } else if (!strcmp(new_contrast_str, "0")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_DEFAULT; + else + new_contrast = CONTRAST_DEFAULT; + } else if (!strcmp(new_contrast_str, "1")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_PLUS_1; + else + new_contrast = CONTRAST_PLUS_1; + } else if (!strcmp(new_contrast_str, "2")) { + if (mUseInternalISP) + new_contrast = IS_CONTRAST_PLUS_2; + else + new_contrast = CONTRAST_PLUS_2; + } else { + LOGE("ERR(%s):Invalid contrast value(%s)", __func__, new_contrast_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_contrast) { + if (mSecCamera->setContrast(new_contrast) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setContrast(contrast(%d))", __func__, new_contrast); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("contrast", new_contrast_str); + } + } + } + + //WDR + int new_wdr = params.getInt("wdr"); + LOGV("%s : new_wdr %d", __func__, new_wdr); + + if (0 <= new_wdr) { + if (mSecCamera->setWDR(new_wdr) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_wdr); + ret = UNKNOWN_ERROR; + } + } + + //anti shake + int new_anti_shake = mInternalParameters.getInt("anti-shake"); + + if (0 <= new_anti_shake) { + if (mSecCamera->setAntiShake(new_anti_shake) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_anti_shake); + ret = UNKNOWN_ERROR; + } + } + + // gps latitude + const char *new_gps_latitude_str = params.get(CameraParameters::KEY_GPS_LATITUDE); + if (mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __func__, new_gps_latitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_latitude_str) { + mParameters.set(CameraParameters::KEY_GPS_LATITUDE, new_gps_latitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_LATITUDE); + } + } + + // gps longitude + const char *new_gps_longitude_str = params.get(CameraParameters::KEY_GPS_LONGITUDE); + + if (mSecCamera->setGPSLongitude(new_gps_longitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __func__, new_gps_longitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_longitude_str) { + mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, new_gps_longitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE); + } + } + + // gps altitude + const char *new_gps_altitude_str = params.get(CameraParameters::KEY_GPS_ALTITUDE); + + if (mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __func__, new_gps_altitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_altitude_str) { + mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, new_gps_altitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE); + } + } + + // gps timestamp + const char *new_gps_timestamp_str = params.get(CameraParameters::KEY_GPS_TIMESTAMP); + + if (mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) { + LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __func__, new_gps_timestamp_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_timestamp_str) { + mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, new_gps_timestamp_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP); + } + } + + // gps processing method + const char *new_gps_processing_method_str = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD); + + if (mSecCamera->setGPSProcessingMethod(new_gps_processing_method_str) < 0) { + LOGE("%s::mSecCamera->setGPSProcessingMethod(%s) fail", __func__, new_gps_processing_method_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_processing_method_str) { + mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, new_gps_processing_method_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD); + } + } + + // Recording size + /* TODO */ + /* GED application don't set different recording size before recording button is pushed */ + int new_recording_width = 0; + int new_recording_height = 0; + params.getVideoSize(&new_recording_width, &new_recording_height); + LOGV("new_recording_width (%d) new_recording_height (%d)", + new_recording_width, new_recording_height); + + int current_recording_width, current_recording_height; + mParameters.getVideoSize(¤t_recording_width, ¤t_recording_height); + LOGV("current_recording_width (%d) current_recording_height (%d)", + current_recording_width, current_recording_height); + + if (current_recording_width != new_recording_width || + current_recording_height != new_recording_height) { + if (0 < new_recording_width && 0 < new_recording_height) { + if (mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", + __func__, new_recording_width, new_recording_height); + ret = UNKNOWN_ERROR; + } + mParameters.setVideoSize(new_recording_width, new_recording_height); + } + } + + //gamma + const char *new_gamma_str = mInternalParameters.get("video_recording_gamma"); + + if (new_gamma_str != NULL) { + int new_gamma = -1; + if (!strcmp(new_gamma_str, "off")) + new_gamma = GAMMA_OFF; + else if (!strcmp(new_gamma_str, "on")) + new_gamma = GAMMA_ON; + else { + LOGE("%s::unmatched gamma(%s)", __func__, new_gamma_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_gamma) { + if (mSecCamera->setGamma(new_gamma) < 0) { + LOGE("%s::mSecCamera->setGamma(%d) fail", __func__, new_gamma); + ret = UNKNOWN_ERROR; + } + } + } + + //slow ae + const char *new_slow_ae_str = mInternalParameters.get("slow_ae"); + + if (new_slow_ae_str != NULL) { + int new_slow_ae = -1; + + if (!strcmp(new_slow_ae_str, "off")) + new_slow_ae = SLOW_AE_OFF; + else if (!strcmp(new_slow_ae_str, "on")) + new_slow_ae = SLOW_AE_ON; + else { + LOGE("%s::unmatched slow_ae(%s)", __func__, new_slow_ae_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_slow_ae) { + if (mSecCamera->setSlowAE(new_slow_ae) < 0) { + LOGE("%s::mSecCamera->setSlowAE(%d) fail", __func__, new_slow_ae); + ret = UNKNOWN_ERROR; + } + } + } + + /*Camcorder fix fps*/ + int new_sensor_mode = mInternalParameters.getInt("cam_mode"); + + if (0 <= new_sensor_mode) { + if (mSecCamera->setSensorMode(new_sensor_mode) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __func__, new_sensor_mode); + ret = UNKNOWN_ERROR; + } + } else { + new_sensor_mode=0; + } + + /*Shot mode*/ + int new_shot_mode = mInternalParameters.getInt("shot_mode"); + + if (0 <= new_shot_mode) { + if (mSecCamera->setShotMode(new_shot_mode) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __func__, new_shot_mode); + ret = UNKNOWN_ERROR; + } + } else { + new_shot_mode=0; + } + + // chk_dataline + int new_dataline = mInternalParameters.getInt("chk_dataline"); + + if (0 <= new_dataline) { + if (mSecCamera->setDataLineCheck(new_dataline) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __func__, new_dataline); + ret = UNKNOWN_ERROR; + } + } + LOGV("%s return ret = %d", __func__, ret); + + return ret; +} + +CameraParameters CameraHardwareSec::getParameters() const +{ + LOGV("%s :", __func__); + return mParameters; +} + +status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2) +{ + /* TODO */ + /* CAMERA_CMD_START_FACE_DETECTION and CAMERA_CMD_STOP_FACE_DETECTION + for Face Detection */ + if(command == CAMERA_CMD_START_FACE_DETECTION) { + if (mSecCamera->setFaceDetect(FACE_DETECTION_ON) < 0) { + LOGE("ERR(%s): Fail on mSecCamera->startFaceDetection()"); + return BAD_VALUE; + } else { + return NO_ERROR; + } + } + if(command == CAMERA_CMD_STOP_FACE_DETECTION) { + if (mSecCamera->setFaceDetect(FACE_DETECTION_OFF) < 0) { + LOGE("ERR(%s): Fail on mSecCamera->stopFaceDetection()"); + return BAD_VALUE; + } else { + return NO_ERROR; + } + } + + return BAD_VALUE; +} + +void CameraHardwareSec::release() +{ + LOGV("%s", __func__); + + /* shut down any threads we have that might be running. do it here + * instead of the destructor. we're guaranteed to be on another thread + * than the ones below. if we used the destructor, since the threads + * have a reference to this object, we could wind up trying to wait + * for ourself to exit, which is a deadlock. + */ + if (mPreviewThread != NULL) { + /* this thread is normally already in it's threadLoop but blocked + * on the condition variable or running. signal it so it wakes + * up and can exit. + */ + mPreviewThread->requestExit(); + mExitPreviewThread = true; + mPreviewRunning = true; /* let it run so it can exit */ + mPreviewCondition.signal(); + mPreviewThread->requestExitAndWait(); + mPreviewThread.clear(); + } + if (mAutoFocusThread != NULL) { + /* this thread is normally already in it's threadLoop but blocked + * on the condition variable. signal it so it wakes up and can exit. + */ + mFocusLock.lock(); + mAutoFocusThread->requestExit(); + mExitAutoFocusThread = true; + mFocusCondition.signal(); + mFocusLock.unlock(); + mAutoFocusThread->requestExitAndWait(); + mAutoFocusThread.clear(); + } + if (mPictureThread != NULL) { + mPictureThread->requestExitAndWait(); + mPictureThread.clear(); + } + + if (mRawHeap) { + mRawHeap->release(mRawHeap); + mRawHeap = 0; + } + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) { + if (mRecordHeap[i]) { + mRecordHeap[i]->release(mRecordHeap[i]); + mRecordHeap[i] = 0; + } + } + + /* close after all the heaps are cleared since those + * could have dup'd our file descriptor. + */ + mSecCamera->DestroyCamera(); +} + +static CameraInfo sCameraInfo[] = { + { + CAMERA_FACING_BACK, + 90, /* orientation */ + }, + { + CAMERA_FACING_FRONT, + 90, /* orientation */ + } +}; + +status_t CameraHardwareSec::storeMetaDataInBuffers(bool enable) +{ + // FIXME: + // metadata buffer mode can be turned on or off. + // Samsung needs to fix this. + if (!enable) { + LOGE("Non-metadata buffer mode is not supported!"); + return INVALID_OPERATION; + } + return OK; +} + +/** Close this device */ + +static camera_device_t *g_cam_device; + +static int HAL_camera_device_close(struct hw_device_t* device) +{ + LOGI("%s", __func__); + if (device) { + camera_device_t *cam_device = (camera_device_t *)device; + delete static_cast(cam_device->priv); + free(cam_device); + g_cam_device = 0; + } + return 0; +} + +static inline CameraHardwareSec *obj(struct camera_device *dev) +{ + return reinterpret_cast(dev->priv); +} + +/** Set the preview_stream_ops to which preview frames are sent */ +static int HAL_camera_device_set_preview_window(struct camera_device *dev, + struct preview_stream_ops *buf) +{ + LOGV("%s", __func__); + return obj(dev)->setPreviewWindow(buf); +} + +/** Set the notification and data callbacks */ +static void HAL_camera_device_set_callbacks(struct camera_device *dev, + camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void* user) +{ + LOGV("%s", __func__); + obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp, + get_memory, + user); +} + +/** + * The following three functions all take a msg_type, which is a bitmask of + * the messages defined in include/ui/Camera.h + */ + +/** + * Enable a message, or set of messages. + */ +static void HAL_camera_device_enable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + obj(dev)->enableMsgType(msg_type); +} + +/** + * Disable a message, or a set of messages. + * + * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera + * HAL should not rely on its client to call releaseRecordingFrame() to + * release video recording frames sent out by the cameral HAL before and + * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL + * clients must not modify/access any video recording frame after calling + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). + */ +static void HAL_camera_device_disable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + obj(dev)->disableMsgType(msg_type); +} + +/** + * Query whether a message, or a set of messages, is enabled. Note that + * this is operates as an AND, if any of the messages queried are off, this + * will return false. + */ +static int HAL_camera_device_msg_type_enabled(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + return obj(dev)->msgTypeEnabled(msg_type); +} + +/** + * Start preview mode. + */ +static int HAL_camera_device_start_preview(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->startPreview(); +} + +/** + * Stop a previously started preview. + */ +static void HAL_camera_device_stop_preview(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->stopPreview(); +} + +/** + * Returns true if preview is enabled. + */ +static int HAL_camera_device_preview_enabled(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->previewEnabled(); +} + +/** + * Request the camera HAL to store meta data or real YUV data in the video + * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If + * it is not called, the default camera HAL behavior is to store real YUV + * data in the video buffers. + * + * This method should be called before startRecording() in order to be + * effective. + * + * If meta data is stored in the video buffers, it is up to the receiver of + * the video buffers to interpret the contents and to find the actual frame + * data with the help of the meta data in the buffer. How this is done is + * outside of the scope of this method. + * + * Some camera HALs may not support storing meta data in the video buffers, + * but all camera HALs should support storing real YUV data in the video + * buffers. If the camera HAL does not support storing the meta data in the + * video buffers when it is requested to do do, INVALID_OPERATION must be + * returned. It is very useful for the camera HAL to pass meta data rather + * than the actual frame data directly to the video encoder, since the + * amount of the uncompressed frame data can be very large if video size is + * large. + * + * @param enable if true to instruct the camera HAL to store + * meta data in the video buffers; false to instruct + * the camera HAL to store real YUV data in the video + * buffers. + * + * @return OK on success. + */ +static int HAL_camera_device_store_meta_data_in_buffers(struct camera_device *dev, int enable) +{ + LOGV("%s", __func__); + return obj(dev)->storeMetaDataInBuffers(enable); +} + +/** + * Start record mode. When a record image is available, a + * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding + * frame. Every record frame must be released by a camera HAL client via + * releaseRecordingFrame() before the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames, + * and the client must not modify/access any video recording frames. + */ +static int HAL_camera_device_start_recording(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->startRecording(); +} + +/** + * Stop a previously started recording. + */ +static void HAL_camera_device_stop_recording(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->stopRecording(); +} + +/** + * Returns true if recording is enabled. + */ +static int HAL_camera_device_recording_enabled(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->recordingEnabled(); +} + +/** + * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. + * + * It is camera HAL client's responsibility to release video recording + * frames sent out by the camera HAL before the camera HAL receives a call + * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames. + */ +static void HAL_camera_device_release_recording_frame(struct camera_device *dev, + const void *opaque) +{ + LOGV("%s", __func__); + obj(dev)->releaseRecordingFrame(opaque); +} + +/** + * Start auto focus, the notification callback routine is called with + * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be + * called again if another auto focus is needed. + */ +static int HAL_camera_device_auto_focus(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->autoFocus(); +} + +/** + * Cancels auto-focus function. If the auto-focus is still in progress, + * this function will cancel it. Whether the auto-focus is in progress or + * not, this function will return the focus position to the default. If + * the camera does not support auto-focus, this is a no-op. + */ +static int HAL_camera_device_cancel_auto_focus(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->cancelAutoFocus(); +} + +/** + * Take a picture. + */ +static int HAL_camera_device_take_picture(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->takePicture(); +} + +/** + * Cancel a picture that was started with takePicture. Calling this method + * when no picture is being taken is a no-op. + */ +static int HAL_camera_device_cancel_picture(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->cancelPicture(); +} + +/** + * Set the camera parameters. This returns BAD_VALUE if any parameter is + * invalid or not supported. + */ +static int HAL_camera_device_set_parameters(struct camera_device *dev, + const char *parms) +{ + LOGV("%s", __func__); + String8 str(parms); + CameraParameters p(str); + return obj(dev)->setParameters(p); +} + +/** Return the camera parameters. */ +char *HAL_camera_device_get_parameters(struct camera_device *dev) +{ + LOGV("%s", __func__); + String8 str; + CameraParameters parms = obj(dev)->getParameters(); + str = parms.flatten(); + return strdup(str.string()); +} + +static void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms) +{ + LOGV("%s", __func__); + free(parms); +} + +/** + * Send command to camera driver. + */ +static int HAL_camera_device_send_command(struct camera_device *dev, + int32_t cmd, int32_t arg1, int32_t arg2) +{ + LOGV("%s", __func__); + return obj(dev)->sendCommand(cmd, arg1, arg2); +} + +/** + * Release the hardware resources owned by this object. Note that this is + * *not* done in the destructor. + */ +static void HAL_camera_device_release(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->release(); +} + +/** + * Dump state of the camera hardware + */ +static int HAL_camera_device_dump(struct camera_device *dev, int fd) +{ + LOGV("%s", __func__); + return obj(dev)->dump(fd); +} + +static int HAL_getNumberOfCameras() +{ + LOGV("%s", __func__); + + int cam_fd; + static struct v4l2_input input; + + cam_fd = open(CAMERA_DEV_NAME, O_RDONLY); + if (cam_fd < 0) { + LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, CAMERA_DEV_NAME, strerror(errno)); + return -1; + } + + input.index = 0; + while (ioctl(cam_fd, VIDIOC_ENUMINPUT, &input) == 0) { + LOGI("Name of input channel[%d] is %s", input.index, input.name); + input.index++; + } + + close(cam_fd); + + return --input.index; +} + +static int HAL_getCameraInfo(int cameraId, struct camera_info *cameraInfo) +{ + LOGV("%s", __func__); + memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo)); + return 0; +} + +#define SET_METHOD(m) m : HAL_camera_device_##m + +static camera_device_ops_t camera_device_ops = { + SET_METHOD(set_preview_window), + SET_METHOD(set_callbacks), + SET_METHOD(enable_msg_type), + SET_METHOD(disable_msg_type), + SET_METHOD(msg_type_enabled), + SET_METHOD(start_preview), + SET_METHOD(stop_preview), + SET_METHOD(preview_enabled), + SET_METHOD(store_meta_data_in_buffers), + SET_METHOD(start_recording), + SET_METHOD(stop_recording), + SET_METHOD(recording_enabled), + SET_METHOD(release_recording_frame), + SET_METHOD(auto_focus), + SET_METHOD(cancel_auto_focus), + SET_METHOD(take_picture), + SET_METHOD(cancel_picture), + SET_METHOD(set_parameters), + SET_METHOD(get_parameters), + SET_METHOD(put_parameters), + SET_METHOD(send_command), + SET_METHOD(release), + SET_METHOD(dump), +}; + +#undef SET_METHOD + +static int HAL_camera_device_open(const struct hw_module_t* module, + const char *id, + struct hw_device_t** device) +{ + LOGV("%s", __func__); + + int cameraId = atoi(id); + if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) { + LOGE("Invalid camera ID %s", id); + return -EINVAL; + } + + if (g_cam_device) { + if (obj(g_cam_device)->getCameraId() == cameraId) { + LOGV("returning existing camera ID %s", id); + goto done; + } else { + LOGE("Cannot open camera %d. camera %d is already running!", + cameraId, obj(g_cam_device)->getCameraId()); + return -ENOSYS; + } + } + + g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t)); + if (!g_cam_device) + return -ENOMEM; + + g_cam_device->common.tag = HARDWARE_DEVICE_TAG; + g_cam_device->common.version = 1; + g_cam_device->common.module = const_cast(module); + g_cam_device->common.close = HAL_camera_device_close; + + g_cam_device->ops = &camera_device_ops; + + LOGI("%s: open camera %s", __func__, id); + + g_cam_device->priv = new CameraHardwareSec(cameraId, g_cam_device); + +done: + *device = (hw_device_t *)g_cam_device; + LOGI("%s: opened camera %s (%p)", __func__, id, *device); + return 0; +} + +static hw_module_methods_t camera_module_methods = { + open : HAL_camera_device_open +}; + +extern "C" { + struct camera_module HAL_MODULE_INFO_SYM = { + common : { + tag : HARDWARE_MODULE_TAG, + version_major : 1, + version_minor : 0, + id : CAMERA_HARDWARE_MODULE_ID, + name : "orion camera HAL", + author : "Samsung Corporation", + methods : &camera_module_methods, + }, + get_number_of_cameras : HAL_getNumberOfCameras, + get_camera_info : HAL_getCameraInfo + }; +} + +}; // namespace android diff --git a/exynos4/hal/libcamera/SecCameraHWInterface.h b/exynos4/hal/libcamera/SecCameraHWInterface.h new file mode 100644 index 0000000..321eb15 --- /dev/null +++ b/exynos4/hal/libcamera/SecCameraHWInterface.h @@ -0,0 +1,242 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H +#define ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H + +#include "SecCamera.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef BOARD_USE_V4L2_ION +#include +#include "gralloc_priv.h" + +#define BUFFER_COUNT_FOR_GRALLOC (MAX_BUFFERS + 4) +#define BUFFER_COUNT_FOR_ARRAY (MAX_BUFFERS) +#else +#define BUFFER_COUNT_FOR_GRALLOC (MAX_BUFFERS) +#define BUFFER_COUNT_FOR_ARRAY (1) +#endif + +namespace android { + class CameraHardwareSec : public virtual RefBase { +public: + virtual void setCallbacks(camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user); + + virtual void enableMsgType(int32_t msgType); + virtual void disableMsgType(int32_t msgType); + virtual bool msgTypeEnabled(int32_t msgType); + + virtual status_t startPreview(); + virtual void stopPreview(); + virtual bool previewEnabled(); + + virtual status_t startRecording(); + virtual void stopRecording(); + virtual bool recordingEnabled(); + virtual void releaseRecordingFrame(const void *opaque); + + virtual status_t autoFocus(); + virtual status_t cancelAutoFocus(); + virtual status_t takePicture(); + virtual status_t cancelPicture(); + virtual status_t dump(int fd) const; + virtual status_t setParameters(const CameraParameters& params); + virtual CameraParameters getParameters() const; + virtual status_t sendCommand(int32_t command, int32_t arg1, int32_t arg2); + virtual status_t setPreviewWindow(preview_stream_ops *w); + virtual status_t storeMetaDataInBuffers(bool enable); + virtual void release(); + + inline int getCameraId() const; + + CameraHardwareSec(int cameraId, camera_device_t *dev); + virtual ~CameraHardwareSec(); +private: + status_t startPreviewInternal(); + void stopPreviewInternal(); + + class PreviewThread : public Thread { + CameraHardwareSec *mHardware; + public: + PreviewThread(CameraHardwareSec *hw): + Thread(false), + mHardware(hw) { } + virtual void onFirstRef() { + run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + mHardware->previewThreadWrapper(); + return false; + } + }; + + class PictureThread : public Thread { + CameraHardwareSec *mHardware; + public: + PictureThread(CameraHardwareSec *hw): + Thread(false), + mHardware(hw) { } + virtual bool threadLoop() { + mHardware->pictureThread(); + return false; + } + }; + + class AutoFocusThread : public Thread { + CameraHardwareSec *mHardware; + public: + AutoFocusThread(CameraHardwareSec *hw): Thread(false), mHardware(hw) { } + virtual void onFirstRef() { + run("CameraAutoFocusThread", PRIORITY_DEFAULT); + } + virtual bool threadLoop() { + mHardware->autoFocusThread(); + return true; + } + }; + + void initDefaultParameters(int cameraId); + void initHeapLocked(); + + sp mPreviewThread; + int previewThread(); + int previewThreadWrapper(); + + sp mAutoFocusThread; + int autoFocusThread(); + + sp mPictureThread; + int pictureThread(); + bool mCaptureInProgress; + + int save_jpeg(unsigned char *real_jpeg, int jpeg_size); + void save_postview(const char *fname, uint8_t *buf, + uint32_t size); + int decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData); + bool YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight); + bool scaleDownYuv422(char *srcBuf, uint32_t srcWidth, + uint32_t srcHight, char *dstBuf, + uint32_t dstWidth, uint32_t dstHight); + + bool CheckVideoStartMarker(unsigned char *pBuf); + bool CheckEOIMarker(unsigned char *pBuf); + bool FindEOIMarkerInJPEG(unsigned char *pBuf, + int dwBufSize, int *pnJPEGsize); + bool SplitFrame(unsigned char *pFrame, int dwSize, + int dwJPEGLineLength, int dwVideoLineLength, + int dwVideoHeight, void *pJPEG, + int *pdwJPEGSize, void *pVideo, + int *pdwVideoSize); + void setSkipFrame(int frame); + bool isSupportedPreviewSize(const int width, + const int height) const; + bool getVideosnapshotSize(int *width, int *height); + /* used by auto focus thread to block until it's told to run */ + mutable Mutex mFocusLock; + mutable Condition mFocusCondition; + bool mExitAutoFocusThread; + int mTouched; + + /* used by preview thread to block until it's told to run */ + mutable Mutex mPreviewLock; + mutable Condition mPreviewCondition; + mutable Condition mPreviewStoppedCondition; + bool mPreviewRunning; + bool mPreviewStartDeferred; + bool mExitPreviewThread; + + preview_stream_ops *mPreviewWindow; + + /* used to guard threading state */ + mutable Mutex mStateLock; + + enum PREVIEW_FMT { + PREVIEW_FMT_1_PLANE = 0, + PREVIEW_FMT_2_PLANE, + PREVIEW_FMT_3_PLANE, + }; + + int mPreviewFmtPlane; + + CameraParameters mParameters; + CameraParameters mInternalParameters; + + int mFrameSizeDelta; + camera_memory_t *mPreviewHeap; + camera_memory_t *mRawHeap; + sp mPostviewHeap[CAP_BUFFERS]; + sp mThumbnailHeap; + camera_memory_t *mRecordHeap[BUFFER_COUNT_FOR_ARRAY]; + + camera_frame_metadata_t *mFaceData; + camera_memory_t *mFaceDataHeap; + + buffer_handle_t *mBufferHandle[BUFFER_COUNT_FOR_ARRAY]; + int mStride[BUFFER_COUNT_FOR_ARRAY]; + + + SecCamera *mSecCamera; + const __u8 *mCameraSensorName; + bool mUseInternalISP; + + mutable Mutex mSkipFrameLock; + int mSkipFrame; + + camera_notify_callback mNotifyCb; + camera_data_callback mDataCb; + camera_data_timestamp_callback mDataCbTimestamp; + camera_request_memory mGetMemoryCb; + void *mCallbackCookie; + + int32_t mMsgEnabled; + + bool mRecordRunning; + bool mRecordHint; + mutable Mutex mRecordLock; + int mPostViewWidth; + int mPostViewHeight; + int mPostViewSize; + struct SecBuffer mCapBuffer; + int mCapIndex; + int mCameraID; + + Vector mSupportedPreviewSizes; + + camera_device_t *mHalDevice; + static gralloc_module_t const* mGrallocHal; +}; + +}; // namespace android + +#endif diff --git a/exynos4/hal/libfimc/Android.mk b/exynos4/hal/libfimc/Android.mk new file mode 100644 index 0000000..624d39e --- /dev/null +++ b/exynos4/hal/libfimc/Android.mk @@ -0,0 +1,55 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog libutils libcutils +ifeq ($(BOARD_SUPPORT_SYSMMU),true) +LOCAL_SHARED_LIBRARIES+= libMali +endif + +ifeq ($(BOARD_SUPPORT_SYSMMU),true) +LOCAL_CFLAGS+=-DBOARD_SUPPORT_SYSMMU +endif + +ifeq ($(TARGET_SOC),exynos4210) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +ifeq ($(BOARD_USE_V4L2),true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +LOCAL_CFLAGS += \ + -DDEFAULT_FB_NUM=$(DEFAULT_FB_NUM) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include \ + framework/base/include + +LOCAL_SRC_FILES := SecFimc.cpp + +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE := libfimc +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libfimc/SecFimc.cpp b/exynos4/hal/libfimc/SecFimc.cpp new file mode 100644 index 0000000..ab744a2 --- /dev/null +++ b/exynos4/hal/libfimc/SecFimc.cpp @@ -0,0 +1,1701 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + * \file SecFimc.cpp + * \brief source file for Fimc HAL MODULE + * \author Hyunkyung, Kim(hk310.kim@samsung.com) + * \date 2010/10/13 + * + * Revision History: + * - 2010/10/13 : Hyunkyung, Kim(hk310.kim@samsung.com) \n + * Initial version + * + * - 2011/11/15 : Sunmi, Lee(carrotsm.lee@samsung.com) \n + * Adjust V4L2 architecture \n + */ + +#define LOG_TAG "libfimc" +#include + +#include "SecFimc.h" + +#define FIMC2_DEV_NAME "/dev/video2" + +//#define DEBUG_LIB_FIMC + +#ifdef BOARD_USE_V4L2 +#define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE +#define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE +#define V4L2_ROTATE V4L2_CID_ROTATE +#else +#define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT +#define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE +#define V4L2_ROTATE V4L2_CID_ROTATION +#endif + +#define V4L2_BUF_TYPE_SRC V4L2_BUF_TYPE_OUTPUT +#define V4L2_MEMORY_TYPE_SRC V4L2_MEMORY_USERPTR +#ifdef BOARD_USE_V4L2 +#define V4L2_BUF_TYPE_DST V4L2_BUF_TYPE_CAPTURE +#define V4L2_MEMORY_TYPE_DST V4L2_MEMORY_MMAP +#else +#define V4L2_BUF_TYPE_DST V4L2_BUF_TYPE_VIDEO_OVERLAY +#define V4L2_MEMORY_TYPE_DST V4L2_MEMORY_USERPTR +#endif + +struct yuv_fmt_list yuv_list[] = { + { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 2 }, +#ifdef BOARD_USE_V4L2 + { "V4L2_PIX_FMT_NV12M", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12M, 12, 2 }, + { "V4L2_PIX_FMT_NV12MT", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12MT, 12, 2 }, +#endif + { "V4L2_PIX_FMT_NV12T", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12T, 12, 2 }, + { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 2 }, + { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 }, + { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 }, +#ifdef BOARD_USE_V4L2 + { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 }, +#endif + { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 }, + { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 }, + { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 }, + { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 }, + { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 }, + { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 }, + { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 }, + { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 }, + { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 }, + { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 }, +}; + +#ifdef BOARD_USE_V4L2 +void dump_pixfmt_mp(struct v4l2_pix_format_mplane *pix_mp) +{ + LOGI("w: %d", pix_mp->width); + LOGI("h: %d", pix_mp->height); + LOGI("color: %x", pix_mp->colorspace); + + switch (pix_mp->pixelformat) { + case V4L2_PIX_FMT_YUYV: + LOGI ("YUYV"); + break; + case V4L2_PIX_FMT_UYVY: + LOGI ("UYVY"); + break; + case V4L2_PIX_FMT_RGB565: + LOGI ("RGB565"); + break; + case V4L2_PIX_FMT_RGB565X: + LOGI ("RGB565X"); + break; + default: + LOGI("not supported"); + } +} +#endif + +void dump_pixfmt(struct v4l2_pix_format *pix) +{ + LOGI("w: %d", pix->width); + LOGI("h: %d", pix->height); + LOGI("color: %x", pix->colorspace); + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + LOGI ("YUYV"); + break; + case V4L2_PIX_FMT_UYVY: + LOGI ("UYVY"); + break; + case V4L2_PIX_FMT_RGB565: + LOGI ("RGB565"); + break; + case V4L2_PIX_FMT_RGB565X: + LOGI ("RGB565X"); + break; + default: + LOGI("not supported"); + } +} + +void dump_crop(struct v4l2_crop *crop) +{ + LOGI("crop l: %d", crop->c.left); + LOGI("crop t: %d", crop->c.top); + LOGI("crop w: %d", crop->c.width); + LOGI("crop h: %d", crop->c.height); +} + +void dump_window(struct v4l2_window *win) +{ + LOGI("window l: %d", win->w.left); + LOGI("window t: %d", win->w.top); + LOGI("window w: %d", win->w.width); + LOGI("window h: %d", win->w.height); +} + +void v4l2_overlay_dump_state(int fd) +{ + struct v4l2_format format; + struct v4l2_crop crop; + + format.type = V4L2_BUF_TYPE_OUTPUT; + if (ioctl(fd, VIDIOC_G_FMT, &format) < 0) + return; + + LOGI("dumping driver state:"); +#ifdef BOARD_USE_V4L2 + dump_pixfmt_mp(&format.fmt.pix_mp); +#else + dump_pixfmt(&format.fmt.pix); +#endif + + crop.type = format.type; + if (ioctl(fd, VIDIOC_G_CROP, &crop) < 0) + return; + + LOGI("input window(crop):"); + dump_crop(&crop); + + crop.type = V4L2_BUF_TYPE_CAPTURE; + if (ioctl(fd, VIDIOC_G_CROP, &crop) < 0) + return; + + LOGI("output crop:"); + dump_crop(&crop); + +} + +int fimc_v4l2_query_buf(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_plane) +{ + struct v4l2_buffer buf; + memset(&buf, 0, sizeof(struct v4l2_buffer)); + +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[MAX_PLANES]; + for (int i = 0; i < MAX_PLANES; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); +#endif + + if (MAX_DST_BUFFERS <= buf_index || MAX_PLANES <= num_plane) { + LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_plane); + return -1; + } + + buf.type = type; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_index; +#ifdef BOARD_USE_V4L2 + buf.m.planes = planes; + buf.length = num_plane; +#endif + + if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length); + return -1; + } + +#ifdef BOARD_USE_V4L2 + for (int i = 0; i < num_plane; i++) { + secBuf->phys.extP[i] = (unsigned int)buf.m.planes[i].cookie; + secBuf->size.extS[i] = buf.m.planes[i].length; + + if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) { + LOGE("%s::mmap failed", __func__); + LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset); + LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length); + LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + LOGE("%s::paddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->phys.extP[i]); + return -1; + } + } +#else + secBuf->size.s = buf.length; + + if ((secBuf->virt.p = (char *)mmap(0, buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset)) < 0) { + LOGE("%s::mmap failed", __func__); + return -1; + } + LOGI("%s::buffers[%d] vaddr = 0x%x", __func__, buf_index, (unsigned int)secBuf->virt.p); +#endif + + return 0; +} + +int fimc_v4l2_req_buf(int fd, unsigned int num_bufs, enum v4l2_buf_type type, enum v4l2_memory memory) +{ + struct v4l2_requestbuffers reqbuf; + + reqbuf.type = type; + reqbuf.memory = memory; + reqbuf.count = num_bufs; + + if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { + LOGE("%s::VIDIOC_REQBUFS failed", __func__); + return -1; + } + +#ifdef DEBUG_LIB_FIMC + LOGI("%d buffers allocated %d requested", reqbuf.count, 4); +#endif + + if (reqbuf.count < num_bufs) { + LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))", + __func__, reqbuf.count, num_bufs); + return -1; + } + + return 0; +} + +int fimc_v4l2_s_ctrl(int fd, int id, int value) +{ + struct v4l2_control vc; + vc.id = id; + vc.value = value; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value); + return -1; + } + + return 0; +} + +int fimc_v4l2_set_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, s5p_fimc_img_info *img_info, unsigned int addr) +{ + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + struct v4l2_crop crop; + struct fimc_buf fimc_dst_buf; + struct v4l2_control vc; + + fmt.type = type; + if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + return -1; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + fmt.fmt.pix.width = img_info->full_width; + fmt.fmt.pix.height = img_info->full_height; + fmt.fmt.pix.pixelformat = img_info->color_space; + fmt.fmt.pix.field = field; + break; +#ifdef BOARD_USE_V4L2 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt.fmt.pix_mp.width = img_info->full_width; + fmt.fmt.pix_mp.height = img_info->full_height; + fmt.fmt.pix_mp.pixelformat = img_info->color_space; + fmt.fmt.pix_mp.field = field; + fmt.fmt.pix_mp.num_planes = img_info->planes; + break; +#endif + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (ioctl(fd, VIDIOC_G_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_G_FBUF failed", __func__); + return -1; + } + + fbuf.base = (void *)addr; + fbuf.fmt.width = img_info->full_width; + fbuf.fmt.height = img_info->full_height; + fbuf.fmt.pixelformat = img_info->color_space; + + if (ioctl(fd, VIDIOC_S_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_S_FBUF (w=%d, h=%d, color=%d) failed", + __func__, + img_info->full_width, + img_info->full_height, + img_info->color_space); + return -1; + } + + fimc_dst_buf.base[0] = (unsigned int)img_info->buf_addr_phy_rgb_y; + fimc_dst_buf.base[1] = (unsigned int)img_info->buf_addr_phy_cb; + fimc_dst_buf.base[2] = (unsigned int)img_info->buf_addr_phy_cr; + + vc.id = V4L2_CID_DST_INFO; + vc.value = (unsigned int)&fimc_dst_buf.base[0]; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, vc.id, vc.value); + return -1; + } + + fmt.fmt.win.w.left = img_info->start_x; + fmt.fmt.win.w.top = img_info->start_y; + fmt.fmt.win.w.width = img_info->width; + fmt.fmt.win.w.height = img_info->height; + break; + default: + LOGE("invalid buffer type"); + return -1; + break; + } + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_S_FMT failed", __func__); + return -1; + } + + if (fmt.type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + crop.type = type; + crop.c.left = img_info->start_x; + crop.c.top = img_info->start_y; + crop.c.width = img_info->width; + crop.c.height = img_info->height; + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed", + __func__, + img_info->start_x, + img_info->start_y, + img_info->width, + img_info->height); + return -1; + } + } + + return 0; +} + +int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type) +{ + if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { + LOGE("%s::VIDIOC_STREAMON failed", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_queue(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, int index, int num_plane) +{ + struct v4l2_buffer buf; + memset(&buf, 0, sizeof(struct v4l2_buffer)); + +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[MAX_PLANES]; + for (int i = 0; i < MAX_PLANES; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); +#else + struct fimc_buf fimcbuf; +#endif + + buf.type = type; + buf.memory = memory; + buf.length = num_plane; + buf.index = index; +#ifdef BOARD_USE_V4L2 + buf.m.planes = planes; + + for (unsigned int i = 0; i < buf.length; i++) { + buf.m.planes[i].length = secBuf->size.extS[i]; + buf.m.planes[i].m.userptr = (unsigned long)secBuf->phys.extP[i]; + } +#else + for (int i = 0; i < 3 ; i++) { + fimcbuf.base[i] = secBuf->phys.extP[i]; + fimcbuf.length[i] = secBuf->size.extS[i]; + } + + buf.m.userptr = (unsigned long)(&fimcbuf); + //buf.m.userptr = secBuf->phys.p; +#endif + + if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QBUF failed", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_dequeue(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *index, int num_plane) +{ + struct v4l2_buffer buf; + memset(&buf, 0, sizeof(struct v4l2_buffer)); + +#ifdef BOARD_USE_V4L2 + struct v4l2_plane planes[MAX_PLANES]; + for (int i = 0; i < MAX_PLANES; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); +#endif + + buf.type = type; + buf.memory = memory; + buf.length = num_plane; +#ifdef BOARD_USE_V4L2 + buf.m.planes = planes; +#endif + if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { + LOGE("%s::VIDIOC_DQBUF failed", __func__); + return -1; + } + *index = buf.index; + + return 0; +} + +int fimc_v4l2_stream_off(int fd, enum v4l2_buf_type type) +{ + if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { + LOGE("%s::VIDIOC_STREAMOFF failed", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_clr_buf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory) +{ + struct v4l2_requestbuffers req; + + req.count = 0; + req.type = type; + req.memory = memory; + + if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { + LOGE("%s::VIDIOC_REQBUFS", __func__); + return -1; + } + + return 0; +} + +static inline int multipleOfN(int number, int N) +{ + int result = number; + switch (N) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + result = (number - (number & (N-1))); + break; + default: + result = number - (number % N); + break; + } + return result; +} + +extern "C" SecFimc* create_instance() +{ + return new SecFimc; +} + +extern "C" void destroy_instance(SecFimc* handle) +{ + if (handle != NULL) + delete handle; +} + +SecFimc::SecFimc() +: mFlagCreate(false) +{ + memset(&mFimcCap, 0, sizeof(struct v4l2_capability)); + memset(&mS5pFimc, 0, sizeof(s5p_fimc_t)); + + mRotVal = 0; + mRealDev = -1; + mNumOfBuf = 0; + mHwVersion = 0; + mGlobalAlpha = 0x0; + mFlagStreamOn = false; + mFlagSetSrcParam = false; + mFlagSetDstParam = false; + mFlagGlobalAlpha = false; + mFlagLocalAlpha = false; + mFlagColorKey = false; + mFimcMode = 0; + mFd = 0; + mDev = 0; + mColorKey = 0x0; +} + +SecFimc::~SecFimc() +{ + if (mFlagCreate == true) { + LOGE("%s::this is not Destroyed fail", __func__); + if (destroy() == false) + LOGE("%s::destroy failed", __func__); + } +} + +bool SecFimc::create(enum DEV dev, enum MODE mode, int numOfBuf) +{ + if (mFlagCreate == true) { + LOGE("%s::Already Created fail", __func__); + return false; + } + + char node[20]; + struct v4l2_format fmt; + struct v4l2_control vc; + SecBuffer zeroBuf; + + mDev = dev; + mRealDev = dev; + + switch (mode) { + case MODE_SINGLE_BUF: + mFimcMode = FIMC_OVLY_NONE_SINGLE_BUF; + break; + case MODE_MULTI_BUF: + mFimcMode = FIMC_OVLY_NONE_MULTI_BUF; + break; + case MODE_DMA_AUTO: + mFimcMode = FIMC_OVLY_DMA_AUTO; + break; + default: + LOGE("%s::Invalid mode(%d) fail", __func__, mode); + mFimcMode = FIMC_OVLY_NOT_FIXED; + goto err; + break; + } + + mNumOfBuf = numOfBuf; + + for (int i = 0; i < MAX_DST_BUFFERS; i++) + mDstBuffer[i] = zeroBuf; + +#ifdef BOARD_USE_V4L2 + switch(mDev) { + case DEV_0: + mRealDev = 0; + break; + case DEV_1: + mRealDev = 2; + break; + case DEV_2: + mRealDev = 4; + break; + case DEV_3: + mRealDev = 5; + break; + default: + LOGE("%s::invalid mDev(%d)", __func__, mDev); + goto err; + break; + } +#endif + + sprintf(node, "%s%d", PFX_NODE_FIMC, (int)mRealDev); + + mFd = open(node, O_RDWR); + if (mFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + mFd = 0; + goto err; + } + + /* check capability */ + if (ioctl(mFd, VIDIOC_QUERYCAP, &mFimcCap) < 0) { + LOGE("%s::VIDIOC_QUERYCAP failed", __func__); + goto err; + } + + if (!(mFimcCap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("%s::%s has no streaming support", __func__, node); + goto err; + } + +#ifdef BOARD_USE_V4L2 + if (!(mFimcCap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) { + LOGE("%s::%s is no video output mplane", __func__, node); + goto err; + } + + if (!(mFimcCap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) { + LOGE("%s::%s is no video capture mplane", __func__, node); + goto err; + } +#else + if (!(mFimcCap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + LOGE("%s::%s is no video output", __func__, node); + goto err; + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + if (ioctl(mFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + goto err; + } + + vc.id = V4L2_CID_RESERVED_MEM_BASE_ADDR; + vc.value = 0; + if (ioctl(mFd, VIDIOC_G_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_G_CTRL - V4L2_CID_RESERVED_MEM_BAES_ADDR", __func__); + goto err; + } + + mDstBuffer[0].phys.p = (unsigned int)vc.value; + + mS5pFimc.out_buf.phys_addr = (void *)mDstBuffer[0].phys.p; + + vc.id = V4L2_CID_FIMC_VERSION; + vc.value = 0; + if (ioctl(mFd, VIDIOC_G_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_G_CTRL - V4L2_CID_FIMC_VERSION failed, FIMC version is set with default", __func__); + vc.value = 0x43; + } + + mHwVersion = vc.value; + + vc.id = V4L2_CID_OVLY_MODE; + vc.value = mFimcMode; + if (ioctl(mFd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL - V4L2_CID_OVLY_MODE failed", __func__); + goto err; + } +#endif + + mFlagCreate = true; + + return true; + +err : + if (0 < mFd) + close(mFd); + mFd = 0; + + return false; +} + +bool SecFimc::destroy() +{ + s5p_fimc_params_t *params = &(mS5pFimc.params); + + if (mFlagCreate == false) { + LOGE("%s::Already Destroyed fail", __func__); + return false; + } + + if (mFlagStreamOn == true) { + if (fimc_v4l2_stream_off(mFd, V4L2_BUF_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_stream_off() failed", __func__); + return false; + } +#ifdef BOARD_USE_V4L2 + if (fimc_v4l2_stream_off(mFd, V4L2_BUF_TYPE_DST) < 0) { + LOGE("%s::fimc_v4l2_stream_off() failed", __func__); + return false; + } +#endif + mFlagStreamOn = false; + } + + if (fimc_v4l2_clr_buf(mFd, V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_clr_buf()[src] failed", __func__); + return false; + } + +#ifdef BOARD_USE_V4L2 + if (fimc_v4l2_clr_buf(mFd, V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST) < 0) { + LOGE("%s::fimc_v4l2_clr_buf()[dst] failed", __func__); + return false; + } +#endif + if (mS5pFimc.out_buf.phys_addr != NULL) { + mS5pFimc.out_buf.phys_addr = NULL; + mS5pFimc.out_buf.length = 0; + } + + if (0 < mFd) + close(mFd); + mFd = 0; + + mFlagCreate = false; + + return true; +} + +bool SecFimc::flagCreate(void) +{ + return mFlagCreate; +} + +int SecFimc::getFd(void) +{ + return mFd; +} + +SecBuffer * SecFimc::getMemAddr(int index) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + return &mDstBuffer[index]; +} + +int SecFimc::getHWVersion(void) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + return mHwVersion; +} + +bool SecFimc::setSrcParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(colorFormat); + if (v4l2ColorFormat < 0) { + LOGE("%s::not supported color format", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + + unsigned int fimcWidth = *cropWidth; + unsigned int fimcHeight = *cropHeight; + int src_planes = m_getYuvPlanes(v4l2ColorFormat); + + m_checkSrcSize(width, height, + cropX, cropY, + &fimcWidth, &fimcHeight, + v4l2ColorFormat, + false); + + if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) { + if (forceChange == true) { +#ifdef DEBUG_LIB_FIMC + LOGD("size is changed from [w = %d, h= %d] to [w = %d, h = %d]", + *cropWidth, *cropHeight, fimcWidth, fimcHeight); +#endif + } else { + LOGE("%s::invalid source params", __func__); + return false; + } + } + + if ( (params->src.full_width == width) + && (params->src.full_height == height) + && (params->src.start_x == cropX) + && (params->src.start_y == cropY) + && (params->src.width == fimcWidth) + && (params->src.height == fimcHeight) + && (params->src.color_space == (unsigned int)v4l2ColorFormat)) + return true; + + params->src.full_width = width; + params->src.full_height = height; + params->src.start_x = cropX; + params->src.start_y = cropY; + params->src.width = fimcWidth; + params->src.height = fimcHeight; + params->src.color_space = v4l2ColorFormat; + src_planes = (src_planes == -1) ? 1 : src_planes; + + if (mFlagSetSrcParam == true) { + if (fimc_v4l2_clr_buf(mFd, V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_clr_buf_src() failed", __func__); + return false; + } + } + + if (fimc_v4l2_set_fmt(mFd, V4L2_BUF_TYPE_SRC, V4L2_FIELD_NONE, &(params->src), 0) < 0) { + LOGE("%s::fimc_v4l2_set_fmt()[src] failed", __func__); + return false; + } + + if (fimc_v4l2_req_buf(mFd, 1, V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_req_buf()[src] failed", __func__); + return false; + } + + *cropWidth = fimcWidth; + *cropHeight = fimcHeight; + + mFlagSetSrcParam = true; + return true; +} + +bool SecFimc::getSrcParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *colorFormat) +{ + struct v4l2_format fmt; + struct v4l2_crop crop; + + fmt.type = V4L2_BUF_TYPE_SRC; + + if (ioctl(mFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT(fmt.type : %d) failed", __func__, fmt.type); + return false; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + *width = fmt.fmt.pix.width; + *height = fmt.fmt.pix.height; + *colorFormat = fmt.fmt.pix.pixelformat; + break; +#ifdef BOARD_USE_V4L2 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + *width = fmt.fmt.pix_mp.width; + *height = fmt.fmt.pix_mp.height; + *colorFormat = fmt.fmt.pix_mp.pixelformat; + break; +#endif + default: + LOGE("%s::Invalid buffer type", __func__); + return false; + break; + } + + crop.type = V4L2_BUF_TYPE_SRC; + if (ioctl(mFd, VIDIOC_G_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_G_CROP failed", __func__); + return false; + } + + *cropX = crop.c.left; + *cropY = crop.c.top; + *cropWidth = crop.c.width; + *cropHeight = crop.c.height; + + return true; +} + +bool SecFimc::setSrcAddr(unsigned int physYAddr, + unsigned int physCbAddr, + unsigned int physCrAddr, + int colorFormat) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + int src_planes = m_getYuvPlanes(params->src.color_space); + int src_bpp = m_getYuvBpp(params->src.color_space); + unsigned int frame_size = params->src.full_width * params->src.full_height; + src_planes = (src_planes == -1) ? 1 : src_planes; + + mSrcBuffer.phys.extP[0] = physYAddr; + + if (colorFormat == HAL_PIXEL_FORMAT_YV12) { + mSrcBuffer.phys.extP[1] = physCrAddr; + mSrcBuffer.phys.extP[2] = physCbAddr; + } else { + mSrcBuffer.phys.extP[1] = physCbAddr; + mSrcBuffer.phys.extP[2] = physCrAddr; + } + + if (2 <= src_planes && mSrcBuffer.phys.extP[1] == 0) + mSrcBuffer.phys.extP[1] = mSrcBuffer.phys.extP[0] + frame_size; + + if (3 == src_planes && mSrcBuffer.phys.extP[2] == 0) { + if (colorFormat == HAL_PIXEL_FORMAT_YV12) { + if (12 == src_bpp) + mSrcBuffer.phys.extP[1] = mSrcBuffer.phys.extP[2] + (frame_size >> 2); + else + mSrcBuffer.phys.extP[1] = mSrcBuffer.phys.extP[2] + (frame_size >> 1); + } else { + if (12 == src_bpp) + mSrcBuffer.phys.extP[2] = mSrcBuffer.phys.extP[1] + (frame_size >> 2); + else + mSrcBuffer.phys.extP[2] = mSrcBuffer.phys.extP[1] + (frame_size >> 1); + } + } + + return true; +} + +bool SecFimc::setDstParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(colorFormat); + if (v4l2ColorFormat < 0) { + LOGE("%s::not supported color format", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + + unsigned int fimcWidth = *cropWidth; + unsigned int fimcHeight = *cropHeight; + int dst_planes = m_getYuvPlanes(v4l2ColorFormat); + + m_checkDstSize(width, height, + cropX, cropY, + &fimcWidth, &fimcHeight, + v4l2ColorFormat, + mRotVal, + true); + + if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) { + if (forceChange == true) { +#ifdef DEBUG_LIB_FIMC + LOGD("size is changed from [w = %d, h= %d] to [w = %d, h = %d]", + *cropWidth, *cropHeight, fimcWidth, fimcHeight); +#endif + } else { + LOGE("%s::Invalid destination params", __func__); + return false; + } + } + + if (90 == mRotVal || 270 == mRotVal) { + params->dst.full_width = height; + params->dst.full_height = width; + + if (90 == mRotVal) { + params->dst.start_x = cropY; + params->dst.start_y = width - (cropX + fimcWidth); + } else { + params->dst.start_x = height - (cropY + fimcHeight); + params->dst.start_y = cropX; + } + + params->dst.width = fimcHeight; + params->dst.height = fimcWidth; + + if (0x50 != mHwVersion) + params->dst.start_y += (fimcWidth - params->dst.height); + + } else { + params->dst.full_width = width; + params->dst.full_height = height; + + if (180 == mRotVal) { + params->dst.start_x = width - (cropX + fimcWidth); + params->dst.start_y = height - (cropY + fimcHeight); + } else { + params->dst.start_x = cropX; + params->dst.start_y = cropY; + } + + params->dst.width = fimcWidth; + params->dst.height = fimcHeight; + } + params->dst.color_space = v4l2ColorFormat; + dst_planes = (dst_planes == -1) ? 1 : dst_planes; + +#ifdef BOARD_USE_V4L2 + if (mFlagSetDstParam == true) { + if (fimc_v4l2_clr_buf(mFd, V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST) < 0) { + LOGE("%s::fimc_v4l2_clr_buf_dst() failed", __func__); + return false; + } + } +#endif + + if (fimc_v4l2_s_ctrl(mFd, V4L2_ROTATE, mRotVal) < 0) { + LOGE("%s::fimc_v4l2_s_ctrl(V4L2_ROTATE)", __func__); + return false; + } + + if (fimc_v4l2_set_fmt(mFd, V4L2_BUF_TYPE_DST, V4L2_FIELD_ANY, &(params->dst), (unsigned int)mS5pFimc.out_buf.phys_addr) < 0) { + LOGE("%s::fimc_v4l2_set_fmt()[dst] failed", __func__); + return false; + } + +#ifdef BOARD_USE_V4L2 + if (fimc_v4l2_req_buf(mFd, mNumOfBuf, V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST) < 0) { + LOGE("%s::fimc_v4l2_req_buf()[dst] failed", __func__); + return false; + } + + for (int i = 0; i < mNumOfBuf; i++) { + if (fimc_v4l2_query_buf(mFd, &(mDstBuffer[i]), + V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST, i, dst_planes) < 0) { + LOGE("%s::fimc_v4l2_query_buf() failed", __func__); + } + } +#endif + + *cropWidth = fimcWidth; + *cropHeight = fimcHeight; + + mFlagSetDstParam = true; + return true; +} + +bool SecFimc::getDstParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *colorFormat) +{ + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + struct v4l2_crop crop; + + fmt.type = V4L2_BUF_TYPE_DST; + if (ioctl(mFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT(fmt.type : %d) failed", __func__, fmt.type); + return false; + } + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + *width = fmt.fmt.pix.width; + *height = fmt.fmt.pix.height; + *colorFormat = fmt.fmt.pix.pixelformat; + break; +#ifdef BOARD_USE_V4L2 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + *width = fmt.fmt.pix_mp.width; + *height = fmt.fmt.pix_mp.height; + *colorFormat = fmt.fmt.pix_mp.pixelformat; + break; +#endif + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + *cropX = fmt.fmt.win.w.left; + *cropY = fmt.fmt.win.w.top; + *cropWidth = fmt.fmt.win.w.width; + *cropHeight = fmt.fmt.win.w.height; + + if (ioctl(mFd, VIDIOC_G_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_G_FBUF failed", __func__); + return false; + } + + *width = fbuf.fmt.width; + *height = fbuf.fmt.height; + *colorFormat = fbuf.fmt.pixelformat; + break; + default: + LOGE("%s::Invalid buffer type", __func__); + return false; + break; + } + + if (fmt.type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + + crop.type = V4L2_BUF_TYPE_DST; + if (ioctl(mFd, VIDIOC_G_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_G_CROP(crop.type : %d) failed", __func__, crop.type); + return false; + } + + *cropX = crop.c.left; + *cropY = crop.c.top; + *cropWidth = crop.c.width; + *cropHeight = crop.c.height; + } + + return true; +} + +bool SecFimc::setDstAddr(unsigned int physYAddr, unsigned int physCbAddr, unsigned int physCrAddr, int buf_index) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + s5p_fimc_params_t *params = &(mS5pFimc.params); + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + mS5pFimc.out_buf.phys_addr = (void *)physYAddr; + + mDstBuffer[buf_index].phys.extP[0] = physYAddr; + mDstBuffer[buf_index].phys.extP[1] = physCbAddr; + mDstBuffer[buf_index].phys.extP[2] = physCrAddr; + +#ifdef BOARD_USE_V4L2 + if (physYAddr != 0) + mS5pFimc.use_ext_out_mem = 1; +#else + params->dst.buf_addr_phy_rgb_y = physYAddr; + params->dst.buf_addr_phy_cb = physCbAddr; + params->dst.buf_addr_phy_cr = physCrAddr; + + if ((physYAddr != 0) + && ((unsigned int)mS5pFimc.out_buf.phys_addr != mDstBuffer[0].phys.p)) + mS5pFimc.use_ext_out_mem = 1; + + if (fimc_v4l2_s_ctrl(mFd, V4L2_ROTATE, mRotVal) < 0) { + LOGE("%s::fimc_v4l2_s_ctrl(V4L2_ROTATE)", __func__); + return false; + } + + if (fimc_v4l2_set_fmt(mFd, V4L2_BUF_TYPE_DST, V4L2_FIELD_ANY, &(params->dst), (unsigned int)mS5pFimc.out_buf.phys_addr) < 0) { + LOGE("%s::fimc_v4l2_set_fmt()[dst] failed", __func__); + return false; + } +#endif + + return true; +} + +bool SecFimc::setRotVal(unsigned int rotVal) +{ + struct v4l2_control vc; + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (fimc_v4l2_s_ctrl(mFd, V4L2_ROTATE, rotVal) < 0) { + LOGE("%s::fimc_v4l2_s_ctrl(V4L2_ROTATE) failed", __func__); + return false; + } + + mRotVal = rotVal; + return true; +} + +bool SecFimc::setGlobalAlpha(bool enable, int alpha) +{ + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + if (mFlagGlobalAlpha == enable && mGlobalAlpha == alpha) + return true; + + memset(&fbuf, 0, sizeof(fbuf)); + + if (ioctl(mFd, VIDIOC_G_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_G_FBUF failed", __func__); + return false; + } + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA; + + if (ioctl(mFd, VIDIOC_S_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_S_FBUF failed", __func__); + return false; + } + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + + if (ioctl(mFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + return false; + } + + fmt.fmt.win.global_alpha = alpha & 0xFF; + if (ioctl(mFd, VIDIOC_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_S_FMT failed", __func__); + return false; + } + } + + mFlagGlobalAlpha = enable; + mGlobalAlpha = alpha; + + return true; + +} + +bool SecFimc::setLocalAlpha(bool enable) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + if (mFlagLocalAlpha == enable) + return true; + + return true; +} + +bool SecFimc::setColorKey(bool enable, int colorKey) +{ + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + if (mFlagColorKey == enable && mColorKey == colorKey) + return true; + + memset(&fbuf, 0, sizeof(fbuf)); + + if (ioctl(mFd, VIDIOC_G_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_G_FBUF failed", __func__); + return false; + } + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; + + if (ioctl(mFd, VIDIOC_S_FBUF, &fbuf) < 0) { + LOGE("%s::VIDIOC_S_FBUF failed", __func__); + return false; + } + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + + if (ioctl(mFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + return false; + } + + fmt.fmt.win.chromakey = colorKey & 0xFFFFFF; + + if (ioctl(mFd, VIDIOC_S_FMT, &fmt) < 0) + LOGE("%s::VIDIOC_S_FMT failed", __func__); + } + mFlagColorKey = enable; + mColorKey = colorKey; + return true; +} + +bool SecFimc::draw(int src_index, int dst_index) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagSetSrcParam == false) { + LOGE("%s::mFlagSetSrcParam == false fail", __func__); + return false; + } + + if (mFlagSetDstParam == false) { + LOGE("%s::mFlagSetDstParam == false fail", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + bool flagStreamOn = false; + int src_planes = m_getYuvPlanes(params->src.color_space); + int dst_planes = m_getYuvPlanes(params->dst.color_space); + src_planes = (src_planes == -1) ? 1 : src_planes; + dst_planes = (dst_planes == -1) ? 1 : dst_planes; + +#ifdef BOARD_USE_V4L2 + if (mFlagStreamOn == false) { + if (m_streamOn() == false) { + LOGE("%s::m_streamOn failed", __func__); + return false; + } + mFlagStreamOn = true; + } + if (fimc_v4l2_dequeue(mFd, V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST, &dst_index, dst_planes) < 0) { + LOGE("%s::fimc_v4l2_dequeue[dst](mNumOfBuf : %d) failed", __func__, mNumOfBuf); + return false; + } + + if (fimc_v4l2_dequeue(mFd, V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC, &src_index, src_planes) < 0) { + LOGE("%s::fimc_v4l2_dequeue[src](mNumOfBuf : %d) failed", __func__, mNumOfBuf); + return false; + } + + if (fimc_v4l2_queue(mFd, &(mSrcBuffer), V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC, src_index, src_planes) < 0) { + LOGE("%s::fimc_v4l2_queue[src](index : %d) (mNumOfBuf : %d) failed", __func__, 0, mNumOfBuf); + return false; + } + + if (fimc_v4l2_queue(mFd, &(mDstBuffer[dst_index]), V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST, dst_index, dst_planes) < 0) { + LOGE("%s::fimc_v4l2_queue[dst](index : %d) (mNumOfBuf : %d) failed", __func__, dst_index, mNumOfBuf); + return false; + } +#else + if (fimc_v4l2_stream_on(mFd, V4L2_BUF_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_stream_on() failed", __func__); + goto err; + } + + flagStreamOn = true; + + if (fimc_v4l2_queue(mFd, &(mSrcBuffer), V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC, src_index, src_planes) < 0) { + LOGE("%s::fimc_v4l2_queue(index : %d) (mNumOfBuf : %d) failed", __func__, 0, mNumOfBuf); + goto err; + } + + if (fimc_v4l2_dequeue(mFd, V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC, &src_index, src_planes) < 0) { + LOGE("%s::fimc_v4l2_dequeue (mNumOfBuf : %d) failed", __func__, mNumOfBuf); + goto err; + } +#endif + +err : +#ifndef BOARD_USE_V4L2 + if (flagStreamOn == true) { + if (fimc_v4l2_stream_off(mFd, V4L2_BUF_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_stream_off() failed", __func__); + return false; + } + } +#endif + + return true; +} + +bool SecFimc::m_streamOn() +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + +#ifdef BOARD_USE_V4L2 + s5p_fimc_params_t *params = &(mS5pFimc.params); + int src_planes = m_getYuvPlanes(params->src.color_space); + int dst_planes = m_getYuvPlanes(params->dst.color_space); + src_planes = (src_planes == -1) ? 1 : src_planes; + dst_planes = (dst_planes == -1) ? 1 : dst_planes; + + if (params->src.color_space == V4L2_PIX_FMT_RGB32) { + mSrcBuffer.size.extS[0] = params->src.full_height * params->src.full_width * 4; + + } else if ( (params->src.color_space == V4L2_PIX_FMT_NV12MT) + || (params->src.color_space == V4L2_PIX_FMT_NV12M)) { + mSrcBuffer.size.extS[0] = params->src.full_height * params->src.full_width; + mSrcBuffer.size.extS[1] = params->src.full_height * params->src.full_width / 2; + } else if ( (params->src.color_space == V4L2_PIX_FMT_YUV420) + || (params->src.color_space == V4L2_PIX_FMT_YUV420M)) { + mSrcBuffer.size.extS[0] = params->src.full_height * params->src.full_width; + mSrcBuffer.size.extS[1] = params->src.full_height * params->src.full_width / 4; + mSrcBuffer.size.extS[2] = params->src.full_height * params->src.full_width / 4; + } else { + mSrcBuffer.size.extS[0] = params->src.full_height * params->src.full_width * 2; + } + + if (fimc_v4l2_queue(mFd, &(mSrcBuffer), V4L2_BUF_TYPE_SRC, V4L2_MEMORY_TYPE_SRC, 0, src_planes) < 0) { + LOGE("%s::fimc_v4l2_queue(index : %d) (mSrcBufNum : %d) failed", __func__, 0, 1); + return false; + } + + for (int i = 0; i < mNumOfBuf; i++) { + if (fimc_v4l2_queue(mFd, &(mDstBuffer[i]), + V4L2_BUF_TYPE_DST, V4L2_MEMORY_TYPE_DST, i, dst_planes) < 0) { + LOGE("%s::fimc_v4l2_queue(index : %d) (mDstBufNum : %d) failed", __func__, i, mNumOfBuf); + return false; + } + } +#endif + if (fimc_v4l2_stream_on(mFd, V4L2_BUF_TYPE_SRC) < 0) { + LOGE("%s::fimc_v4l2_stream_on() failed", __func__); + return false; + } + +#ifdef BOARD_USE_V4L2 + if (fimc_v4l2_stream_on(mFd, V4L2_BUF_TYPE_DST) < 0) { + LOGE("%s::fimc_v4l2_stream_on() failed", __func__); + return false; + } +#endif + return true; +} + +bool SecFimc::m_checkSrcSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ + bool ret = true; + + if (8 <= height && *cropHeight < 8) { + if (forceChange) + *cropHeight = 8; + ret = false; + } + + if (16 <= width && *cropWidth < 16) { + if (forceChange) + *cropWidth = 16; + ret = false; + } + + if (0x50 == mHwVersion) { + if (colorFormat == V4L2_PIX_FMT_YUV422P) { + if (*cropHeight % 2 != 0) { + if (forceChange) + *cropHeight = multipleOfN(*cropHeight, 2); + ret = false; + } + if (*cropWidth % 2 != 0) { + if (forceChange) + *cropWidth = multipleOfN(*cropWidth, 2); + ret = false; + } + } + } else { + if (height < 8) + return false; + + if (width % 16 != 0) + return false; + + if (*cropWidth % 16 != 0) { + if (forceChange) + *cropWidth = multipleOfN(*cropWidth, 16); + ret = false; + } + } + + return ret; +} + +bool SecFimc::m_checkDstSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, int rotVal, bool forceChange) +{ + bool ret = true; + unsigned int rotWidth; + unsigned int rotHeight; + unsigned int *rotCropWidth; + unsigned int *rotCropHeight; + + if (rotVal == 90 || rotVal == 270) { + rotWidth = height; + rotHeight = width; + rotCropWidth = cropHeight; + rotCropHeight = cropWidth; + } else { + rotWidth = width; + rotHeight = height; + rotCropWidth = cropWidth; + rotCropHeight = cropHeight; + } + + if (rotHeight < 8) + return false; + + if (rotWidth % 8 != 0) + return false; + + switch (colorFormat) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: +#ifdef BOARD_USE_V4L2 + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_YUV420M: +#endif + case V4L2_PIX_FMT_YUV420: + if (*rotCropHeight % 2 != 0) { + if (forceChange) + *rotCropHeight = multipleOfN(*rotCropHeight, 2); + ret = false; + } + } + return ret; +} + +int SecFimc::m_widthOfFimc(int v4l2ColorFormat, int width) +{ + int newWidth = width; + + if (0x50 == mHwVersion) { + switch (v4l2ColorFormat) { + /* 422 1/2/3 plane */ + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_YUV422P: + /* 420 2/3 plane */ + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: +#ifdef BOARD_USE_V4L2 + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_YUV420M: +#endif + case V4L2_PIX_FMT_YUV420: + + newWidth = multipleOfN(width, 2); + break; + default : + break; + } + } else { + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_RGB565: + newWidth = multipleOfN(width, 8); + break; + case V4L2_PIX_FMT_RGB32: + newWidth = multipleOfN(width, 4); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + newWidth = multipleOfN(width, 4); + break; + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + newWidth = multipleOfN(width, 8); + break; + case V4L2_PIX_FMT_YUV422P: + newWidth = multipleOfN(width, 16); + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: +#ifdef BOARD_USE_V4L2 + case V4L2_PIX_FMT_NV12MT: +#endif + newWidth = multipleOfN(width, 8); + break; +#ifdef BOARD_USE_V4L2 + case V4L2_PIX_FMT_YUV420M: +#endif + case V4L2_PIX_FMT_YUV420: + newWidth = multipleOfN(width, 16); + break; + default : + break; + } + } + return newWidth; +} + +int SecFimc::m_heightOfFimc(int v4l2ColorFormat, int height) +{ + int newHeight = height; + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: +#ifdef BOARD_USE_V4L2 + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_YUV420M: +#endif + case V4L2_PIX_FMT_YUV420: + newHeight = multipleOfN(height, 2); + break; + default : + break; + } + return newHeight; +} + +int SecFimc::m_getYuvBpp(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].bpp; +} + +int SecFimc::m_getYuvPlanes(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].planes; +} diff --git a/exynos4/hal/libfimg/Android.mk b/exynos4/hal/libfimg/Android.mk deleted file mode 100644 index 0d607e2..0000000 --- a/exynos4/hal/libfimg/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_C_INCLUDES += \ - $(BOARD_HAL_PATH)/include \ - -LOCAL_SRC_FILES := \ - FimgApi.cpp \ - FimgC210.cpp - -LOCAL_SHARED_LIBRARIES:= liblog libutils libbinder - -LOCAL_MODULE_TAGS := eng -LOCAL_MODULE := libfimg - -LOCAL_PRELINK_MODULE := false - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libfimg/FimgApi.cpp b/exynos4/hal/libfimg/FimgApi.cpp deleted file mode 100644 index b4c5890..0000000 --- a/exynos4/hal/libfimg/FimgApi.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* -** -** Copyright 2009 Samsung Electronics Co, Ltd. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -** -** -*/ - -/////////////////////////////////////////////////// -// include -/////////////////////////////////////////////////// -#define LOG_NDEBUG 0 -#define LOG_TAG "FimgApi" -#include - -#include "FimgApi.h" - -//---------------------------------------------------------------------------// -// Global Function -//---------------------------------------------------------------------------// -#ifndef REAL_DEBUG - void VOID_FUNC(const char* format, ...) - {} -#endif - -//---------------------------------------------------------------------------// -// FimgApi -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -// Method Function Implementation -//---------------------------------------------------------------------------// - -FimgApi::FimgApi() -{ - m_flagCreate = false; -} - -FimgApi::~FimgApi() -{ - if(m_flagCreate == true) - PRINT("%s::this is not Destroyed fail \n", __func__); -} - -bool FimgApi::Create(void) -{ - bool ret = false; - - if(t_Lock() == false) { - PRINT("%s::t_Lock() fail \n", __func__); - goto CREATE_DONE; - } - - if(m_flagCreate == true) { - PRINT("%s::Already Created fail \n", __func__); - goto CREATE_DONE; - } - - if(t_Create() == false) { - PRINT("%s::t_Create() fail \n", __func__); - goto CREATE_DONE; - } - - m_flagCreate = true; - - ret = true; - -CREATE_DONE : - - t_UnLock(); - - return ret; -} - -bool FimgApi::Destroy(void) -{ - bool ret = false; - - if(t_Lock() == false) { - PRINT("%s::t_Lock() fail \n", __func__); - goto DESTROY_DONE; - } - - if(m_flagCreate == false) { - PRINT("%s::Already Destroyed fail \n", __func__); - goto DESTROY_DONE; - } - - if(t_Destroy() == false) { - PRINT("%s::t_Destroy() fail \n", __func__); - goto DESTROY_DONE; - } - - m_flagCreate = false; - - ret = true; - -DESTROY_DONE : - - t_UnLock(); - - return ret; -} - -bool FimgApi::Stretch(FimgRect * src, FimgRect * dst, FimgClip *clip, FimgFlag * flag) -{ - bool ret = false; - - if(t_Lock() == false) { - PRINT("%s::t_Lock() fail \n", __func__); - goto STRETCH_DONE; - } - - if(m_flagCreate == false) { - PRINT("%s::This is not Created fail \n", __func__); - goto STRETCH_DONE; - } - - if(t_Stretch(src, dst, clip, flag) == false) { - goto STRETCH_DONE; - } - - ret = true; - -STRETCH_DONE : - - t_UnLock(); - - return ret; -} - -bool FimgApi::Sync(void) -{ - bool ret = false; - - if(m_flagCreate == false) { - PRINT("%s::This is not Created fail \n", __func__); - goto SYNC_DONE; - } - - if(t_Sync() == false) { - goto SYNC_DONE; - } - - ret = true; - -SYNC_DONE : - - return ret; -} - -bool FimgApi::t_Create(void) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - -bool FimgApi::t_Destroy(void) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - -bool FimgApi::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - -bool FimgApi::t_Sync(void) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - -bool FimgApi::t_Lock(void) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - -bool FimgApi::t_UnLock(void) -{ - PRINT("%s::This is empty virtual function fail\n", __func__); - return false; -} - - -//---------------------------------------------------------------------------// -// extern function -//---------------------------------------------------------------------------// -extern "C" int stretchFimgApi(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) -{ - FimgApi * fimgApi = createFimgApi(); - - if(fimgApi == NULL) { - PRINT("%s::createFimgApi() fail \n", __func__); - return -1; - } - - if(fimgApi->Stretch(src, dst, clip, flag) == false) { - if(fimgApi != NULL) - destroyFimgApi(fimgApi); - - return -1; - } - - if(fimgApi != NULL) - destroyFimgApi(fimgApi); - - return 0; -} - -extern "C" int SyncFimgApi(void) -{ - FimgApi * fimgApi = createFimgApi(); - if(fimgApi == NULL) { - PRINT("%s::createFimgApi() fail \n", __func__); - return -1; - } - - if(fimgApi->Sync() == false) { - if(fimgApi != NULL) - destroyFimgApi(fimgApi); - - return -1; - } - - if(fimgApi != NULL) - destroyFimgApi(fimgApi); - - return 0; -} - diff --git a/exynos4/hal/libfimg/FimgApi.h b/exynos4/hal/libfimg/FimgApi.h deleted file mode 100644 index 3daac3d..0000000 --- a/exynos4/hal/libfimg/FimgApi.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -** -** Copyright 2009 Samsung Electronics Co, Ltd. -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -** -** -*/ - -#ifndef FIMG_API_H -#define FIMG_API_H - -#include - -#include "../include/sec_g2d.h" -//#include -#define REAL_DEBUG -#define ANDROID_LOG - -#if defined(REAL_DEBUG) -#ifdef ANDROID_LOG - #define PRINT LOGE - #define PRINTD LOGD -#else - #define PRINT printf - #define PRINTD printf -#endif -#else - void VOID_FUNC(const char* format, ...); - - #define PRINT VOID_FUNC - #define PRINTD VOID_FUNC -#endif - -typedef g2d_rect FimgRect; -typedef g2d_flag FimgFlag; -typedef g2d_clip FimgClip; - -#ifdef __cplusplus -class FimgApi -{ -public: -#endif - enum COLOR_FORMAT { - COLOR_FORMAT_BASE = 0, - - COLOR_FORMAT_RGB_565 = G2D_RGB_565, - - COLOR_FORMAT_RGBA_8888 = G2D_RGBA_8888, - COLOR_FORMAT_ARGB_8888 = G2D_ARGB_8888, - COLOR_FORMAT_BGRA_8888 = G2D_BGRA_8888, - COLOR_FORMAT_ABGR_8888 = G2D_ABGR_8888, - - COLOR_FORMAT_RGBX_8888 = G2D_RGBX_8888, - COLOR_FORMAT_XRGB_8888 = G2D_XRGB_8888, - COLOR_FORMAT_BGRX_8888 = G2D_BGRX_8888, - COLOR_FORMAT_XBGR_8888 = G2D_XBGR_8888, - - COLOR_FORMAT_RGBA_5551 = G2D_RGBA_5551, - COLOR_FORMAT_ARGB_1555 = G2D_ARGB_1555, - COLOR_FORMAT_BGRA_5551 = G2D_BGRA_5551, - COLOR_FORMAT_ABGR_1555 = G2D_ABGR_1555, - - COLOR_FORMAT_RGBX_5551 = G2D_RGBX_5551, - COLOR_FORMAT_XRGB_1555 = G2D_XRGB_1555, - COLOR_FORMAT_BGRX_5551 = G2D_BGRX_5551, - COLOR_FORMAT_XBGR_1555 = G2D_XBGR_1555, - - COLOR_FORMAT_RGBA_4444 = G2D_RGBA_4444, - COLOR_FORMAT_ARGB_4444 = G2D_ARGB_4444, - COLOR_FORMAT_BGRA_4444 = G2D_BGRA_4444, - COLOR_FORMAT_ABGR_4444 = G2D_ABGR_4444, - - COLOR_FORMAT_RGBX_4444 = G2D_RGBX_4444, - COLOR_FORMAT_XRGB_4444 = G2D_XRGB_4444, - COLOR_FORMAT_BGRX_4444 = G2D_BGRX_4444, - COLOR_FORMAT_XBGR_4444 = G2D_XBGR_4444, - - COLOR_FORMAT_PACKED_RGB_888 = G2D_PACKED_RGB_888, - COLOR_FORMAT_PACKED_BGR_888 = G2D_PACKED_BGR_888, - COLOR_FORMAT_YUV_420SP, - COLOR_FORMAT_YUV_420P, - COLOR_FORMAT_YUV_420I, - COLOR_FORMAT_YUV_422SP, - COLOR_FORMAT_YUV_422P, - COLOR_FORMAT_YUV_422I, - COLOR_FORMAT_YUYV, - - COLOR_FORMAT_MAX, - }; - - enum ROTATE { - ROTATE_BASE = 0, - ROTATE_0 = G2D_ROT_0, - ROTATE_90 = G2D_ROT_90, - ROTATE_180 = G2D_ROT_180, - ROTATE_270 = G2D_ROT_270, - ROTATE_X_FLIP = G2D_ROT_X_FLIP, - ROTATE_Y_FLIP = G2D_ROT_Y_FLIP, - ROTATE_MAX, - }; - - enum ALPHA_VALUE { - ALPHA_MIN = G2D_ALPHA_BLENDING_MIN, // wholly transparent - ALPHA_MAX = G2D_ALPHA_BLENDING_MAX, // 255 - ALPHA_OPAQUE = G2D_ALPHA_BLENDING_OPAQUE, // opaque - }; - - enum DITHER { - DITHER_BASE = 0, - DITHER_OFF = 0, - DITHER_ON = 1, - DITHER_MAX, - }; -#ifdef __cplusplus -private : - bool m_flagCreate; - -protected : - FimgApi(); - FimgApi(const FimgApi& rhs) {} - virtual ~FimgApi(); - -public: - bool Create(void); - bool Destroy(void); - inline bool FlagCreate(void) { return m_flagCreate; } - bool Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); - bool Sync(void); - -protected: - virtual bool t_Create(void); - virtual bool t_Destroy(void); - virtual bool t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); - virtual bool t_Sync(void); - virtual bool t_Lock(void); - virtual bool t_UnLock(void); - -}; -#endif - -/*--------------------------------------------------------------------------- - * user api extern function - *--------------------------------------------------------------------------- - * usage 1 - * FimgApi * p = createFimgApi(); - * p->Stretch() - * destroyFimgApi(p); - * - * usage 2 - * stretchFimgApi(src, dst, clip, flag); - *-------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" -#endif -struct FimgApi * createFimgApi(); - -#ifdef __cplusplus -extern "C" -#endif -void destroyFimgApi(FimgApi * ptrFimgApi); - -#ifdef __cplusplus -extern "C" -#endif -int stretchFimgApi(FimgRect * src, - FimgRect * dst, - FimgClip * clip, - FimgFlag * flag); -#ifdef __cplusplus -extern "C" -#endif -int SyncFimgApi(void); - -#endif //FIMG_API_H diff --git a/exynos4/hal/libfimg/FimgC210.cpp b/exynos4/hal/libfimg/FimgC210.cpp deleted file mode 100644 index 129acae..0000000 --- a/exynos4/hal/libfimg/FimgC210.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/* -** -** Copyright 2009 Samsung Electronics Co, Ltd. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -** -** -*/ - -/////////////////////////////////////////////////// -// include -/////////////////////////////////////////////////// -#define LOG_NDEBUG 0 -#define LOG_TAG "FimgC210" -#include - -#include "FimgC210.h" - -namespace android -{ - -//---------------------------------------------------------------------------// -// FimgC210 -//---------------------------------------------------------------------------// - -Mutex FimgC210::m_instanceLock; -int FimgC210::m_curFimgC210Index = 0; -int FimgC210::m_numOfInstance = 0; -FimgApi * FimgC210::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, }; - -//---------------------------------------------------------------------------// - -FimgC210::FimgC210() - : m_g2dFd(0), - m_g2dVirtAddr(NULL), - m_g2dSize(0), - m_g2dSrcVirtAddr(NULL), - m_g2dSrcSize(0), - m_g2dDstVirtAddr(NULL), - m_g2dDstSize(0) -{ - m_lock = new Mutex(Mutex::SHARED, "FimgC210"); -} - -FimgC210::~FimgC210() -{ - delete m_lock; -} - -FimgApi * FimgC210::CreateInstance() -{ - Mutex::Autolock autolock(m_instanceLock); - - FimgApi * ptrFimg = NULL; - - // Using List like RingBuffer... - for(int i = m_curFimgC210Index; i < NUMBER_FIMG_LIST; i++) { - if(m_ptrFimgApiList[i] == NULL) - m_ptrFimgApiList[i] = new FimgC210; - - if(m_ptrFimgApiList[i]->FlagCreate() == false) { - if(m_ptrFimgApiList[i]->Create() == false) { - PRINT("%s::Create(%d) fail\n", __func__, i); - goto CreateInstance_End; - } - else - m_numOfInstance++; - } - - if(i < NUMBER_FIMG_LIST - 1) - m_curFimgC210Index = i + 1; - else - m_curFimgC210Index = 0; - - ptrFimg = m_ptrFimgApiList[i]; - goto CreateInstance_End; - } - -CreateInstance_End : - - return ptrFimg; -} - -void FimgC210::DestroyInstance(FimgApi * ptrFimgApi) -{ - Mutex::Autolock autolock(m_instanceLock); - - for(int i = 0; i < NUMBER_FIMG_LIST; i++) { - if(m_ptrFimgApiList[i] != NULL - && m_ptrFimgApiList[i] == ptrFimgApi) { - if(m_ptrFimgApiList[i]->FlagCreate() == true - && m_ptrFimgApiList[i]->Destroy() == false) { - PRINT("%s::Destroy() fail\n", __func__); - } else { - FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i]; - delete tempFimgC210; - m_ptrFimgApiList[i] = NULL; - - m_numOfInstance--; - } - - break; - } - } -} - -void FimgC210::DestroyAllInstance(void) -{ - Mutex::Autolock autolock(m_instanceLock); - - for(int i = 0; i < NUMBER_FIMG_LIST; i++) { - if(m_ptrFimgApiList[i] != NULL) { - if(m_ptrFimgApiList[i]->FlagCreate() == true - && m_ptrFimgApiList[i]->Destroy() == false) { - PRINT("%s::Destroy() fail\n", __func__); - } else { - FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i]; - delete tempFimgC210; - m_ptrFimgApiList[i] = NULL; - } - } - } -} - - -bool FimgC210::t_Create(void) -{ - bool ret = true; - - if(m_CreateG2D() == false) { - PRINT("%s::m_CreateG2D() fail \n", __func__); - - if(m_DestroyG2D() == false) - PRINT("%s::m_DestroyG2D() fail \n", __func__); - - ret = false; - } - - return ret; -} - -bool FimgC210::t_Destroy(void) -{ - bool ret = true; - - if(m_DestroyG2D() == false) { - PRINT("%s::m_DestroyG2D() fail \n", __func__); - ret = false; - } - - return ret; -} - -bool FimgC210::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) -{ - #ifdef CHECK_FIMGC210_PERFORMANCE - #define NUM_OF_STEP (10) - StopWatch stopWatch("CHECK_FIMGC210_PERFORMANCE"); - const char * stopWatchName[NUM_OF_STEP]; - nsecs_t stopWatchTime[NUM_OF_STEP]; - int stopWatchIndex = 0; - #endif // CHECK_FIMGC210_PERFORMANCE - - if(m_DoG2D(src, dst, clip, flag) == false) { - goto STRETCH_FAIL; - } - -#ifdef G2D_NONE_BLOCKING_MODE - if(m_PollG2D(&m_g2dPoll) == false) - { - PRINT("%s::m_PollG2D() fail\n", __func__); - goto STRETCH_FAIL; - } -#endif - - #ifdef CHECK_FIMGC210_PERFORMANCE - m_PrintFimgC210Performance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); - #endif // CHECK_FIMGC210_PERFORMANCE - - return true; - -STRETCH_FAIL: - return false; - -} - -bool FimgC210::t_Sync(void) -{ -#if 0 - if(ioctl(m_g2dFd, G2D_SYNC) < 0) { - PRINT("%s::G2D_Sync fail\n", __func__); - goto SYNC_FAIL; - } -#else - if(m_PollG2D(&m_g2dPoll) == false) - { - PRINT("%s::m_PollG2D() fail\n", __func__); - goto SYNC_FAIL; - } -#endif - return true; - -SYNC_FAIL: - return false; - -} - -bool FimgC210::t_Lock(void) -{ - m_lock->lock(); - return true; -} - -bool FimgC210::t_UnLock(void) -{ - m_lock->unlock(); - return true; -} - -bool FimgC210::m_CreateG2D(void) -{ - void * mmap_base; - - if(m_g2dFd != 0) { - PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd); - return false; - } - -#ifdef G2D_NONE_BLOCKING_MODE - m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK); -#else - m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR); -#endif - if(m_g2dFd < 0) { - PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno)); - m_g2dFd = 0; - return false; - } - - memset(&m_g2dPoll, 0, sizeof(m_g2dPoll)); - m_g2dPoll.fd = m_g2dFd; - m_g2dPoll.events = POLLOUT | POLLERR; - - return true; -} - -bool FimgC210::m_DestroyG2D(void) -{ - if(m_g2dVirtAddr != NULL) { - munmap(m_g2dVirtAddr, m_g2dSize); - m_g2dVirtAddr = NULL; - m_g2dSize = 0; - } - - if(0 < m_g2dFd) { - close(m_g2dFd); - } - m_g2dFd = 0; - - return true; -} - -//bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, int rotateValue, int alphaValue, int colorKey) -bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) -{ - g2d_params params; - - memcpy(¶ms.src_rect, src, sizeof(FimgRect)); - memcpy(¶ms.dst_rect, dst, sizeof(FimgRect)); - memcpy(¶ms.clip, clip, sizeof(FimgClip)); - memcpy(¶ms.flag, flag, sizeof(FimgFlag)); - - if(ioctl(m_g2dFd, G2D_BLIT, ¶ms) < 0) { - #if 0 - { - PRINT("---------------------------------------\n"); - PRINT("src.color_format : %d \n", src->color_format); - PRINT("src.full_w : %d \n", src->full_w); - PRINT("src.full_h : %d \n", src->full_h); - PRINT("src.x : %d \n", src->x); - PRINT("src.y : %d \n", src->y); - PRINT("src.w : %d \n", src->w); - PRINT("src.h : %d \n", src->h); - - PRINT("dst.color_format : %d \n", dst->color_format); - PRINT("dst.full_w : %d \n", dst->full_w); - PRINT("dst.full_h : %d \n", dst->full_h); - PRINT("dst.x : %d \n", dst->x); - PRINT("dst.y : %d \n", dst->y); - PRINT("dst.w : %d \n", dst->w); - PRINT("dst.h : %d \n", dst->h); - - PRINT("flag.rotate_val : %d \n", flag->rotate_val); - PRINT("flag.alpha_val : %d(%d) \n", flag->alpha_val); - PRINT("flag.color_key_mode : %d(%d) \n", flag->color_key_mode, flag->color_key_val); - PRINT("---------------------------------------\n"); - } - #endif - - return false; - } - - return true; -} - -inline bool FimgC210::m_PollG2D(struct pollfd * events) -{ - #define G2D_POLL_TIME (1000) - - int ret; - - ret = poll(events, 1, G2D_POLL_TIME); - - if (ret < 0) { - if(ioctl(m_g2dFd, G2D_RESET) < 0) { - PRINT("%s::G2D_RESET fail\n", __func__); - } - PRINT("%s::poll fail \n", __func__); - return false; - } - else if (ret == 0) { - if(ioctl(m_g2dFd, G2D_RESET) < 0) { - PRINT("%s::G2D_RESET fail\n", __func__); - } - PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME); - return false; - } - - return true; -} - -inline bool FimgC210::m_CleanG2D(unsigned int virtAddr, unsigned int size) -{ - g2d_dma_info dma_info = { virtAddr, size }; - - if(ioctl(m_g2dFd, G2D_DMA_CACHE_CLEAN, &dma_info) < 0) { - PRINT("%s::G2D_DMA_CACHE_CLEAN(%d, %d) fail\n", __func__, virtAddr, size); - return false; - } - return true; -} - -inline bool FimgC210::m_FlushG2D (unsigned int virtAddr, unsigned int size) -{ - g2d_dma_info dma_info = { virtAddr, size }; - - if(ioctl(m_g2dFd, G2D_DMA_CACHE_FLUSH, &dma_info) < 0) { - PRINT("%s::G2D_DMA_CACHE_FLUSH(%d, %d) fail\n", __func__, virtAddr, size); - return false; - } - return true; -} - -inline int FimgC210::m_RotateValueFimgApi2FimgHw(int rotateValue) -{ - switch (rotateValue) { - case ROTATE_0: return G2D_ROT_0; - case ROTATE_90: return G2D_ROT_90; - case ROTATE_180: return G2D_ROT_180; - case ROTATE_270: return G2D_ROT_270; - case ROTATE_X_FLIP: return G2D_ROT_X_FLIP; - case ROTATE_Y_FLIP: return G2D_ROT_Y_FLIP; - } - - return -1; -} - - -#ifdef CHECK_FIMGC210_PERFORMANCE -void FimgC210::m_PrintFimgC210Performance(FimgRect * src, - FimgRect * dst, - int stopWatchIndex, - const char * stopWatchName[], - nsecs_t stopWatchTime[]) -{ - char * srcColorFormat = "UNKNOW_COLOR_FORMAT"; - char * dstColorFormat = "UNKNOW_COLOR_FORMAT"; - - switch(src->color_format) - { - case COLOR_FORMAT_RGB_565 : - srcColorFormat = "RGB_565"; - break; - case COLOR_FORMAT_RGBA_8888 : - srcColorFormat = "RGBA_8888"; - break; - case COLOR_FORMAT_RGBX_8888 : - srcColorFormat = "RGBX_8888"; - break; - default : - srcColorFormat = "UNKNOW_COLOR_FORMAT"; - break; - } - - switch(dst->color_format) - { - case COLOR_FORMAT_RGB_565 : - dstColorFormat = "RGB_565"; - break; - case COLOR_FORMAT_RGBA_8888 : - dstColorFormat = "RGBA_8888"; - break; - case COLOR_FORMAT_RGBX_8888 : - dstColorFormat = "RGBX_8888"; - break; - default : - dstColorFormat = "UNKNOW_COLOR_FORMAT"; - break; - } - - -#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE -#else - PRINT("===============================================\n"); - PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n", - src->w, src->h, srcColorFormat, - dst->w, dst->h, dstColorFormat); -#endif - - nsecs_t totalTime = stopWatchTime[stopWatchIndex - 1]; - - for(int i = 0 ; i < stopWatchIndex; i++) { - nsecs_t sectionTime; - - if(i != 0) - sectionTime = stopWatchTime[i] - stopWatchTime[i-1]; - else - sectionTime = stopWatchTime[i]; - -#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE - if(1500 < (sectionTime / 1000)) // check 1.5 mille second.. -#endif - { - PRINT("===============================================\n"); - PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n", - src->w, src->h, srcColorFormat, - dst->w, dst->h, dstColorFormat); - - PRINT("%20s : %5lld msec(%5.2f %%)\n", - stopWatchName[i], - sectionTime / 1000, - ((float)sectionTime / (float)totalTime) * 100.0f); - } - } - -} -#endif // CHECK_FIMGC210_PERFORMANCE - -//---------------------------------------------------------------------------// -// extern function -//---------------------------------------------------------------------------// -extern "C" struct FimgApi * createFimgApi() -{ - if (fimgApiAutoFreeThread == 0) - fimgApiAutoFreeThread = new FimgApiAutoFreeThread(); - else - fimgApiAutoFreeThread->SetOneMoreSleep(); - - return FimgC210::CreateInstance(); -} - -extern "C" void destroyFimgApi(FimgApi * ptrFimgApi) -{ - // Dont' call DestrotInstance.. - // return FimgC210::DestroyInstance(ptrFimgApi); -} - -}; // namespace android diff --git a/exynos4/hal/libfimg/FimgC210.h b/exynos4/hal/libfimg/FimgC210.h deleted file mode 100644 index 7aa9a9a..0000000 --- a/exynos4/hal/libfimg/FimgC210.h +++ /dev/null @@ -1,197 +0,0 @@ -/* -** -** Copyright 2008, The Android Open Source Project -** Copyright 2009 Samsung Electronics Co, Ltd. All Rights Reserved. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -** -** -*/ - -#ifndef FIMG_C210_H -#define FIMG_C210_H - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "FimgApi.h" -//#include "FimgMem.h" - -#include "sec_g2d.h" - -//-----------------------------------------------------------------// - -namespace android -{ - -//#define CHECK_FIMGC210_PERFORMANCE -//#define CHECK_FIMGC210_CRITICAL_PERFORMANCE -#define NUMBER_FIMG_LIST (1) // kcoolsw : because of pmem -//#define G2D_NONE_BLOCKING_MODE // Not supported yet. because of sysMMU Page fault -#define GET_RECT_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) -#define GET_REAL_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) -#define GET_START_ADDR(rect) (rect->virt_addr + ((rect->y * rect->full_w) * rect->bytes_per_pixel)) - - -//---------------------------------------------------------------------------// -// class FimgC210 : public FimgBase -//---------------------------------------------------------------------------// -class FimgC210 : public FimgApi -{ -private : - int m_g2dFd; - - unsigned char * m_g2dVirtAddr; - unsigned int m_g2dSize; - unsigned char * m_g2dSrcVirtAddr; - unsigned int m_g2dSrcSize; - unsigned char * m_g2dDstVirtAddr; - unsigned int m_g2dDstSize; - struct pollfd m_g2dPoll; - - Mutex * m_lock; - - static Mutex m_instanceLock; - static int m_curFimgC210Index; - static int m_numOfInstance; - - static FimgApi * m_ptrFimgApiList[NUMBER_FIMG_LIST]; - - -protected : - FimgC210(); - virtual ~FimgC210(); - -public: - static FimgApi * CreateInstance(); - static void DestroyInstance(FimgApi * ptrFimgApi); - static void DestroyAllInstance(void); - -protected: - virtual bool t_Create(void); - virtual bool t_Destroy(void); - virtual bool t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); - virtual bool t_Sync(void); - virtual bool t_Lock(void); - virtual bool t_UnLock(void); - -private: - bool m_CreateG2D(void); - bool m_DestroyG2D(void); - bool SetClipRectl(FimgRect * dst, FimgClip * clip, FimgClip * clipTempMidRect); - - bool m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); - - inline bool m_PollG2D(struct pollfd * events); - - inline bool m_CleanG2D (unsigned int addr, unsigned int size); - inline bool m_FlushG2D (unsigned int addr, unsigned int size); - - inline int m_ColorFormatFimgApi2FimgHw(int colorFormat); - inline int m_RotateValueFimgApi2FimgHw(int rotateValue); - - #ifdef CHECK_FIMGC210_PERFORMANCE - void m_PrintFimgC210Performance(FimgRect * src, - FimgRect * dst, - int stopWatchIndex, - const char * stopWatchName[], - nsecs_t stopWatchTime[]); - #endif // CHECK_FIMGC210_PERFORMANCE -}; - -//---------------------------------------------------------------------------// -// class FimgApiAutoFreeThread : public Thread -//---------------------------------------------------------------------------// -class FimgApiAutoFreeThread; - -static sp fimgApiAutoFreeThread = 0; - -class FimgApiAutoFreeThread : public Thread -{ - private: - bool mOneMoreSleep; - bool mDestroyed; - - public: - FimgApiAutoFreeThread(void): - //Thread(true), - Thread(false), - mOneMoreSleep(true), - mDestroyed(false) - { } - ~FimgApiAutoFreeThread(void) - { - if(mDestroyed == false) - { - FimgC210::DestroyAllInstance(); - mDestroyed = true; - } - } - - virtual void onFirstRef() - { - run("FimgApiAutoFreeThread", PRIORITY_BACKGROUND); - } - - virtual bool threadLoop() - { - //#define SLEEP_TIME (10000000) // 10 sec - #define SLEEP_TIME (3000000) // 3 sec - //#define SLEEP_TIME (1000000) // 1 sec - - if(mOneMoreSleep == true) - { - mOneMoreSleep = false; - usleep(SLEEP_TIME); - - return true; - } - else - { - if(mDestroyed == false) - { - FimgC210::DestroyAllInstance(); - mDestroyed = true; - } - - fimgApiAutoFreeThread = 0; - - return false; - } - } - - void SetOneMoreSleep(void) - { - mOneMoreSleep = true; - } -}; - -}; // namespace android - -#endif // FIMG_C210_H diff --git a/exynos4/hal/libfimg3x/Android.mk b/exynos4/hal/libfimg3x/Android.mk new file mode 100644 index 0000000..c60274d --- /dev/null +++ b/exynos4/hal/libfimg3x/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +ifeq ($(BOARD_USES_FIMGAPI),true) + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES:= \ + FimgApi.cpp \ + FimgC210.cpp + +LOCAL_SHARED_LIBRARIES:= liblog libutils libbinder + +LOCAL_MODULE:= libfimg + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libfimg3x/FimgApi.cpp b/exynos4/hal/libfimg3x/FimgApi.cpp new file mode 100644 index 0000000..b4c5890 --- /dev/null +++ b/exynos4/hal/libfimg3x/FimgApi.cpp @@ -0,0 +1,245 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +/////////////////////////////////////////////////// +// include +/////////////////////////////////////////////////// +#define LOG_NDEBUG 0 +#define LOG_TAG "FimgApi" +#include + +#include "FimgApi.h" + +//---------------------------------------------------------------------------// +// Global Function +//---------------------------------------------------------------------------// +#ifndef REAL_DEBUG + void VOID_FUNC(const char* format, ...) + {} +#endif + +//---------------------------------------------------------------------------// +// FimgApi +//---------------------------------------------------------------------------// + +//---------------------------------------------------------------------------// +// Method Function Implementation +//---------------------------------------------------------------------------// + +FimgApi::FimgApi() +{ + m_flagCreate = false; +} + +FimgApi::~FimgApi() +{ + if(m_flagCreate == true) + PRINT("%s::this is not Destroyed fail \n", __func__); +} + +bool FimgApi::Create(void) +{ + bool ret = false; + + if(t_Lock() == false) { + PRINT("%s::t_Lock() fail \n", __func__); + goto CREATE_DONE; + } + + if(m_flagCreate == true) { + PRINT("%s::Already Created fail \n", __func__); + goto CREATE_DONE; + } + + if(t_Create() == false) { + PRINT("%s::t_Create() fail \n", __func__); + goto CREATE_DONE; + } + + m_flagCreate = true; + + ret = true; + +CREATE_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Destroy(void) +{ + bool ret = false; + + if(t_Lock() == false) { + PRINT("%s::t_Lock() fail \n", __func__); + goto DESTROY_DONE; + } + + if(m_flagCreate == false) { + PRINT("%s::Already Destroyed fail \n", __func__); + goto DESTROY_DONE; + } + + if(t_Destroy() == false) { + PRINT("%s::t_Destroy() fail \n", __func__); + goto DESTROY_DONE; + } + + m_flagCreate = false; + + ret = true; + +DESTROY_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Stretch(FimgRect * src, FimgRect * dst, FimgClip *clip, FimgFlag * flag) +{ + bool ret = false; + + if(t_Lock() == false) { + PRINT("%s::t_Lock() fail \n", __func__); + goto STRETCH_DONE; + } + + if(m_flagCreate == false) { + PRINT("%s::This is not Created fail \n", __func__); + goto STRETCH_DONE; + } + + if(t_Stretch(src, dst, clip, flag) == false) { + goto STRETCH_DONE; + } + + ret = true; + +STRETCH_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Sync(void) +{ + bool ret = false; + + if(m_flagCreate == false) { + PRINT("%s::This is not Created fail \n", __func__); + goto SYNC_DONE; + } + + if(t_Sync() == false) { + goto SYNC_DONE; + } + + ret = true; + +SYNC_DONE : + + return ret; +} + +bool FimgApi::t_Create(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Destroy(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Sync(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Lock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_UnLock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" int stretchFimgApi(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) +{ + FimgApi * fimgApi = createFimgApi(); + + if(fimgApi == NULL) { + PRINT("%s::createFimgApi() fail \n", __func__); + return -1; + } + + if(fimgApi->Stretch(src, dst, clip, flag) == false) { + if(fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if(fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + +extern "C" int SyncFimgApi(void) +{ + FimgApi * fimgApi = createFimgApi(); + if(fimgApi == NULL) { + PRINT("%s::createFimgApi() fail \n", __func__); + return -1; + } + + if(fimgApi->Sync() == false) { + if(fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if(fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + diff --git a/exynos4/hal/libfimg3x/FimgApi.h b/exynos4/hal/libfimg3x/FimgApi.h new file mode 100644 index 0000000..3daac3d --- /dev/null +++ b/exynos4/hal/libfimg3x/FimgApi.h @@ -0,0 +1,186 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_API_H +#define FIMG_API_H + +#include + +#include "../include/sec_g2d.h" +//#include +#define REAL_DEBUG +#define ANDROID_LOG + +#if defined(REAL_DEBUG) +#ifdef ANDROID_LOG + #define PRINT LOGE + #define PRINTD LOGD +#else + #define PRINT printf + #define PRINTD printf +#endif +#else + void VOID_FUNC(const char* format, ...); + + #define PRINT VOID_FUNC + #define PRINTD VOID_FUNC +#endif + +typedef g2d_rect FimgRect; +typedef g2d_flag FimgFlag; +typedef g2d_clip FimgClip; + +#ifdef __cplusplus +class FimgApi +{ +public: +#endif + enum COLOR_FORMAT { + COLOR_FORMAT_BASE = 0, + + COLOR_FORMAT_RGB_565 = G2D_RGB_565, + + COLOR_FORMAT_RGBA_8888 = G2D_RGBA_8888, + COLOR_FORMAT_ARGB_8888 = G2D_ARGB_8888, + COLOR_FORMAT_BGRA_8888 = G2D_BGRA_8888, + COLOR_FORMAT_ABGR_8888 = G2D_ABGR_8888, + + COLOR_FORMAT_RGBX_8888 = G2D_RGBX_8888, + COLOR_FORMAT_XRGB_8888 = G2D_XRGB_8888, + COLOR_FORMAT_BGRX_8888 = G2D_BGRX_8888, + COLOR_FORMAT_XBGR_8888 = G2D_XBGR_8888, + + COLOR_FORMAT_RGBA_5551 = G2D_RGBA_5551, + COLOR_FORMAT_ARGB_1555 = G2D_ARGB_1555, + COLOR_FORMAT_BGRA_5551 = G2D_BGRA_5551, + COLOR_FORMAT_ABGR_1555 = G2D_ABGR_1555, + + COLOR_FORMAT_RGBX_5551 = G2D_RGBX_5551, + COLOR_FORMAT_XRGB_1555 = G2D_XRGB_1555, + COLOR_FORMAT_BGRX_5551 = G2D_BGRX_5551, + COLOR_FORMAT_XBGR_1555 = G2D_XBGR_1555, + + COLOR_FORMAT_RGBA_4444 = G2D_RGBA_4444, + COLOR_FORMAT_ARGB_4444 = G2D_ARGB_4444, + COLOR_FORMAT_BGRA_4444 = G2D_BGRA_4444, + COLOR_FORMAT_ABGR_4444 = G2D_ABGR_4444, + + COLOR_FORMAT_RGBX_4444 = G2D_RGBX_4444, + COLOR_FORMAT_XRGB_4444 = G2D_XRGB_4444, + COLOR_FORMAT_BGRX_4444 = G2D_BGRX_4444, + COLOR_FORMAT_XBGR_4444 = G2D_XBGR_4444, + + COLOR_FORMAT_PACKED_RGB_888 = G2D_PACKED_RGB_888, + COLOR_FORMAT_PACKED_BGR_888 = G2D_PACKED_BGR_888, + COLOR_FORMAT_YUV_420SP, + COLOR_FORMAT_YUV_420P, + COLOR_FORMAT_YUV_420I, + COLOR_FORMAT_YUV_422SP, + COLOR_FORMAT_YUV_422P, + COLOR_FORMAT_YUV_422I, + COLOR_FORMAT_YUYV, + + COLOR_FORMAT_MAX, + }; + + enum ROTATE { + ROTATE_BASE = 0, + ROTATE_0 = G2D_ROT_0, + ROTATE_90 = G2D_ROT_90, + ROTATE_180 = G2D_ROT_180, + ROTATE_270 = G2D_ROT_270, + ROTATE_X_FLIP = G2D_ROT_X_FLIP, + ROTATE_Y_FLIP = G2D_ROT_Y_FLIP, + ROTATE_MAX, + }; + + enum ALPHA_VALUE { + ALPHA_MIN = G2D_ALPHA_BLENDING_MIN, // wholly transparent + ALPHA_MAX = G2D_ALPHA_BLENDING_MAX, // 255 + ALPHA_OPAQUE = G2D_ALPHA_BLENDING_OPAQUE, // opaque + }; + + enum DITHER { + DITHER_BASE = 0, + DITHER_OFF = 0, + DITHER_ON = 1, + DITHER_MAX, + }; +#ifdef __cplusplus +private : + bool m_flagCreate; + +protected : + FimgApi(); + FimgApi(const FimgApi& rhs) {} + virtual ~FimgApi(); + +public: + bool Create(void); + bool Destroy(void); + inline bool FlagCreate(void) { return m_flagCreate; } + bool Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); + bool Sync(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +}; +#endif + +/*--------------------------------------------------------------------------- + * user api extern function + *--------------------------------------------------------------------------- + * usage 1 + * FimgApi * p = createFimgApi(); + * p->Stretch() + * destroyFimgApi(p); + * + * usage 2 + * stretchFimgApi(src, dst, clip, flag); + *-------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +#endif +struct FimgApi * createFimgApi(); + +#ifdef __cplusplus +extern "C" +#endif +void destroyFimgApi(FimgApi * ptrFimgApi); + +#ifdef __cplusplus +extern "C" +#endif +int stretchFimgApi(FimgRect * src, + FimgRect * dst, + FimgClip * clip, + FimgFlag * flag); +#ifdef __cplusplus +extern "C" +#endif +int SyncFimgApi(void); + +#endif //FIMG_API_H diff --git a/exynos4/hal/libfimg3x/FimgC210.cpp b/exynos4/hal/libfimg3x/FimgC210.cpp new file mode 100644 index 0000000..129acae --- /dev/null +++ b/exynos4/hal/libfimg3x/FimgC210.cpp @@ -0,0 +1,478 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +/////////////////////////////////////////////////// +// include +/////////////////////////////////////////////////// +#define LOG_NDEBUG 0 +#define LOG_TAG "FimgC210" +#include + +#include "FimgC210.h" + +namespace android +{ + +//---------------------------------------------------------------------------// +// FimgC210 +//---------------------------------------------------------------------------// + +Mutex FimgC210::m_instanceLock; +int FimgC210::m_curFimgC210Index = 0; +int FimgC210::m_numOfInstance = 0; +FimgApi * FimgC210::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, }; + +//---------------------------------------------------------------------------// + +FimgC210::FimgC210() + : m_g2dFd(0), + m_g2dVirtAddr(NULL), + m_g2dSize(0), + m_g2dSrcVirtAddr(NULL), + m_g2dSrcSize(0), + m_g2dDstVirtAddr(NULL), + m_g2dDstSize(0) +{ + m_lock = new Mutex(Mutex::SHARED, "FimgC210"); +} + +FimgC210::~FimgC210() +{ + delete m_lock; +} + +FimgApi * FimgC210::CreateInstance() +{ + Mutex::Autolock autolock(m_instanceLock); + + FimgApi * ptrFimg = NULL; + + // Using List like RingBuffer... + for(int i = m_curFimgC210Index; i < NUMBER_FIMG_LIST; i++) { + if(m_ptrFimgApiList[i] == NULL) + m_ptrFimgApiList[i] = new FimgC210; + + if(m_ptrFimgApiList[i]->FlagCreate() == false) { + if(m_ptrFimgApiList[i]->Create() == false) { + PRINT("%s::Create(%d) fail\n", __func__, i); + goto CreateInstance_End; + } + else + m_numOfInstance++; + } + + if(i < NUMBER_FIMG_LIST - 1) + m_curFimgC210Index = i + 1; + else + m_curFimgC210Index = 0; + + ptrFimg = m_ptrFimgApiList[i]; + goto CreateInstance_End; + } + +CreateInstance_End : + + return ptrFimg; +} + +void FimgC210::DestroyInstance(FimgApi * ptrFimgApi) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if(m_ptrFimgApiList[i] != NULL + && m_ptrFimgApiList[i] == ptrFimgApi) { + if(m_ptrFimgApiList[i]->FlagCreate() == true + && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i]; + delete tempFimgC210; + m_ptrFimgApiList[i] = NULL; + + m_numOfInstance--; + } + + break; + } + } +} + +void FimgC210::DestroyAllInstance(void) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if(m_ptrFimgApiList[i] != NULL) { + if(m_ptrFimgApiList[i]->FlagCreate() == true + && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i]; + delete tempFimgC210; + m_ptrFimgApiList[i] = NULL; + } + } + } +} + + +bool FimgC210::t_Create(void) +{ + bool ret = true; + + if(m_CreateG2D() == false) { + PRINT("%s::m_CreateG2D() fail \n", __func__); + + if(m_DestroyG2D() == false) + PRINT("%s::m_DestroyG2D() fail \n", __func__); + + ret = false; + } + + return ret; +} + +bool FimgC210::t_Destroy(void) +{ + bool ret = true; + + if(m_DestroyG2D() == false) { + PRINT("%s::m_DestroyG2D() fail \n", __func__); + ret = false; + } + + return ret; +} + +bool FimgC210::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) +{ + #ifdef CHECK_FIMGC210_PERFORMANCE + #define NUM_OF_STEP (10) + StopWatch stopWatch("CHECK_FIMGC210_PERFORMANCE"); + const char * stopWatchName[NUM_OF_STEP]; + nsecs_t stopWatchTime[NUM_OF_STEP]; + int stopWatchIndex = 0; + #endif // CHECK_FIMGC210_PERFORMANCE + + if(m_DoG2D(src, dst, clip, flag) == false) { + goto STRETCH_FAIL; + } + +#ifdef G2D_NONE_BLOCKING_MODE + if(m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto STRETCH_FAIL; + } +#endif + + #ifdef CHECK_FIMGC210_PERFORMANCE + m_PrintFimgC210Performance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); + #endif // CHECK_FIMGC210_PERFORMANCE + + return true; + +STRETCH_FAIL: + return false; + +} + +bool FimgC210::t_Sync(void) +{ +#if 0 + if(ioctl(m_g2dFd, G2D_SYNC) < 0) { + PRINT("%s::G2D_Sync fail\n", __func__); + goto SYNC_FAIL; + } +#else + if(m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto SYNC_FAIL; + } +#endif + return true; + +SYNC_FAIL: + return false; + +} + +bool FimgC210::t_Lock(void) +{ + m_lock->lock(); + return true; +} + +bool FimgC210::t_UnLock(void) +{ + m_lock->unlock(); + return true; +} + +bool FimgC210::m_CreateG2D(void) +{ + void * mmap_base; + + if(m_g2dFd != 0) { + PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd); + return false; + } + +#ifdef G2D_NONE_BLOCKING_MODE + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK); +#else + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR); +#endif + if(m_g2dFd < 0) { + PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno)); + m_g2dFd = 0; + return false; + } + + memset(&m_g2dPoll, 0, sizeof(m_g2dPoll)); + m_g2dPoll.fd = m_g2dFd; + m_g2dPoll.events = POLLOUT | POLLERR; + + return true; +} + +bool FimgC210::m_DestroyG2D(void) +{ + if(m_g2dVirtAddr != NULL) { + munmap(m_g2dVirtAddr, m_g2dSize); + m_g2dVirtAddr = NULL; + m_g2dSize = 0; + } + + if(0 < m_g2dFd) { + close(m_g2dFd); + } + m_g2dFd = 0; + + return true; +} + +//bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, int rotateValue, int alphaValue, int colorKey) +bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag) +{ + g2d_params params; + + memcpy(¶ms.src_rect, src, sizeof(FimgRect)); + memcpy(¶ms.dst_rect, dst, sizeof(FimgRect)); + memcpy(¶ms.clip, clip, sizeof(FimgClip)); + memcpy(¶ms.flag, flag, sizeof(FimgFlag)); + + if(ioctl(m_g2dFd, G2D_BLIT, ¶ms) < 0) { + #if 0 + { + PRINT("---------------------------------------\n"); + PRINT("src.color_format : %d \n", src->color_format); + PRINT("src.full_w : %d \n", src->full_w); + PRINT("src.full_h : %d \n", src->full_h); + PRINT("src.x : %d \n", src->x); + PRINT("src.y : %d \n", src->y); + PRINT("src.w : %d \n", src->w); + PRINT("src.h : %d \n", src->h); + + PRINT("dst.color_format : %d \n", dst->color_format); + PRINT("dst.full_w : %d \n", dst->full_w); + PRINT("dst.full_h : %d \n", dst->full_h); + PRINT("dst.x : %d \n", dst->x); + PRINT("dst.y : %d \n", dst->y); + PRINT("dst.w : %d \n", dst->w); + PRINT("dst.h : %d \n", dst->h); + + PRINT("flag.rotate_val : %d \n", flag->rotate_val); + PRINT("flag.alpha_val : %d(%d) \n", flag->alpha_val); + PRINT("flag.color_key_mode : %d(%d) \n", flag->color_key_mode, flag->color_key_val); + PRINT("---------------------------------------\n"); + } + #endif + + return false; + } + + return true; +} + +inline bool FimgC210::m_PollG2D(struct pollfd * events) +{ + #define G2D_POLL_TIME (1000) + + int ret; + + ret = poll(events, 1, G2D_POLL_TIME); + + if (ret < 0) { + if(ioctl(m_g2dFd, G2D_RESET) < 0) { + PRINT("%s::G2D_RESET fail\n", __func__); + } + PRINT("%s::poll fail \n", __func__); + return false; + } + else if (ret == 0) { + if(ioctl(m_g2dFd, G2D_RESET) < 0) { + PRINT("%s::G2D_RESET fail\n", __func__); + } + PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME); + return false; + } + + return true; +} + +inline bool FimgC210::m_CleanG2D(unsigned int virtAddr, unsigned int size) +{ + g2d_dma_info dma_info = { virtAddr, size }; + + if(ioctl(m_g2dFd, G2D_DMA_CACHE_CLEAN, &dma_info) < 0) { + PRINT("%s::G2D_DMA_CACHE_CLEAN(%d, %d) fail\n", __func__, virtAddr, size); + return false; + } + return true; +} + +inline bool FimgC210::m_FlushG2D (unsigned int virtAddr, unsigned int size) +{ + g2d_dma_info dma_info = { virtAddr, size }; + + if(ioctl(m_g2dFd, G2D_DMA_CACHE_FLUSH, &dma_info) < 0) { + PRINT("%s::G2D_DMA_CACHE_FLUSH(%d, %d) fail\n", __func__, virtAddr, size); + return false; + } + return true; +} + +inline int FimgC210::m_RotateValueFimgApi2FimgHw(int rotateValue) +{ + switch (rotateValue) { + case ROTATE_0: return G2D_ROT_0; + case ROTATE_90: return G2D_ROT_90; + case ROTATE_180: return G2D_ROT_180; + case ROTATE_270: return G2D_ROT_270; + case ROTATE_X_FLIP: return G2D_ROT_X_FLIP; + case ROTATE_Y_FLIP: return G2D_ROT_Y_FLIP; + } + + return -1; +} + + +#ifdef CHECK_FIMGC210_PERFORMANCE +void FimgC210::m_PrintFimgC210Performance(FimgRect * src, + FimgRect * dst, + int stopWatchIndex, + const char * stopWatchName[], + nsecs_t stopWatchTime[]) +{ + char * srcColorFormat = "UNKNOW_COLOR_FORMAT"; + char * dstColorFormat = "UNKNOW_COLOR_FORMAT"; + + switch(src->color_format) + { + case COLOR_FORMAT_RGB_565 : + srcColorFormat = "RGB_565"; + break; + case COLOR_FORMAT_RGBA_8888 : + srcColorFormat = "RGBA_8888"; + break; + case COLOR_FORMAT_RGBX_8888 : + srcColorFormat = "RGBX_8888"; + break; + default : + srcColorFormat = "UNKNOW_COLOR_FORMAT"; + break; + } + + switch(dst->color_format) + { + case COLOR_FORMAT_RGB_565 : + dstColorFormat = "RGB_565"; + break; + case COLOR_FORMAT_RGBA_8888 : + dstColorFormat = "RGBA_8888"; + break; + case COLOR_FORMAT_RGBX_8888 : + dstColorFormat = "RGBX_8888"; + break; + default : + dstColorFormat = "UNKNOW_COLOR_FORMAT"; + break; + } + + +#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE +#else + PRINT("===============================================\n"); + PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n", + src->w, src->h, srcColorFormat, + dst->w, dst->h, dstColorFormat); +#endif + + nsecs_t totalTime = stopWatchTime[stopWatchIndex - 1]; + + for(int i = 0 ; i < stopWatchIndex; i++) { + nsecs_t sectionTime; + + if(i != 0) + sectionTime = stopWatchTime[i] - stopWatchTime[i-1]; + else + sectionTime = stopWatchTime[i]; + +#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE + if(1500 < (sectionTime / 1000)) // check 1.5 mille second.. +#endif + { + PRINT("===============================================\n"); + PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n", + src->w, src->h, srcColorFormat, + dst->w, dst->h, dstColorFormat); + + PRINT("%20s : %5lld msec(%5.2f %%)\n", + stopWatchName[i], + sectionTime / 1000, + ((float)sectionTime / (float)totalTime) * 100.0f); + } + } + +} +#endif // CHECK_FIMGC210_PERFORMANCE + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" struct FimgApi * createFimgApi() +{ + if (fimgApiAutoFreeThread == 0) + fimgApiAutoFreeThread = new FimgApiAutoFreeThread(); + else + fimgApiAutoFreeThread->SetOneMoreSleep(); + + return FimgC210::CreateInstance(); +} + +extern "C" void destroyFimgApi(FimgApi * ptrFimgApi) +{ + // Dont' call DestrotInstance.. + // return FimgC210::DestroyInstance(ptrFimgApi); +} + +}; // namespace android diff --git a/exynos4/hal/libfimg3x/FimgC210.h b/exynos4/hal/libfimg3x/FimgC210.h new file mode 100644 index 0000000..7aa9a9a --- /dev/null +++ b/exynos4/hal/libfimg3x/FimgC210.h @@ -0,0 +1,197 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2009 Samsung Electronics Co, Ltd. All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_C210_H +#define FIMG_C210_H + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "FimgApi.h" +//#include "FimgMem.h" + +#include "sec_g2d.h" + +//-----------------------------------------------------------------// + +namespace android +{ + +//#define CHECK_FIMGC210_PERFORMANCE +//#define CHECK_FIMGC210_CRITICAL_PERFORMANCE +#define NUMBER_FIMG_LIST (1) // kcoolsw : because of pmem +//#define G2D_NONE_BLOCKING_MODE // Not supported yet. because of sysMMU Page fault +#define GET_RECT_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_REAL_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_START_ADDR(rect) (rect->virt_addr + ((rect->y * rect->full_w) * rect->bytes_per_pixel)) + + +//---------------------------------------------------------------------------// +// class FimgC210 : public FimgBase +//---------------------------------------------------------------------------// +class FimgC210 : public FimgApi +{ +private : + int m_g2dFd; + + unsigned char * m_g2dVirtAddr; + unsigned int m_g2dSize; + unsigned char * m_g2dSrcVirtAddr; + unsigned int m_g2dSrcSize; + unsigned char * m_g2dDstVirtAddr; + unsigned int m_g2dDstSize; + struct pollfd m_g2dPoll; + + Mutex * m_lock; + + static Mutex m_instanceLock; + static int m_curFimgC210Index; + static int m_numOfInstance; + + static FimgApi * m_ptrFimgApiList[NUMBER_FIMG_LIST]; + + +protected : + FimgC210(); + virtual ~FimgC210(); + +public: + static FimgApi * CreateInstance(); + static void DestroyInstance(FimgApi * ptrFimgApi); + static void DestroyAllInstance(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +private: + bool m_CreateG2D(void); + bool m_DestroyG2D(void); + bool SetClipRectl(FimgRect * dst, FimgClip * clip, FimgClip * clipTempMidRect); + + bool m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag); + + inline bool m_PollG2D(struct pollfd * events); + + inline bool m_CleanG2D (unsigned int addr, unsigned int size); + inline bool m_FlushG2D (unsigned int addr, unsigned int size); + + inline int m_ColorFormatFimgApi2FimgHw(int colorFormat); + inline int m_RotateValueFimgApi2FimgHw(int rotateValue); + + #ifdef CHECK_FIMGC210_PERFORMANCE + void m_PrintFimgC210Performance(FimgRect * src, + FimgRect * dst, + int stopWatchIndex, + const char * stopWatchName[], + nsecs_t stopWatchTime[]); + #endif // CHECK_FIMGC210_PERFORMANCE +}; + +//---------------------------------------------------------------------------// +// class FimgApiAutoFreeThread : public Thread +//---------------------------------------------------------------------------// +class FimgApiAutoFreeThread; + +static sp fimgApiAutoFreeThread = 0; + +class FimgApiAutoFreeThread : public Thread +{ + private: + bool mOneMoreSleep; + bool mDestroyed; + + public: + FimgApiAutoFreeThread(void): + //Thread(true), + Thread(false), + mOneMoreSleep(true), + mDestroyed(false) + { } + ~FimgApiAutoFreeThread(void) + { + if(mDestroyed == false) + { + FimgC210::DestroyAllInstance(); + mDestroyed = true; + } + } + + virtual void onFirstRef() + { + run("FimgApiAutoFreeThread", PRIORITY_BACKGROUND); + } + + virtual bool threadLoop() + { + //#define SLEEP_TIME (10000000) // 10 sec + #define SLEEP_TIME (3000000) // 3 sec + //#define SLEEP_TIME (1000000) // 1 sec + + if(mOneMoreSleep == true) + { + mOneMoreSleep = false; + usleep(SLEEP_TIME); + + return true; + } + else + { + if(mDestroyed == false) + { + FimgC210::DestroyAllInstance(); + mDestroyed = true; + } + + fimgApiAutoFreeThread = 0; + + return false; + } + } + + void SetOneMoreSleep(void) + { + mOneMoreSleep = true; + } +}; + +}; // namespace android + +#endif // FIMG_C210_H diff --git a/exynos4/hal/libfimg4x/Android.mk b/exynos4/hal/libfimg4x/Android.mk new file mode 100644 index 0000000..f42da3f --- /dev/null +++ b/exynos4/hal/libfimg4x/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +ifeq ($(BOARD_USES_FIMGAPI),true) + +#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include +LOCAL_C_INCLUDES += external/skia/include/core +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES:= \ + FimgApi.cpp \ + FimgExynos4.cpp + +LOCAL_SHARED_LIBRARIES:= liblog libutils libbinder + +LOCAL_MODULE:= libfimg + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libfimg4x/FimgApi.cpp b/exynos4/hal/libfimg4x/FimgApi.cpp new file mode 100644 index 0000000..ff11b8d --- /dev/null +++ b/exynos4/hal/libfimg4x/FimgApi.cpp @@ -0,0 +1,376 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "SKIA" +#include + +#include "FimgApi.h" + +struct blit_op_table optbl[] = { + { (int)BLIT_OP_SOLID_FILL, "FILL" }, + { (int)BLIT_OP_CLR, "CLR" }, + { (int)BLIT_OP_SRC, "SRC" }, + { (int)BLIT_OP_DST, "DST" }, + { (int)BLIT_OP_SRC_OVER, "SRC_OVER" }, + { (int)BLIT_OP_DST_OVER, "DST_OVER" }, + { (int)BLIT_OP_SRC_IN, "SRC_IN" }, + { (int)BLIT_OP_DST_IN, "DST_IN" }, + { (int)BLIT_OP_SRC_OUT, "SRC_OUT" }, + { (int)BLIT_OP_DST_OUT, "DST_OUT" }, + { (int)BLIT_OP_SRC_ATOP, "SRC_ATOP" }, + { (int)BLIT_OP_DST_ATOP, "DST_ATOP" }, + { (int)BLIT_OP_XOR, "XOR" }, + { (int)BLIT_OP_ADD, "ADD" }, + { (int)BLIT_OP_MULTIPLY, "MULTIPLY" }, + { (int)BLIT_OP_SCREEN, "SCREEN" }, + { (int)BLIT_OP_DARKEN, "DARKEN" }, + { (int)BLIT_OP_LIGHTEN, "LIGHTEN" }, + { (int)BLIT_OP_DISJ_SRC_OVER, "DISJ_SRC_OVER" }, + { (int)BLIT_OP_DISJ_DST_OVER, "DISJ_DST_OVER" }, + { (int)BLIT_OP_DISJ_SRC_IN, "DISJ_SRC_IN" }, + { (int)BLIT_OP_DISJ_DST_IN, "DISJ_DST_IN" }, + { (int)BLIT_OP_DISJ_SRC_OUT, "DISJ_SRC_OUT" }, + { (int)BLIT_OP_DISJ_DST_OUT, "DISJ_DST_OUT" }, + { (int)BLIT_OP_DISJ_SRC_ATOP, "DISJ_SRC_ATOP" }, + { (int)BLIT_OP_DISJ_DST_ATOP, "DISJ_DST_ATOP" }, + { (int)BLIT_OP_DISJ_XOR, "DISJ_XOR" }, + { (int)BLIT_OP_CONJ_SRC_OVER, "CONJ_SRC_OVER" }, + { (int)BLIT_OP_CONJ_DST_OVER, "CONJ_DST_OVER" }, + { (int)BLIT_OP_CONJ_SRC_IN, "CONJ_SRC_IN" }, + { (int)BLIT_OP_CONJ_DST_IN, "CONJ_DST_IN" }, + { (int)BLIT_OP_CONJ_SRC_OUT, "CONJ_SRC_OUT" }, + { (int)BLIT_OP_CONJ_DST_OUT, "CONJ_DST_OUT" }, + { (int)BLIT_OP_CONJ_SRC_ATOP, "CONJ_SRC_ATOP" }, + { (int)BLIT_OP_CONJ_DST_ATOP, "CONJ_DST_ATOP" }, + { (int)BLIT_OP_CONJ_XOR, "CONJ_XOR" }, + { (int)BLIT_OP_USER_COEFF, "USER_COEFF" }, + { (int)BLIT_OP_END, "" }, +}; + +#ifndef REAL_DEBUG + void VOID_FUNC(const char *format, ...) + {} +#endif + +FimgApi::FimgApi() +{ + m_flagCreate = false; +} + +FimgApi::~FimgApi() +{ + if (m_flagCreate == true) + PRINT("%s::this is not Destroyed fail\n", __func__); +} + +bool FimgApi::Create(void) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto CREATE_DONE; + } + + if (m_flagCreate == true) { + PRINT("%s::Already Created fail\n", __func__); + goto CREATE_DONE; + } + + if (t_Create() == false) { + PRINT("%s::t_Create() fail\n", __func__); + goto CREATE_DONE; + } + + m_flagCreate = true; + + ret = true; + +CREATE_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Destroy(void) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto DESTROY_DONE; + } + + if (m_flagCreate == false) { + PRINT("%s::Already Destroyed fail\n", __func__); + goto DESTROY_DONE; + } + + if (t_Destroy() == false) { + PRINT("%s::t_Destroy() fail\n", __func__); + goto DESTROY_DONE; + } + + m_flagCreate = false; + + ret = true; + +DESTROY_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Stretch(struct fimg2d_blit *cmd) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto STRETCH_DONE; + } + + if (m_flagCreate == false) { + PRINT("%s::This is not Created fail\n", __func__); + goto STRETCH_DONE; + } + + if (t_Stretch(cmd) == false) { + goto STRETCH_DONE; + } + + ret = true; + +STRETCH_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Sync(void) +{ + bool ret = false; + + if (m_flagCreate == false) { + PRINT("%s::This is not Created fail\n", __func__); + goto SYNC_DONE; + } + + if (t_Sync() == false) + goto SYNC_DONE; + + ret = true; + +SYNC_DONE : + + return ret; +} + +bool FimgApi::t_Create(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Destroy(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Stretch(struct fimg2d_blit *cmd) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Sync(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Lock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_UnLock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" int stretchFimgApi(struct fimg2d_blit *cmd) +{ + FimgApi * fimgApi = createFimgApi(); + + if (fimgApi == NULL) { + PRINT("%s::createFimgApi() fail\n", __func__); + return -1; + } + + if (fimgApi->Stretch(cmd) == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + +extern "C" int SyncFimgApi(void) +{ + FimgApi * fimgApi = createFimgApi(); + if (fimgApi == NULL) { + PRINT("%s::createFimgApi() fail\n", __func__); + return -1; + } + + if (fimgApi->Sync() == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + +void printDataBlit(char *title, struct fimg2d_blit *cmd) +{ + LOGI("%s\n", title); + + LOGI(" sequence_no. = %u\n", cmd->seq_no); + LOGI(" blit_op = %d(%s)\n", cmd->op, optbl[cmd->op].str); + LOGI(" fill_color = %X\n", cmd->solid_color); + LOGI(" global_alpha = %u\n", (unsigned int)cmd->g_alpha); + LOGI(" PREMULT = %s\n", cmd->premult == PREMULTIPLIED ? "PREMULTIPLIED" : "NON-PREMULTIPLIED"); + LOGI(" do_dither = %s\n", cmd->dither == true ? "dither" : "no-dither"); + + printDataBlitRotate(cmd->rotate); + + printDataBlitScale(cmd->scaling); + + printDataBlitImage("SRC", cmd->src); + printDataBlitImage("DST", cmd->dst); + printDataBlitImage("MSK", cmd->msk); + + printDataBlitRect("SRC", cmd->src_rect); + printDataBlitRect("DST", cmd->dst_rect); + printDataBlitRect("MSK", cmd->msk_rect); + + printDataBlitClip(cmd->clipping); +} + +void printDataBlitImage(char *title, struct fimg2d_image *image) +{ + if (NULL != image) { + LOGI(" Image_%s\n", title); + LOGI(" addr = %X\n", image->addr.start); + LOGI(" size = %u\n", image->addr.size); + LOGI(" (width, height) = (%d, %d)\n", image->width, image->height); + LOGI(" format = %d\n", image->fmt); + } else + LOGI(" Image_%s : NULL\n", title); +} + +void printDataBlitRect(char *title, struct fimg2d_rect *rect) +{ + if (NULL != rect) { + LOGI(" RECT_%s\n", title); + LOGI(" (x1, y1) = (%d, %d)\n", rect->x1, rect->y1); + LOGI(" (x2, y2) = (%d, %d)\n", rect->x2, rect->y2); + LOGI(" (width, height) = (%d, %d)\n", rect->x2 - rect->x1, rect->y2 - rect->y1); + } else + LOGI(" RECT_%s : NULL\n", title); +} + +void printDataBlitRotate(enum rotation rotate) +{ + LOGI(" ROTATE : %d\n", rotate); +} + +void printDataBlitClip(struct fimg2d_clip *clip) +{ + if (NULL != clip) { + LOGI(" CLIP\n"); + LOGI(" clip %s\n", clip->enable == true ? "enabled" : "disabled"); + LOGI(" (x1, y1) = (%d, %d)\n", clip->x1, clip->y1); + LOGI(" (x2, y2) = (%d, %d)\n", clip->x2, clip->y2); + LOGI(" (width, hight) = (%d, %d)\n", clip->x2 - clip->x1, clip->y2 - clip->y1); + } else + LOGI(" CLIP : NULL\n"); +} + +void printDataBlitScale(struct fimg2d_scale *scaling) +{ + if (NULL != scaling) { + LOGI(" SCALING\n"); + LOGI(" scale_mode : %s\n", scaling->mode == 0 ? + "NO_SCALING" : + (scaling->mode == 1 ? "SCALING_NEAREST" : "SCALING_BILINEAR")); + LOGI(" scaling_factor_unit : %s\n", scaling->factor == 0 ? "PERCENT" : "PIXEL"); + + if (scaling->factor == 0) + LOGI(" scaling_factor : (scale_w, scale_y) = (%d, %d)\n", scaling->scale_w, scaling->scale_h); + else { + LOGI(" src : (src_w, src_h) = (%d, %d)\n", scaling->src_w, scaling->src_h); + LOGI(" dst : (dst_w, dst_h) = (%d, %d)\n", scaling->dst_w, scaling->dst_h); + LOGI(" scaling_factor : (scale_w, scale_y) = (%3.2f, %3.2f)\n", (double)scaling->dst_w / scaling->src_w, (double)scaling->dst_h / scaling->src_h); + } + } else + LOGI(" SCALING : NULL(NO SCALE MODE)\n"); + +} + +void printDataMatrix(int matrixType) +{ + LOGI(" MATRIX\n"); + + if (matrixType & SkMatrix::kIdentity_Mask) + LOGI(" Matrix_type : Identity_Mask\n"); + + if (matrixType & SkMatrix::kTranslate_Mask) + LOGI(" Matrix_type : Translate_Mask(the matrix has translation)\n"); + + if (matrixType & SkMatrix::kScale_Mask) + LOGI(" Matrix_type : Scale_Mask(the matrix has X or Y scale)\n"); + + if (matrixType & SkMatrix::kAffine_Mask) + LOGI(" Matrix_type : Affine_Mask(the matrix skews or rotates)\n"); + + if (matrixType & SkMatrix::kPerspective_Mask) + LOGI(" Matrix_type : Perspective_Mask(the matrix is in perspective)\n"); +} diff --git a/exynos4/hal/libfimg4x/FimgApi.h b/exynos4/hal/libfimg4x/FimgApi.h new file mode 100644 index 0000000..a2c9eac --- /dev/null +++ b/exynos4/hal/libfimg4x/FimgApi.h @@ -0,0 +1,114 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_API_H +#define FIMG_API_H + +#include +#include "SkMatrix.h" +#include "sec_g2d_4x.h" + +#define REAL_DEBUG +#define ANDROID_LOG + +#if defined(REAL_DEBUG) +#ifdef ANDROID_LOG +#define PRINT LOGE +#define PRINTD LOGD +#else +#define PRINT printf +#define PRINTD printf +#endif +#else +void VOID_FUNC(const char *format, ...); + +#define PRINT VOID_FUNC +#define PRINTD VOID_FUNC +#endif + +#ifdef __cplusplus + +struct blit_op_table { + int op; + const char *str; +}; + +extern struct blit_op_table optbl[]; + +class FimgApi +{ +public: +#endif + +#ifdef __cplusplus +private : + bool m_flagCreate; + +protected : + FimgApi(); + FimgApi(const FimgApi& rhs) {} + virtual ~FimgApi(); + +public: + bool Create(void); + bool Destroy(void); + inline bool FlagCreate(void) { return m_flagCreate; } + bool Stretch(struct fimg2d_blit *cmd); + bool Sync(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(struct fimg2d_blit *cmd); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +}; +#endif + +#ifdef __cplusplus +extern "C" +#endif +struct FimgApi *createFimgApi(); + +#ifdef __cplusplus +extern "C" +#endif +void destroyFimgApi(FimgApi *ptrFimgApi); + +#ifdef __cplusplus +extern "C" +#endif +int stretchFimgApi(struct fimg2d_blit *cmd); +#ifdef __cplusplus +extern "C" +#endif +int SyncFimgApi(void); + +void printDataBlit(char *title, struct fimg2d_blit *cmd); +void printDataBlitRotate(enum rotation rotate); +void printDataBlitImage(char *title, struct fimg2d_image *image); +void printDataBlitRect(char *title, struct fimg2d_rect *rect); +void printDataBlitClip(struct fimg2d_clip *clip); +void printDataBlitScale(struct fimg2d_scale *scaling); +void printDataMatrix(int matrixType); + +#endif //FIMG_API_H diff --git a/exynos4/hal/libfimg4x/FimgExynos4.cpp b/exynos4/hal/libfimg4x/FimgExynos4.cpp new file mode 100644 index 0000000..f9a7f1e --- /dev/null +++ b/exynos4/hal/libfimg4x/FimgExynos4.cpp @@ -0,0 +1,302 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "FimgExynos4" +#include + +#include "FimgExynos4.h" + +namespace android +{ +Mutex FimgV4x::m_instanceLock; +unsigned FimgV4x::m_curFimgV4xIndex = 0; +int FimgV4x::m_numOfInstance = 0; +FimgApi * FimgV4x::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, }; + +//---------------------------------------------------------------------------// + +FimgV4x::FimgV4x() + : m_g2dFd(0), + m_g2dVirtAddr(NULL), + m_g2dSize(0), + m_g2dSrcVirtAddr(NULL), + m_g2dSrcSize(0), + m_g2dDstVirtAddr(NULL), + m_g2dDstSize(0) +{ + memset(&(m_g2dPoll), 0, sizeof(struct pollfd)); + m_lock = new Mutex(Mutex::SHARED, "FimgV4x"); +} + +FimgV4x::~FimgV4x() +{ + delete m_lock; +} + +FimgApi *FimgV4x::CreateInstance() +{ + Mutex::Autolock autolock(m_instanceLock); + + FimgApi *ptrFimg = NULL; + + for(unsigned int i = m_curFimgV4xIndex; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] == NULL) + m_ptrFimgApiList[i] = new FimgV4x; + + if (m_ptrFimgApiList[i]->FlagCreate() == false) { + if (m_ptrFimgApiList[i]->Create() == false) { + PRINT("%s::Create(%d) fail\n", __func__, i); + goto CreateInstance_End; + } + else + m_numOfInstance++; + } + + if (i < NUMBER_FIMG_LIST - 1) + m_curFimgV4xIndex = i + 1; + else + m_curFimgV4xIndex = 0; + + ptrFimg = m_ptrFimgApiList[i]; + goto CreateInstance_End; + } + +CreateInstance_End : + + return ptrFimg; +} + +void FimgV4x::DestroyInstance(FimgApi * ptrFimgApi) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] != NULL && m_ptrFimgApiList[i] == ptrFimgApi) { + if (m_ptrFimgApiList[i]->FlagCreate() == true && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; + delete tempFimgV4x; + m_ptrFimgApiList[i] = NULL; + + m_numOfInstance--; + } + + break; + } + } +} + +void FimgV4x::DestroyAllInstance(void) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] != NULL) { + if (m_ptrFimgApiList[i]->FlagCreate() == true + && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; + delete tempFimgV4x; + m_ptrFimgApiList[i] = NULL; + } + } + } +} + +bool FimgV4x::t_Create(void) +{ + bool ret = true; + + if (m_CreateG2D() == false) { + PRINT("%s::m_CreateG2D() fail \n", __func__); + + if (m_DestroyG2D() == false) + PRINT("%s::m_DestroyG2D() fail \n", __func__); + + ret = false; + } + + return ret; +} + +bool FimgV4x::t_Destroy(void) +{ + bool ret = true; + + if (m_DestroyG2D() == false) { + PRINT("%s::m_DestroyG2D() fail \n", __func__); + ret = false; + } + + return ret; +} + +bool FimgV4x::t_Stretch(struct fimg2d_blit *cmd) +{ +#ifdef CHECK_FIMGV4x_PERFORMANCE +#define NUM_OF_STEP (10) + StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE"); + const char *stopWatchName[NUM_OF_STEP]; + nsecs_t stopWatchTime[NUM_OF_STEP]; + int stopWatchIndex = 0; +#endif // CHECK_FIMGV4x_PERFORMANCE + + if (m_DoG2D(cmd) == false) { + goto STRETCH_FAIL; + } + +#ifdef G2D_NONE_BLOCKING_MODE + if (m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto STRETCH_FAIL; + } +#endif + + #ifdef CHECK_FIMGV4x_PERFORMANCE + m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); + #endif // CHECK_FIMGV4x_PERFORMANCE + + return true; + +STRETCH_FAIL: + return false; + +} + +bool FimgV4x::t_Sync(void) +{ + if (m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto SYNC_FAIL; + } + return true; + +SYNC_FAIL: + return false; + +} + +bool FimgV4x::t_Lock(void) +{ + m_lock->lock(); + return true; +} + +bool FimgV4x::t_UnLock(void) +{ + m_lock->unlock(); + return true; +} + +bool FimgV4x::m_CreateG2D(void) +{ + void * mmap_base; + + if (m_g2dFd != 0) { + PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd); + return false; + } + +#ifdef G2D_NONE_BLOCKING_MODE + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK); +#else + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR); +#endif + if (m_g2dFd < 0) { + PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno)); + m_g2dFd = 0; + return false; + } + + memset(&m_g2dPoll, 0, sizeof(m_g2dPoll)); + m_g2dPoll.fd = m_g2dFd; + m_g2dPoll.events = POLLOUT | POLLERR; + + return true; +} + +bool FimgV4x::m_DestroyG2D(void) +{ + if (m_g2dVirtAddr != NULL) { + munmap(m_g2dVirtAddr, m_g2dSize); + m_g2dVirtAddr = NULL; + m_g2dSize = 0; + } + + if (0 < m_g2dFd) { + close(m_g2dFd); + } + m_g2dFd = 0; + + return true; +} + +bool FimgV4x::m_DoG2D(struct fimg2d_blit *cmd) +{ + + if (ioctl(m_g2dFd, FIMG2D_BITBLT_BLIT, cmd) < 0) + return false; + + return true; +} + +inline bool FimgV4x::m_PollG2D(struct pollfd * events) +{ +#define G2D_POLL_TIME (1000) + + int ret; + + ret = poll(events, 1, G2D_POLL_TIME); + + if (ret < 0) { + PRINT("%s::poll fail \n", __func__); + return false; + } + else if (ret == 0) { + PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME); + return false; + } + + return true; +} + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" struct FimgApi * createFimgApi() +{ + if (fimgApiAutoFreeThread == 0) + fimgApiAutoFreeThread = new FimgApiAutoFreeThread(); + else + fimgApiAutoFreeThread->SetOneMoreSleep(); + + return FimgV4x::CreateInstance(); +} + +extern "C" void destroyFimgApi(FimgApi * ptrFimgApi) +{ + // Dont' call DestroyInstance. +} + +}; // namespace android diff --git a/exynos4/hal/libfimg4x/FimgExynos4.h b/exynos4/hal/libfimg4x/FimgExynos4.h new file mode 100644 index 0000000..2a7c42f --- /dev/null +++ b/exynos4/hal/libfimg4x/FimgExynos4.h @@ -0,0 +1,169 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2009 Samsung Electronics Co, Ltd. All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_EXYNOS4_H +#define FIMG_EXYNOS4_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "FimgApi.h" + +#include "sec_g2d_4x.h" + +namespace android +{ + +#define NUMBER_FIMG_LIST (1) // kcoolsw : because of pmem +#define GET_RECT_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_REAL_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_START_ADDR(rect) (rect->virt_addr + ((rect->y * rect->full_w) * rect->bytes_per_pixel)) +#define SLEEP_TIME (3000000) // 3 sec + +//---------------------------------------------------------------------------// +// class FimgV4x : public FimgBase +//---------------------------------------------------------------------------// +class FimgV4x : public FimgApi +{ +private : + int m_g2dFd; + + unsigned char *m_g2dVirtAddr; + unsigned int m_g2dSize; + unsigned char *m_g2dSrcVirtAddr; + unsigned int m_g2dSrcSize; + unsigned char *m_g2dDstVirtAddr; + unsigned int m_g2dDstSize; + struct pollfd m_g2dPoll; + + Mutex *m_lock; + + static Mutex m_instanceLock; + static unsigned m_curFimgV4xIndex; + static int m_numOfInstance; + + static FimgApi *m_ptrFimgApiList[NUMBER_FIMG_LIST]; + +protected : + FimgV4x(); + virtual ~FimgV4x(); + +public: + static FimgApi *CreateInstance(); + static void DestroyInstance(FimgApi *ptrFimgApi); + static void DestroyAllInstance(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(struct fimg2d_blit *cmd); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +private: + bool m_CreateG2D(void); + bool m_DestroyG2D(void); + + bool m_DoG2D(struct fimg2d_blit *cmd); + + inline bool m_PollG2D(struct pollfd *events); + + inline int m_ColorFormatFimgApi2FimgHw(int colorFormat); +}; + +class FimgApiAutoFreeThread; + +static sp fimgApiAutoFreeThread = 0; + +class FimgApiAutoFreeThread : public Thread +{ +private: + bool mOneMoreSleep; + bool mDestroyed; + +public: + FimgApiAutoFreeThread(void): + Thread(false), + mOneMoreSleep(true), + mDestroyed(false) + { } + ~FimgApiAutoFreeThread(void) + { + if (mDestroyed == false) + { + FimgV4x::DestroyAllInstance(); + mDestroyed = true; + } + } + + virtual void onFirstRef() + { + run("FimgApiAutoFreeThread", PRIORITY_BACKGROUND); + } + + virtual bool threadLoop() + { + + if (mOneMoreSleep == true) + { + mOneMoreSleep = false; + usleep(SLEEP_TIME); + + return true; + } + else + { + if (mDestroyed == false) + { + FimgV4x::DestroyAllInstance(); + mDestroyed = true; + } + + fimgApiAutoFreeThread = 0; + + return false; + } + } + + void SetOneMoreSleep(void) + { + mOneMoreSleep = true; + } +}; + +}; // namespace android + +#endif // FIMG_EXYNOS4_H diff --git a/exynos4/hal/libfimg4x/sec_g2d_4x.h b/exynos4/hal/libfimg4x/sec_g2d_4x.h new file mode 100644 index 0000000..b9ddbb2 --- /dev/null +++ b/exynos4/hal/libfimg4x/sec_g2d_4x.h @@ -0,0 +1,326 @@ +/* + * Copyright 2011, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __SEC_G2D_4X_H +#define __SEC_G2D_4X_H __FILE__ + +#define SEC_G2D_DEV_NAME "/dev/fimg2d" + +/* ioctl commands */ +#define FIMG2D_IOCTL_MAGIC 'F' +#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit) +#define FIMG2D_BITBLT_SYNC _IO(FIMG2D_IOCTL_MAGIC, 1) +#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version) + +#define G2D_ALPHA_VALUE_MAX (255) + +enum addr_space { + ADDR_UNKNOWN, + ADDR_PHYS, + ADDR_KERN, + ADDR_USER, + ADDR_DEVICE, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum pixel_order { + AX_RGB = 0, + RGB_AX, + AX_BGR, + BGR_AX, + ARGB_ORDER_END, + + P1_CRY1CBY0, + P1_CBY1CRY0, + P1_Y1CRY0CB, + P1_Y1CBY0CR, + P1_ORDER_END, + + P2_CRCB, + P2_CBCR, + P2_ORDER_END, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum color_format { + CF_XRGB_8888 = 0, + CF_ARGB_8888, + CF_RGB_565, + CF_XRGB_1555, + CF_ARGB_1555, + CF_XRGB_4444, + CF_ARGB_4444, + CF_RGB_888, + CF_YCBCR_444, + CF_YCBCR_422, + CF_YCBCR_420, + CF_A8, + CF_L8, + SRC_DST_FORMAT_END, + + CF_MSK_1BIT, + CF_MSK_4BIT, + CF_MSK_8BIT, + CF_MSK_16BIT_565, + CF_MSK_16BIT_1555, + CF_MSK_16BIT_4444, + CF_MSK_32BIT_8888, + MSK_FORMAT_END, +}; + +enum rotation { + ORIGIN, + ROT_90, /* clockwise */ + ROT_180, + ROT_270, + XFLIP, /* x-axis flip */ + YFLIP, /* y-axis flip */ +}; + +/** + * @NO_REPEAT: no effect + * @REPEAT_NORMAL: repeat horizontally and vertically + * @REPEAT_PAD: pad with pad color + * @REPEAT_REFLECT: reflect horizontally and vertically + * @REPEAT_CLAMP: pad with edge color of original image + * + * DO NOT CHANGE THIS ORDER + */ +enum repeat { + NO_REPEAT = 0, + REPEAT_NORMAL, /* default setting */ + REPEAT_PAD, + REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT, + REPEAT_CLAMP, +}; + +enum scaling { + NO_SCALING, + SCALING_NEAREST, + SCALING_BILINEAR, +}; + +/** + * @SCALING_PERCENTAGE: percentage of width, height + * @SCALING_PIXELS: coordinate of src, dest + */ +enum scaling_factor { + SCALING_PERCENTAGE, + SCALING_PIXELS, +}; + +/** + * premultiplied alpha + */ +enum premultiplied { + PREMULTIPLIED, + NON_PREMULTIPLIED, +}; + +/** + * @TRANSP: discard bluescreen color + * @BLUSCR: replace bluescreen color with background color + */ +enum bluescreen { + OPAQUE, + TRANSP, + BLUSCR, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum blit_op { + BLIT_OP_SOLID_FILL = 0, + + BLIT_OP_CLR, + BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC, + BLIT_OP_DST, + BLIT_OP_SRC_OVER, + BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER, + BLIT_OP_SRC_IN, + BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN, + BLIT_OP_SRC_OUT, + BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT, + BLIT_OP_SRC_ATOP, + BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP, + BLIT_OP_XOR, + + BLIT_OP_ADD, + BLIT_OP_MULTIPLY, + BLIT_OP_SCREEN, + BLIT_OP_DARKEN, + BLIT_OP_LIGHTEN, + + BLIT_OP_DISJ_SRC_OVER, + BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER, + BLIT_OP_DISJ_SRC_IN, + BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN, + BLIT_OP_DISJ_SRC_OUT, + BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT, + BLIT_OP_DISJ_SRC_ATOP, + BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP, + BLIT_OP_DISJ_XOR, + + BLIT_OP_CONJ_SRC_OVER, + BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER, + BLIT_OP_CONJ_SRC_IN, + BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN, + BLIT_OP_CONJ_SRC_OUT, + BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT, + BLIT_OP_CONJ_SRC_ATOP, + BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP, + BLIT_OP_CONJ_XOR, + + /* Add new operation type here */ + + /* user select coefficient manually */ + BLIT_OP_USER_COEFF, + + /* end of blit operation */ + BLIT_OP_END, + + /* driver not supporting format */ + BLIT_OP_NOT_SUPPORTED +}; + +#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END + +struct fimg2d_version { + unsigned int hw; + unsigned int sw; +}; + +/** + * @start: start address or unique id of image + * @size: whole length of allocated image + * @cacheable: memory is cacheable + * @pinnable: memory is pinnable. currently not supported. + */ +struct fimg2d_addr { + enum addr_space type; + unsigned long start; + size_t size; + int cacheable; + int pinnable; +}; + +struct fimg2d_rect { + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +/** + * if factor is percentage, scale_w and scale_h are valid + * if factor is pixels, src_w, src_h, dst_w, dst_h are valid + */ +struct fimg2d_scale { + enum scaling mode; + enum scaling_factor factor; + + /* percentage */ + int scale_w; + int scale_h; + + /* pixels */ + int src_w, src_h; + int dst_w, dst_h; +}; + +/** + * coordinate from start address(0,0) of image + */ +struct fimg2d_clip { + bool enable; + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +struct fimg2d_repeat { + enum repeat mode; + unsigned long pad_color; +}; + +/** + * @bg_color: bg_color is valid only if bluescreen mode is BLUSCR. + */ +struct fimg2d_bluscr { + enum bluescreen mode; + unsigned long bs_color; + unsigned long bg_color; +}; + +/** + * @plane2: address info for CbCr in YCbCr 2plane mode + */ +struct fimg2d_image { + struct fimg2d_addr addr; + struct fimg2d_addr plane2; + int width; + int height; + int stride; + enum pixel_order order; + enum color_format fmt; +}; + +struct fimg2d_param { + enum blit_op op; + unsigned long fillcolor; + unsigned char g_alpha; + enum premultiplied premult; + bool dither; + enum rotation rotate; + struct fimg2d_scale *scaling; + struct fimg2d_repeat *repeat; + struct fimg2d_bluscr *bluscr; + struct fimg2d_clip *clipping; +}; + +/** + * @g_alpha: 0xff is opaque, 0x0 is transparnet + * @seq_no: used for debugging + */ +struct fimg2d_blit { + enum blit_op op; + + enum premultiplied premult; + unsigned char g_alpha; + bool dither; + enum rotation rotate; + struct fimg2d_scale *scaling; + struct fimg2d_repeat *repeat; + struct fimg2d_bluscr *bluscr; + struct fimg2d_clip *clipping; + + unsigned long solid_color; + struct fimg2d_image *src; + struct fimg2d_image *dst; + struct fimg2d_image *msk; + + struct fimg2d_rect *src_rect; + struct fimg2d_rect *dst_rect; + struct fimg2d_rect *msk_rect; + + unsigned int seq_no; +}; +#endif /* __SEC_G2D_4X_H__ */ diff --git a/exynos4/hal/libgralloc_ump/Android.mk b/exynos4/hal/libgralloc_ump/Android.mk new file mode 100644 index 0000000..20584a4 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/Android.mk @@ -0,0 +1,56 @@ +# +# Copyright (C) 2010 ARM Limited. All rights reserved. +# +# Portions of this code have been modified from the original. +# These modifications are: +# * The build configuration for the Gralloc module +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +# HAL module implemenation, not prelinked and stored in +# hw/..so +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils libUMP libGLESv1_CM libion + +# Include the UMP header files +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := \ + gralloc_module.cpp \ + alloc_device.cpp \ + framebuffer_device.cpp + +LOCAL_MODULE_TAGS := eng +#LOCAL_MODULE := gralloc.default +LOCAL_MODULE := gralloc.$(TARGET_DEVICE) +LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -DGRALLOC_32_BITS -DSTANDARD_LINUX_SCREEN +#LOCAL_CFLAGS+= -DMALI_VSYNC_EVENT_REPORT_ENABLE + +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS_CACHE_UMP + +ifeq ($(TARGET_SOC),exynos4210) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libgralloc_ump/alloc_device.cpp b/exynos4/hal/libgralloc_ump/alloc_device.cpp new file mode 100644 index 0000000..982f1b8 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/alloc_device.cpp @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * gralloc_alloc_buffer() + * * gralloc_alloc_framebuffer_locked() + * * gralloc_alloc_framebuffer() + * * alloc_device_alloc() + * * alloc_device_free() + * * alloc_device_close() + * * alloc_device_open() + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include "sec_format.h" + +#include "gralloc_priv.h" +#include "gralloc_helper.h" +#include "framebuffer_device.h" + +#include "ump.h" +#include "ump_ref_drv.h" + +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if HAVE_ANDROID_OS +#include +#include +#endif + +#include "videodev2.h" +#include "s5p_fimc.h" + +#ifdef SAMSUNG_EXYNOS4x12 +#define PFX_NODE_FIMC1 "/dev/video3" +#endif +#ifdef SAMSUNG_EXYNOS4210 +#define PFX_NODE_FIMC1 "/dev/video1" +#endif + +#ifndef OMX_COLOR_FormatYUV420Planar +#define OMX_COLOR_FormatYUV420Planar 0x13 +#endif + +#ifndef OMX_COLOR_FormatYUV420SemiPlanar +#define OMX_COLOR_FormatYUV420SemiPlanar 0x15 +#endif + +bool ion_dev_open = true; +static pthread_mutex_t l_surface= PTHREAD_MUTEX_INITIALIZER; +static int buffer_offset = 0; +static int gfd = 0; + +#ifdef USE_PARTIAL_FLUSH +extern struct private_handle_rect *rect_list; +extern private_handle_rect *find_rect(int secure_id); +extern private_handle_rect *find_last_rect(int secure_id); +extern int release_rect(int secure_id); +#endif + +#define EXYNOS4_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) + +static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp, int stride_raw, int stride) +{ + ump_handle ump_mem_handle; + void *cpu_ptr; + ump_secure_id ump_id; + + size = round_up_to_page_size(size); + if (usage & GRALLOC_USAGE_HW_FIMC1) { + int dev_fd=0; + char node[20]; + int ret; + int paddr=0; + int offset=0; + + struct v4l2_control vc; + sprintf(node, "%s", PFX_NODE_FIMC1); + + if (gfd == 0) { + gfd = open(node, O_RDWR); + + if (gfd < 0) { + LOGE("%s:: %s Post processor open error\n", __func__, node); + return false; + } + } + + vc.id = V4L2_CID_RESERVED_MEM_BASE_ADDR; + vc.value = 0; + ret = ioctl(gfd, VIDIOC_G_CTRL, &vc); + if (ret < 0) { + LOGE("Error in video VIDIOC_G_CTRL - V4L2_CID_RESERVED_MEM_BAES_ADDR (%d)\n", ret); + return false; + } + paddr = (unsigned int)vc.value; + + if ((buffer_offset + size) >= FIMC1_RESERVED_SIZE * 1024) + buffer_offset = 0; + + paddr += buffer_offset; + private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_IOCTL, size, 0, + private_handle_t::LOCK_STATE_MAPPED, 0, 0); + + *pHandle = hnd; + hnd->format = format; + hnd->usage = usage; + hnd->width = w; + hnd->height = h; + hnd->bpp = bpp; + hnd->paddr = paddr; + hnd->offset = buffer_offset; + hnd->stride = stride; + hnd->fd = gfd; + hnd->uoffset = (EXYNOS4_ALIGN((EXYNOS4_ALIGN(hnd->width, 16) * EXYNOS4_ALIGN(hnd->height, 16)), 4096)); + hnd->voffset = (EXYNOS4_ALIGN((EXYNOS4_ALIGN((hnd->width >> 1), 16) * EXYNOS4_ALIGN((hnd->height >> 1), 16)), 4096)); + buffer_offset += size; + + return 0; + } else { + ion_buffer ion_fd = 0; + unsigned int ion_flags = 0; + int priv_alloc_flag = private_handle_t::PRIV_FLAGS_USES_UMP; + + if (usage & GRALLOC_USAGE_HW_ION) { + if (!ion_dev_open) { + LOGE("ERROR, failed to open ion"); + return -1; + } + + private_module_t* m = reinterpret_cast(dev->common.module); + ion_flags = ION_HEAP_EXYNOS_MASK; + ion_fd = ion_alloc(m->ion_client, size, 0, ion_flags); + + if (ion_fd < 0) { + LOGE("Failed to ion_alloc"); + return -1; + } + + cpu_ptr = ion_map(ion_fd, size, 0); + + if (NULL == cpu_ptr) { + LOGE("Failed to ion_map"); + ion_free(ion_fd); + return -1; + } + + ump_mem_handle = ump_ref_drv_ion_import(ion_fd, UMP_REF_DRV_CONSTRAINT_NONE); + + if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { + priv_alloc_flag = private_handle_t::PRIV_FLAGS_USES_ION; + } else { + LOGE("gralloc_alloc_buffer() failed to import ION memory"); + ion_unmap(cpu_ptr, size); + ion_free(ion_fd); + return -1; + } + } +#ifdef SAMSUNG_EXYNOS_CACHE_UMP + else if ((usage&GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) + ump_mem_handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_USE_CACHE); + else + ump_mem_handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_NONE); +#else + else + ump_mem_handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_NONE); +#endif + if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { + if (!(usage & GRALLOC_USAGE_HW_ION)) + cpu_ptr = ump_mapped_pointer_get(ump_mem_handle); + if (NULL != cpu_ptr) { + ump_id = ump_secure_id_get(ump_mem_handle); + if (UMP_INVALID_SECURE_ID != ump_id) { + private_handle_t* hnd; + hnd = new private_handle_t(priv_alloc_flag, size, (int)cpu_ptr, + private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle, ion_fd, 0, 0); + if (NULL != hnd) { + *pHandle = hnd; +#ifdef USE_PARTIAL_FLUSH + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + private_handle_rect *psRect; + private_handle_rect *psFRect; + psRect = (private_handle_rect *)calloc(1, sizeof(private_handle_rect)); + psRect->handle = (int)hnd->ump_id; + psRect->stride = (int)hnd->stride_raw; + psFRect = find_last_rect((int)hnd->ump_id); + psFRect->next = psRect; + } +#endif + hnd->format = format; + hnd->usage = usage; + hnd->width = w; + hnd->height = h; + hnd->bpp = bpp; + hnd->stride = stride; + hnd->uoffset = ((EXYNOS4_ALIGN(hnd->width, 16) * EXYNOS4_ALIGN(hnd->height, 16))); + hnd->voffset = ((EXYNOS4_ALIGN((hnd->width >> 1), 16) * EXYNOS4_ALIGN((hnd->height >> 1), 16))); + return 0; + } else { + LOGE("gralloc_alloc_buffer() failed to allocate handle"); + } + } else { + LOGE("gralloc_alloc_buffer() failed to retrieve valid secure id"); + } + + ump_mapped_pointer_release(ump_mem_handle); + } else { + LOGE("gralloc_alloc_buffer() failed to map UMP memory"); + } + + ump_reference_release(ump_mem_handle); + } else { + LOGE("gralloc_alloc_buffer() failed to allcoate UMP memory"); + } + } + return -1; +} + +static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp) +{ + private_module_t* m = reinterpret_cast(dev->common.module); + /* allocate the framebuffer */ + if (m->framebuffer == NULL) { + /* initialize the framebuffer, the framebuffer is mapped once and forever. */ + int err = init_frame_buffer_locked(m); + if (err < 0) + return err; + } + + const uint32_t bufferMask = m->bufferMask; + const uint32_t numBuffers = m->numBuffers; + const size_t bufferSize = m->finfo.line_length * m->info.yres; + if (numBuffers == 1) { + /* + * If we have only one buffer, we never use page-flipping. Instead, + * we return a regular buffer which will be memcpy'ed to the main + * screen when post is called. + */ + int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; + LOGE("fallback to single buffering"); + return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle, w, h, format, bpp, 0, 0); + } + + if (bufferMask >= ((1LU<framebuffer->base; + /* find a free slot */ + for (uint32_t i = 0; i < numBuffers; i++) { + if ((bufferMask & (1LU<bufferMask |= (1LU<framebuffer->fd), vaddr - m->framebuffer->base); + + hnd->format = format; + hnd->usage = usage; + hnd->width = w; + hnd->height = h; + hnd->bpp = bpp; + + *pHandle = hnd; + + return 0; +} + +static int gralloc_alloc_framebuffer(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp) +{ + private_module_t* m = reinterpret_cast(dev->common.module); + pthread_mutex_lock(&m->lock); + int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle, w, h, format, bpp); + pthread_mutex_unlock(&m->lock); + return err; +} + +static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, + int usage, buffer_handle_t* pHandle, int* pStride) +{ + if (!pHandle || !pStride) + return -EINVAL; + + size_t size = 0; + size_t stride = 0; + size_t stride_raw = 0; + + if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || + format == HAL_PIXEL_FORMAT_YCrCb_420_SP || + format == HAL_PIXEL_FORMAT_YCbCr_422_SP || + format == HAL_PIXEL_FORMAT_YCbCr_420_P || + format == HAL_PIXEL_FORMAT_YV12 || + format == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP || + format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED || + format == GGL_PIXEL_FORMAT_L_8 || + format == OMX_COLOR_FormatYUV420Planar || + format == OMX_COLOR_FormatYUV420SemiPlanar) { + /* FIXME: there is no way to return the vstride */ + int vstride; + stride = (w + 15) & ~15; + vstride = (h + 15) & ~15; + switch (format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + size = stride * vstride * 2; + if(usage & GRALLOC_USAGE_HW_FIMC1) + size += PAGE_SIZE * 2; + break; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + size = (stride * vstride) + (w/2 * h/2) * 2; + break; + case GGL_PIXEL_FORMAT_L_8: + size = (stride * vstride); + break; + default: + return -EINVAL; + } + } else { + int align = 8; + int bpp = 0; + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + bpp = 4; + break; + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + break; + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + default: + return -EINVAL; + } + size_t bpr = (w*bpp + (align-1)) & ~(align-1); + size = bpr * h; + stride = bpr / bpp; + stride_raw = bpr; + } + + int err; + pthread_mutex_lock(&l_surface); + if (usage & GRALLOC_USAGE_HW_FB) + err = gralloc_alloc_framebuffer(dev, size, usage, pHandle, w, h, format, 32); + else + err = gralloc_alloc_buffer(dev, size, usage, pHandle, w, h, format, 0, (int)stride_raw, (int)stride); + + pthread_mutex_unlock(&l_surface); + + if (err < 0) + return err; + + *pStride = stride; + return 0; +} + +static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) + return -EINVAL; + + private_handle_t const* hnd = reinterpret_cast(handle); + private_module_t* m = reinterpret_cast(dev->common.module); + pthread_mutex_lock(&l_surface); + if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + /* free this buffer */ + const size_t bufferSize = m->finfo.line_length * m->info.yres; + int index = (hnd->base - m->framebuffer->base) / bufferSize; + m->bufferMask &= ~(1<fd); + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { +#ifdef USE_PARTIAL_FLUSH + if (!release_rect((int)hnd->ump_id)) + LOGE("secure id: 0x%x, release error",(int)hnd->ump_id); +#endif + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + ump_reference_release((ump_handle)hnd->ump_mem_handle); + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { +#ifdef USE_PARTIAL_FLUSH + if (!release_rect((int)hnd->ump_id)) + LOGE("secure id: 0x%x, release error",(int)hnd->ump_id); +#endif + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + ump_reference_release((ump_handle)hnd->ump_mem_handle); + + ion_unmap((void*)hnd->base, hnd->size); + ion_free(hnd->fd); + } + pthread_mutex_unlock(&l_surface); + delete hnd; + + return 0; +} + +static int alloc_device_close(struct hw_device_t *device) +{ + alloc_device_t* dev = reinterpret_cast(device); + if (dev) { + private_module_t* m = reinterpret_cast(dev->common.module); + if (ion_dev_open) + ion_client_destroy(m->ion_client); + delete dev; + ump_close(); + } + return 0; +} + +int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device) +{ + alloc_device_t *dev; + + dev = new alloc_device_t; + if (NULL == dev) + return -1; + + dev->common.module = const_cast(module); + private_module_t* m = reinterpret_cast(dev->common.module); + m->ion_client = ion_client_create(); + ump_result ump_res = ump_open(); + if (0 > m->ion_client) + ion_dev_open = false; + if (UMP_OK != ump_res) { + LOGE("UMP open failed ump_res %d", ump_res); + delete dev; + return -1; + } + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = const_cast(module); + dev->common.close = alloc_device_close; + dev->alloc = alloc_device_alloc; + dev->free = alloc_device_free; + + *device = &dev->common; + + return 0; +} diff --git a/exynos4/hal/libgralloc_ump/alloc_device.h b/exynos4/hal/libgralloc_ump/alloc_device.h new file mode 100644 index 0000000..4609787 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/alloc_device.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * alloc_device_open() + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// Create an alloc device +int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device); diff --git a/exynos4/hal/libgralloc_ump/framebuffer_device.cpp b/exynos4/hal/libgralloc_ump/framebuffer_device.cpp new file mode 100644 index 0000000..9413112 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/framebuffer_device.cpp @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * enums + * * fb_set_swap_interval() + * * fb_post() + * * init_frame_buffer_locked() + * * init_frame_buffer() + * * fb_close() + * * framebuffer_device_open() + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE +#include "gralloc_vsync_report.h" +#endif + +#include "gralloc_priv.h" +#include "gralloc_helper.h" + +#include "linux/fb.h" + +/* numbers of buffers for page flipping */ +#define NUM_BUFFERS 2 + +enum { + PAGE_FLIP = 0x00000001, +}; + +static int fb_set_swap_interval(struct framebuffer_device_t* dev, int interval) +{ + if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval) + return -EINVAL; + + /* Currently not implemented */ + return 0; +} + +static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) +{ + if (private_handle_t::validate(buffer) < 0) + return -EINVAL; + + private_handle_t const* hnd = reinterpret_cast(buffer); + private_module_t* m = reinterpret_cast(dev->common.module); + + if (m->currentBuffer) { + m->base.unlock(&m->base, m->currentBuffer); + m->currentBuffer = 0; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, + 0, 0, m->info.xres, m->info.yres, NULL); + + const size_t offset = hnd->base - m->framebuffer->base; + int interrupt; + m->info.activate = FB_ACTIVATE_VBL; + m->info.yoffset = offset / m->finfo.line_length; + +#ifdef STANDARD_LINUX_SCREEN +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int) + if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1) { + LOGE("FBIOPAN_DISPLAY failed"); + m->base.unlock(&m->base, buffer); + return 0; + } + + if (m->enableVSync) { + /* enable VSYNC */ + interrupt = 1; + if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) { + LOGE("S3CFB_SET_VSYNC_INT enable failed"); + return 0; + } + /* wait for VSYNC */ + +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT); +#endif + int crtc; + crtc = 0; + if (ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0) { + LOGE("FBIO_WAITFORVSYNC failed"); +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); +#endif + return 0; + } +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); +#endif + // disable VSYNC + interrupt = 0; + if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) { + LOGE("S3CFB_SET_VSYNC_INT disable failed"); + return 0; + } +#else + /*Standard Android way*/ +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT); +#endif + if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { + LOGE("FBIOPUT_VSCREENINFO failed"); +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); +#endif + m->base.unlock(&m->base, buffer); + return -errno; + } +#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE + gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); +#endif +#endif + } + m->currentBuffer = buffer; + } else { + /* + * If we can't do the page_flip, just copy the buffer to the front + * FIXME: use copybit HAL instead of memcpy + */ + void* fb_vaddr; + void* buffer_vaddr; + + m->base.lock(&m->base, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, + 0, 0, m->info.xres, m->info.yres, &fb_vaddr); + + m->base.lock(&m->base, buffer, GRALLOC_USAGE_SW_READ_RARELY, + 0, 0, m->info.xres, m->info.yres, &buffer_vaddr); + + memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres); + + m->base.unlock(&m->base, buffer); + m->base.unlock(&m->base, m->framebuffer); + } + return 0; +} + +int init_frame_buffer_locked(struct private_module_t* module) +{ + /* Nothing to do, already initialized */ + if (module->framebuffer) + return 0; + + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + NULL + }; + + int fd = -1; + int i = 0; + char name[64]; + + while ((fd == -1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + + if (fd < 0) + return -errno; + + struct fb_fix_screeninfo finfo; + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) + return -errno; + + struct fb_var_screeninfo info; + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) + return -errno; + + info.reserved[0] = 0; + info.reserved[1] = 0; + info.reserved[2] = 0; + info.xoffset = 0; + info.yoffset = 0; + info.activate = FB_ACTIVATE_NOW; + +#ifdef GRALLOC_16_BITS + /* + * Explicitly request 5/6/5 + */ + info.bits_per_pixel = 16; + info.red.offset = 11; + info.red.length = 5; + info.green.offset = 5; + info.green.length = 6; + info.blue.offset = 0; + info.blue.length = 5; + info.transp.offset = 0; + info.transp.length = 0; +#else + /* + * Explicitly request 8/8/8 + */ + info.bits_per_pixel = 32; + info.red.offset = 16; + info.red.length = 8; + info.green.offset = 8; + info.green.length = 8; + info.blue.offset = 0; + info.blue.length = 8; + info.transp.offset = 0; + info.transp.length = 0; +#endif + + /* + * Request NUM_BUFFERS screens (at lest 2 for page flipping) + */ + info.yres_virtual = info.yres * NUM_BUFFERS; + + uint32_t flags = PAGE_FLIP; + if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { + info.yres_virtual = info.yres; + flags &= ~PAGE_FLIP; + LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); + } + + if (info.yres_virtual < info.yres * 2) { + // we need at least 2 for page-flipping + info.yres_virtual = info.yres; + flags &= ~PAGE_FLIP; + LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", + info.yres_virtual, info.yres * 2); + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) + return -errno; + + int refreshRate = 1000000000000000LLU / + ( + uint64_t( info.upper_margin + info.lower_margin + info.yres ) + * ( info.left_margin + info.right_margin + info.xres ) + * info.pixclock + ); + + if (refreshRate == 0) + refreshRate = 60 * 1000; /* 60 Hz */ + + if (int(info.width) <= 0 || int(info.height) <= 0) { + /* the driver doesn't return that information. default to 160 dpi */ + info.width = ((info.xres * 25.4f)/160.0f + 0.5f); + info.height = ((info.yres * 25.4f)/160.0f + 0.5f); + } + + float xdpi = (info.xres * 25.4f) / info.width; + float ydpi = (info.yres * 25.4f) / info.height; + float fps = refreshRate / 1000.0f; + + LOGI("using (fd=%d)\n" + "id = %s\n" + "xres = %d px\n" + "yres = %d px\n" + "xres_virtual = %d px\n" + "yres_virtual = %d px\n" + "bpp = %d\n" + "r = %2u:%u\n" + "g = %2u:%u\n" + "b = %2u:%u\n", + fd, + finfo.id, + info.xres, + info.yres, + info.xres_virtual, + info.yres_virtual, + info.bits_per_pixel, + info.red.offset, info.red.length, + info.green.offset, info.green.length, + info.blue.offset, info.blue.length); + + LOGI("width = %d mm (%f dpi)\n" + "height = %d mm (%f dpi)\n" + "refresh rate = %.2f Hz\n", + info.width, xdpi, + info.height, ydpi, + fps); + + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) + return -errno; + + if (finfo.smem_len <= 0) + return -errno; + + module->flags = flags; + module->info = info; + module->finfo = finfo; + module->xdpi = xdpi; + module->ydpi = ydpi; + module->fps = fps; + + char value[32]; + property_get("debug.gralloc.vsync", value, "1"); + module->enableVSync = atoi(value); + /* + * map the framebuffer + */ + size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); + void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (vaddr == MAP_FAILED) { + LOGE("Error mapping the framebuffer (%s)", strerror(errno)); + return -errno; + } + + memset(vaddr, 0, fbSize); + + /* + * Create a "fake" buffer object for the entire frame buffer memory, + * and store it in the module + */ + module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, + fbSize, intptr_t(vaddr), 0, dup(fd), 0); + + module->numBuffers = info.yres_virtual / info.yres; + module->bufferMask = 0; + + return 0; +} + +int enableScreen(struct framebuffer_device_t* dev, int enable) +{ + private_module_t* m = reinterpret_cast(dev->common.module); + + if (enable == 1) { + if (ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) { + LOGE("%s: FBIOBLANK failed : (%d:%s)", + __func__, m->framebuffer->fd, strerror(errno)); + return -EINVAL; + } + } else if (enable == 0) { + if (ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) { + LOGE("%s: FBIOBLANK failed : (%d:%s)", + __func__, m->framebuffer->fd, strerror(errno)); + return -EINVAL; + } + } else { + return -EINVAL; + } + return 0; +} +static int init_frame_buffer(struct private_module_t* module) +{ + pthread_mutex_lock(&module->lock); + int err = init_frame_buffer_locked(module); + pthread_mutex_unlock(&module->lock); + return err; +} + +static int fb_close(struct hw_device_t *device) +{ + framebuffer_device_t* dev = reinterpret_cast(device); + if (dev) { + ump_close(); + delete dev; + } + return 0; +} + +int compositionComplete(struct framebuffer_device_t* dev) +{ +#ifndef HWC_HWOVERLAY + unsigned char pixels[4]; + /* By doing a readpixel here we force the GL driver to start rendering + all the drawcalls up to this point, and to wait for the rendering to be complete. + Readpixel() also reads a dummy pixel, but this is not used. We only use this + function here to flush the render pipeline. */ + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + /* The rendering of the backbuffer is now completed. + When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done + synchronously in the same thread, and not asynchronoulsy in a background thread later. + The SurfaceFlinger requires this behaviour since it releases the lock on all the + SourceBuffers (Layers) after the compositionComplete() function returns. + However this "bad" behaviour by SurfaceFlinger should not affect performance, + since the Applications that render the SourceBuffers (Layers) still get the + full renderpipeline using asynchronouls rendering. So they perform at maximum speed, + and because of their complexity compared to the Surface flinger jobs, the Surface flinger + is normally faster even if it does everyhing synchronous and serial. + */ +#endif + return 0; +} + +int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device) +{ + int status = -EINVAL; + + alloc_device_t* gralloc_device; + status = gralloc_open(module, &gralloc_device); + if (status < 0) + return status; + + private_module_t* m = (private_module_t*)module; + status = init_frame_buffer(m); + if (status < 0) { + gralloc_close(gralloc_device); + return status; + } + + /* initialize our state here */ + framebuffer_device_t *dev = new framebuffer_device_t; + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = const_cast(module); + dev->common.close = fb_close; + dev->setSwapInterval = fb_set_swap_interval; + dev->post = fb_post; + dev->setUpdateRect = 0; + dev->compositionComplete = &compositionComplete; + dev->enableScreen = &enableScreen; + + int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); + const_cast(dev->flags) = 0; + const_cast(dev->width) = m->info.xres; + const_cast(dev->height) = m->info.yres; + const_cast(dev->stride) = stride; +#ifdef GRALLOC_16_BITS + const_cast(dev->format) = HAL_PIXEL_FORMAT_RGB_565; +#else + const_cast(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888; +#endif + const_cast(dev->xdpi) = m->xdpi; + const_cast(dev->ydpi) = m->ydpi; + const_cast(dev->fps) = m->fps; + const_cast(dev->minSwapInterval) = 1; + const_cast(dev->maxSwapInterval) = 1; + *device = &dev->common; + status = 0; + + return status; +} diff --git a/exynos4/hal/libgralloc_ump/framebuffer_device.h b/exynos4/hal/libgralloc_ump/framebuffer_device.h new file mode 100644 index 0000000..efcf1c3 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/framebuffer_device.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * framebuffer_device_open() + * * init_frame_buffer_locked() + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// Create a framebuffer device +int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device); + +// Initialize the framebuffer (must keep module lock before calling +int init_frame_buffer_locked(struct private_module_t* module); \ No newline at end of file diff --git a/exynos4/hal/libgralloc_ump/gr.h b/exynos4/hal/libgralloc_ump/gr.h new file mode 100644 index 0000000..3a43aa7 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/gr.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GR_H_ +#define GR_H_ + +#include +#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define +# include +#else +# include +#endif +#include +#include +#include +#include +#include + +#include + +/*****************************************************************************/ + +struct private_module_t; +struct private_handle_t; + +inline size_t roundUpToPageSize(size_t x) { + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} + +int mapFrameBufferLocked(struct private_module_t* module); +int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd); +int mapBuffer(gralloc_module_t const* module, private_handle_t* hnd); + +/*****************************************************************************/ + +class Locker { + pthread_mutex_t mutex; +public: + class Autolock { + Locker& locker; + public: + inline Autolock(Locker& locker) : locker(locker) { locker.lock(); } + inline ~Autolock() { locker.unlock(); } + }; + inline Locker() { pthread_mutex_init(&mutex, 0); } + inline ~Locker() { pthread_mutex_destroy(&mutex); } + inline void lock() { pthread_mutex_lock(&mutex); } + inline void unlock() { pthread_mutex_unlock(&mutex); } +}; + +#endif /* GR_H_ */ diff --git a/exynos4/hal/libgralloc_ump/gralloc_helper.h b/exynos4/hal/libgralloc_ump/gralloc_helper.h new file mode 100644 index 0000000..21a5135 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/gralloc_helper.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * round_up_to_page_size() + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_HELPER_H_ +#define GRALLOC_HELPER_H_ + +#include + +inline size_t round_up_to_page_size(size_t x) +{ + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} + +#endif /* GRALLOC_HELPER_H_ */ diff --git a/exynos4/hal/libgralloc_ump/gralloc_module.cpp b/exynos4/hal/libgralloc_ump/gralloc_module.cpp new file mode 100644 index 0000000..fb8fc43 --- /dev/null +++ b/exynos4/hal/libgralloc_ump/gralloc_module.cpp @@ -0,0 +1,480 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Portions of this code have been modified from the original. + * These modifications are: + * * includes + * * enums + * * gralloc_device_open() + * * gralloc_register_buffer() + * * gralloc_unregister_buffer() + * * gralloc_lock() + * * gralloc_unlock() + * * gralloc_module_methods + * * HAL_MODULE_INFO_SYM + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "gralloc_priv.h" +#include "alloc_device.h" +#include "framebuffer_device.h" + +#include "ump.h" +#include "ump_ref_drv.h" +#include "s5p_fimc.h" +#include "exynos_mem.h" +static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; + +static int s_ump_is_open = 0; +static int gMemfd = 0; +#define PFX_NODE_MEM "/dev/exynos-mem" + +/* we need this for now because pmem cannot mmap at an offset */ +#define PMEM_HACK 1 +#ifdef USE_PARTIAL_FLUSH +struct private_handle_rect *rect_list; + +private_handle_rect *find_rect(int secure_id) +{ + private_handle_rect *psRect; + + for (psRect = rect_list; psRect; psRect = psRect->next) + if (psRect->handle == secure_id) + break; + if (!psRect) + return NULL; + + return psRect; +} + +private_handle_rect *find_last_rect(int secure_id) +{ + private_handle_rect *psRect; + private_handle_rect *psFRect; + + if (rect_list == NULL) { + rect_list = (private_handle_rect *)calloc(1, sizeof(private_handle_rect)); + return rect_list; + } + + for (psRect = rect_list; psRect; psRect = psRect->next) { + if (psRect->handle == secure_id) + return psFRect; + psFRect = psRect; + } + return psFRect; +} + +int release_rect(int secure_id) +{ + private_handle_rect *psRect; + private_handle_rect *psTRect; + + for (psRect = rect_list; psRect; psRect = psRect->next) { + if (psRect->next) { + if (psRect->next->handle == secure_id) { + if (psRect->next->next) + psTRect = psRect->next->next; + else + psTRect = NULL; + + free(psRect->next); + psRect->next = psTRect; + return 1; + } + } + } + + return 0; +} +#endif + +static int gralloc_map(gralloc_module_t const* module, + buffer_handle_t handle, void** vaddr) +{ + private_handle_t* hnd = (private_handle_t*)handle; + if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) { + size_t size = FIMC1_RESERVED_SIZE * 1024; + void *mappedAddress = mmap(0, size, + PROT_READ|PROT_WRITE, MAP_SHARED, gMemfd, (hnd->paddr - hnd->offset)); + if (mappedAddress == MAP_FAILED) { + LOGE("Could not mmap %s fd(%d)", strerror(errno),hnd->fd); + return -errno; + } + hnd->base = intptr_t(mappedAddress) + hnd->offset; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + size_t size = hnd->size; + hnd->ion_client = ion_client_create(); + void *mappedAddress = ion_map(hnd->fd, size, 0); + + if (mappedAddress == MAP_FAILED) { + LOGE("Could not ion_map %s fd(%d)", strerror(errno), hnd->fd); + return -errno; + } + + hnd->base = intptr_t(mappedAddress) + hnd->offset; + } else { + size_t size = hnd->size; +#if PMEM_HACK + size += hnd->offset; +#endif + void *mappedAddress = mmap(0, size, + PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0); + if (mappedAddress == MAP_FAILED) { + LOGE("Could not mmap %s fd(%d)", strerror(errno),hnd->fd); + return -errno; + } + hnd->base = intptr_t(mappedAddress) + hnd->offset; + } + } + *vaddr = (void*)hnd->base; + return 0; +} + +static int gralloc_unmap(gralloc_module_t const* module, + buffer_handle_t handle) +{ + private_handle_t* hnd = (private_handle_t*)handle; + if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) { + void* base = (void*)(intptr_t(hnd->base) - hnd->offset); + size_t size = FIMC1_RESERVED_SIZE * 1024; + if (munmap(base, size) < 0) + LOGE("Could not unmap %s", strerror(errno)); + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + void* base = (void*)hnd->base; + size_t size = hnd->size; + if (ion_unmap(base, size) < 0) + LOGE("Could not ion_unmap %s", strerror(errno)); + ion_client_destroy(hnd->ion_client); + } else { + void* base = (void*)hnd->base; + size_t size = hnd->size; +#if PMEM_HACK + base = (void*)(intptr_t(base) - hnd->offset); + size += hnd->offset; +#endif + if (munmap(base, size) < 0) + LOGE("Could not unmap %s", strerror(errno)); + } + } + hnd->base = 0; + return 0; +} + +static int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device) +{ + int status = -EINVAL; + + if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) + status = alloc_device_open(module, name, device); + else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) + status = framebuffer_device_open(module, name, device); + + return status; +} + +static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle) +{ + int err = 0; + int retval = -EINVAL; + void *vaddr; + if (private_handle_t::validate(handle) < 0) { + LOGE("Registering invalid buffer, returning error"); + return -EINVAL; + } + + /* if this handle was created in this process, then we keep it as is. */ + private_handle_t* hnd = (private_handle_t*)handle; + +#ifdef USE_PARTIAL_FLUSH + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + private_handle_rect *psRect; + private_handle_rect *psFRect; + psRect = (private_handle_rect *)calloc(1, sizeof(private_handle_rect)); + psRect->handle = (int)hnd->ump_id; + psRect->stride = (int)hnd->stride; + psFRect = find_last_rect((int)hnd->ump_id); + psFRect->next = psRect; + } +#endif + if (hnd->pid == getpid()) + return 0; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + err = gralloc_map(module, handle, &vaddr); + + pthread_mutex_lock(&s_map_lock); + + if (!s_ump_is_open) { + ump_result res = ump_open(); /* TODO: Fix a ump_close() somewhere??? */ + if (res != UMP_OK) { + pthread_mutex_unlock(&s_map_lock); + LOGE("Failed to open UMP library"); + return retval; + } + s_ump_is_open = 1; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); + if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) { + hnd->base = (int)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle); + if (0 != hnd->base) { + hnd->lockState = private_handle_t::LOCK_STATE_MAPPED; + hnd->writeOwner = 0; + hnd->lockState = 0; + + pthread_mutex_unlock(&s_map_lock); + return 0; + } else { + LOGE("Failed to map UMP handle"); + } + + ump_reference_release((ump_handle)hnd->ump_mem_handle); + } else { + LOGE("Failed to create UMP handle"); + } + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) { + pthread_mutex_unlock(&s_map_lock); + return 0; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) { + void* vaddr = NULL; + + if (gMemfd == 0) { + gMemfd = open(PFX_NODE_MEM, O_RDWR); + if (gMemfd < 0) { + LOGE("%s:: %s exynos-mem open error\n", __func__, PFX_NODE_MEM); + return false; + } + } + + gralloc_map(module, handle, &vaddr); + pthread_mutex_unlock(&s_map_lock); + return 0; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); + if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) { + vaddr = (void*)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle); + if (0 != vaddr) { + hnd->lockState = private_handle_t::LOCK_STATE_MAPPED; + hnd->writeOwner = 0; + hnd->lockState = 0; + + pthread_mutex_unlock(&s_map_lock); + return 0; + } else { + LOGE("Failed to map UMP handle"); + } + ump_reference_release((ump_handle)hnd->ump_mem_handle); + } else { + LOGE("Failed to create UMP handle"); + } + } else { + LOGE("registering non-UMP buffer not supported"); + } + + pthread_mutex_unlock(&s_map_lock); + return retval; +} + +static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("unregistering invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + +#ifdef USE_PARTIAL_FLUSH + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) + if (!release_rect((int)hnd->ump_id)) + LOGE("secureID: 0x%x, release error", (int)hnd->ump_id); +#endif + LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, + "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState); + + /* never unmap buffers that were created in this process */ + if (hnd->pid != getpid()) { + pthread_mutex_lock(&s_map_lock); + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + hnd->base = 0; + ump_reference_release((ump_handle)hnd->ump_mem_handle); + hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE; + hnd->lockState = 0; + hnd->writeOwner = 0; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) { + if(hnd->base != 0) + gralloc_unmap(module, handle); + + pthread_mutex_unlock(&s_map_lock); + return 0; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + ump_reference_release((ump_handle)hnd->ump_mem_handle); + if (hnd->base) + gralloc_unmap(module, handle); + + hnd->base = 0; + hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE; + hnd->lockState = 0; + hnd->writeOwner = 0; + } else { + LOGE("unregistering non-UMP buffer not supported"); + } + + pthread_mutex_unlock(&s_map_lock); + } + + return 0; +} + +static int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, + int usage, int l, int t, int w, int h, void** vaddr) +{ + int err = 0; + if (private_handle_t::validate(handle) < 0) { + LOGE("Locking invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + +#ifdef SAMSUNG_EXYNOS_CACHE_UMP + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { +#ifdef USE_PARTIAL_FLUSH + private_handle_rect *psRect; + psRect = find_rect((int)hnd->ump_id); + psRect->l = l; + psRect->t = t; + psRect->w = w; + psRect->h= h; + psRect->locked = 1; +#endif + } +#endif + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) + *vaddr = (void*)hnd->base; + + if (usage & GRALLOC_USAGE_YUV_ADDR) { + vaddr[0] = (void*)hnd->base; + vaddr[1] = (void*)(hnd->base + hnd->uoffset); + vaddr[2] = (void*)(hnd->base + hnd->uoffset + hnd->voffset); + } + return err; +} + +static int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("Unlocking invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + +#ifdef SAMSUNG_EXYNOS_CACHE_UMP + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { +#ifdef USE_PARTIAL_FLUSH + private_handle_rect *psRect; + psRect = find_rect((int)hnd->ump_id); + ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN, + (void *)(hnd->base + (psRect->stride * psRect->t)), psRect->stride * psRect->h ); + return 0; +#endif + ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, NULL, 0); + } +#endif + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + ion_msync(hnd->ion_client, hnd->fd, IMSYNC_DEV_TO_RW | IMSYNC_SYNC_FOR_DEV, hnd->size, hnd->offset); + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) { + int ret; + exynos_mem_flush_range mem; + mem.start = hnd->paddr; + mem.length = hnd->size; + + ret = ioctl(gMemfd, EXYNOS_MEM_PADDR_CACHE_FLUSH, &mem); + if (ret < 0) { + LOGE("Error in exynos-mem : EXYNOS_MEM_PADDR_CACHE_FLUSH (%d)\n", ret); + return false; + } + } + + return 0; +} + +static int gralloc_getphys(gralloc_module_t const* module, buffer_handle_t handle, void** paddr) +{ + private_handle_t* hnd = (private_handle_t*)handle; + paddr[0] = (void*)hnd->paddr; + paddr[1] = (void*)(hnd->paddr + hnd->uoffset); + paddr[2] = (void*)(hnd->paddr + hnd->uoffset + hnd->voffset); + return 0; +} + +/* There is one global instance of the module */ +static struct hw_module_methods_t gralloc_module_methods = +{ + open: gralloc_device_open +}; + +struct private_module_t HAL_MODULE_INFO_SYM = +{ + base: + { + common: + { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: GRALLOC_HARDWARE_MODULE_ID, + name: "Graphics Memory Allocator Module", + author: "ARM Ltd.", + methods: &gralloc_module_methods, + dso: NULL, + reserved : {0,}, + }, + registerBuffer: gralloc_register_buffer, + unregisterBuffer: gralloc_unregister_buffer, + lock: gralloc_lock, + unlock: gralloc_unlock, + getphys: gralloc_getphys, + perform: NULL, + reserved_proc: {0,}, + }, + framebuffer: NULL, + flags: 0, + numBuffers: 0, + bufferMask: 0, + lock: PTHREAD_MUTEX_INITIALIZER, + currentBuffer: NULL, + ion_client: -1, +}; diff --git a/exynos4/hal/libhdmi/Android.mk b/exynos4/hal/libhdmi/Android.mk new file mode 100644 index 0000000..237c53c --- /dev/null +++ b/exynos4/hal/libhdmi/Android.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +include $(all-subdir-makefiles) +endif diff --git a/exynos4/hal/libhdmi/SecHdmi/Android.mk b/exynos4/hal/libhdmi/SecHdmi/Android.mk new file mode 100644 index 0000000..e728309 --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/Android.mk @@ -0,0 +1,88 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := libutils liblog libedid libcec + +LOCAL_SRC_FILES := \ + SecHdmiV4L2Utils.cpp \ + SecHdmi.cpp \ + fimd_api.c + +LOCAL_C_INCLUDES += $(LOCAL_PATH) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include + +ifeq ($(TARGET_SOC),exynos4210) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +LOCAL_CFLAGS += \ + -DSCREEN_WIDTH=$(SCREEN_WIDTH) \ + -DSCREEN_HEIGHT=$(SCREEN_HEIGHT) \ + -DDEFAULT_FB_NUM=$(DEFAULT_FB_NUM) + +LOCAL_SHARED_LIBRARIES += libfimc + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) +LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +ifeq ($(BOARD_USES_FIMGAPI),true) +LOCAL_CFLAGS += -DBOARD_USES_FIMGAPI +LOCAL_C_INCLUDES += $(TARGET_HAL_PATH)/libfimg4x +LOCAL_C_INCLUDES += external/skia/include/core +LOCAL_SHARED_LIBRARIES += libfimg +endif + +ifeq ($(BOARD_HDMI_STD), STD_NTSC_M) +LOCAL_CFLAGS += -DSTD_NTSC_M +endif + +ifeq ($(BOARD_HDMI_STD),STD_480P) +LOCAL_CFLAGS += -DSTD_480P +endif + +ifeq ($(BOARD_HDMI_STD),STD_720P) +LOCAL_CFLAGS += -DSTD_720P +endif + +ifeq ($(BOARD_HDMI_STD),STD_1080P) +LOCAL_CFLAGS += -DSTD_1080P +endif + +ifeq ($(BOARD_USE_V4L2),true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +ifeq ($(BOARD_USE_V4L2_ION),true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION +LOCAL_SHARED_LIBRARIES += libion +endif + +LOCAL_MODULE := libhdmi +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libhdmi/SecHdmi/SecHdmi.cpp b/exynos4/hal/libhdmi/SecHdmi/SecHdmi.cpp new file mode 100644 index 0000000..444a9db --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/SecHdmi.cpp @@ -0,0 +1,1957 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#include + +#if defined(BOARD_USE_V4L2_ION) +#include "ion.h" +#endif + +#include "SecHdmi.h" +#include "SecHdmiV4L2Utils.h" + +#define CHECK_GRAPHIC_LAYER_TIME (0) + +namespace android { + +extern unsigned int output_type; +#if defined(BOARD_USE_V4L2) +extern unsigned int g_preset_id; +#endif +extern v4l2_std_id t_std_id; +extern int g_hpd_state; +extern unsigned int g_hdcp_en; + +#if !defined(BOARD_USE_V4L2) +extern int fp_tvout; +extern int fp_tvout_v; +extern int fp_tvout_g0; +extern int fp_tvout_g1; +#endif + +#if defined(BOARD_USES_FIMGAPI) +extern unsigned int g2d_reserved_memory[HDMI_G2D_OUTPUT_BUF_NUM]; +extern unsigned int g2d_reserved_memory_size; +extern unsigned int cur_g2d_address; +extern unsigned int g2d_buf_index; +#endif + +#if defined(BOARD_USES_CEC) +SecHdmi::CECThread::~CECThread() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + mFlagRunning = false; +} + +bool SecHdmi::CECThread::threadLoop() +{ + unsigned char buffer[CEC_MAX_FRAME_SIZE]; + int size; + unsigned char lsrc, ldst, opcode; + + { + Mutex::Autolock lock(mThreadLoopLock); + mFlagRunning = true; + + size = CECReceiveMessage(buffer, CEC_MAX_FRAME_SIZE, 100000); + + if (!size) // no data available or ctrl-c + return true; + + if (size == 1) + return true; // "Polling Message" + + lsrc = buffer[0] >> 4; + + /* ignore messages with src address == mLaddr*/ + if (lsrc == mLaddr) + return true; + + opcode = buffer[1]; + + if (CECIgnoreMessage(opcode, lsrc)) { + LOGE("### ignore message coming from address 15 (unregistered)\n"); + return true; + } + + if (!CECCheckMessageSize(opcode, size)) { + LOGE("### invalid message size: %d(opcode: 0x%x) ###\n", size, opcode); + return true; + } + + /* check if message broadcasted/directly addressed */ + if (!CECCheckMessageMode(opcode, (buffer[0] & 0x0F) == CEC_MSG_BROADCAST ? 1 : 0)) { + LOGE("### invalid message mode (directly addressed/broadcast) ###\n"); + return true; + } + + ldst = lsrc; + + //TODO: macroses to extract src and dst logical addresses + //TODO: macros to extract opcode + + switch (opcode) { + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + /* responce with "Report Physical Address" */ + buffer[0] = (mLaddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS; + buffer[2] = (mPaddr >> 8) & 0xFF; + buffer[3] = mPaddr & 0xFF; + buffer[4] = mDevtype; + size = 5; + break; + + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + LOGD("[CEC_OPCODE_REQUEST_ACTIVE_SOURCE]\n"); + /* responce with "Active Source" */ + buffer[0] = (mLaddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_ACTIVE_SOURCE; + buffer[2] = (mPaddr >> 8) & 0xFF; + buffer[3] = mPaddr & 0xFF; + size = 4; + LOGD("Tx : [CEC_OPCODE_ACTIVE_SOURCE]\n"); + break; + + case CEC_OPCODE_ABORT: + case CEC_OPCODE_FEATURE_ABORT: + default: + /* send "Feature Abort" */ + buffer[0] = (mLaddr << 4) | ldst; + buffer[1] = CEC_OPCODE_FEATURE_ABORT; + buffer[2] = CEC_OPCODE_ABORT; + buffer[3] = 0x04; // "refused" + size = 4; + break; + } + + if (CECSendMessage(buffer, size) != size) + LOGE("CECSendMessage() failed!!!\n"); + + } + return true; +} + +bool SecHdmi::CECThread::start() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mThreadControlLock); + if (exitPending()) { + if (requestExitAndWait() == WOULD_BLOCK) { + LOGE("mCECThread.requestExitAndWait() == WOULD_BLOCK"); + return false; + } + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("EDIDGetCECPhysicalAddress"); +#endif + /* set to not valid physical address */ + mPaddr = CEC_NOT_VALID_PHYSICAL_ADDRESS; + + if (!EDIDGetCECPhysicalAddress(&mPaddr)) { + LOGE("Error: EDIDGetCECPhysicalAddress() failed.\n"); + return false; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("CECOpen"); +#endif + if (!CECOpen()) { + LOGE("CECOpen() failed!!!\n"); + return false; + } + + /* a logical address should only be allocated when a device \ + has a valid physical address, at all other times a device \ + should take the 'Unregistered' logical address (15) + */ + + /* if physical address is not valid device should take \ + the 'Unregistered' logical address (15) + */ + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("CECAllocLogicalAddress"); +#endif + mLaddr = CECAllocLogicalAddress(mPaddr, mDevtype); + + if (!mLaddr) { + LOGE("CECAllocLogicalAddress() failed!!!\n"); + if (!CECClose()) + LOGE("CECClose() failed!\n"); + return false; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("request to run CECThread"); +#endif + + status_t ret = run("SecHdmi::CECThread", PRIORITY_DISPLAY); + if (ret != NO_ERROR) { + LOGE("%s fail to run thread", __func__); + return false; + } + return true; +} + +bool SecHdmi::CECThread::stop() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s request Exit", __func__); +#endif + Mutex::Autolock lock(mThreadControlLock); + if (requestExitAndWait() == WOULD_BLOCK) { + LOGE("mCECThread.requestExitAndWait() == WOULD_BLOCK"); + return false; + } + + if (!CECClose()) + LOGE("CECClose() failed!\n"); + + mFlagRunning = false; + return true; +} +#endif + +SecHdmi::SecHdmi(): +#if defined(BOARD_USES_CEC) + mCECThread(NULL), +#endif + mFlagCreate(false), + mFlagConnected(false), + mHdmiDstWidth(0), + mHdmiDstHeight(0), + mHdmiSrcYAddr(0), + mHdmiSrcCbCrAddr(0), + mHdmiOutputMode(DEFAULT_OUPUT_MODE), + mHdmiResolutionValue(DEFAULT_HDMI_RESOLUTION_VALUE), // V4L2_STD_480P_60_4_3 + mCompositeStd(DEFAULT_COMPOSITE_STD), + mHdcpMode(false), + mAudioMode(2), + mUIRotVal(0), + mG2DUIRotVal(0), + mCurrentHdmiOutputMode(-1), + mCurrentHdmiResolutionValue(0), // 1080960 + mCurrentHdcpMode(false), + mCurrentAudioMode(-1), + mHdmiInfoChange(true), + mFimcDstColorFormat(0), + mFimcCurrentOutBufIndex(0), + mFBaddr(NULL), + mFBsize(0), + mFBionfd(-1), + mFBIndex(0), + mDefaultFBFd(-1), + mDisplayWidth(DEFALULT_DISPLAY_WIDTH), + mDisplayHeight(DEFALULT_DISPLAY_HEIGHT) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + for (int i = 0; i < HDMI_LAYER_MAX; i++) { + mFlagLayerEnable[i] = false; + mFlagHdmiStart[i] = false; + + mSrcWidth [i] = 0; + mSrcHeight [i] = 0; + mSrcColorFormat[i] = 0; + mHdmiResolutionWidth [i] = 0; + mHdmiResolutionHeight [i] = 0; + mHdmiFd[i] = -1; + mDstWidth [i] = 0; + mDstHeight [i] = 0; + mPrevDstWidth [i] = 0; + mPrevDstHeight [i] = 0; + } + + mHdmiPresetId = DEFAULT_HDMI_PRESET_ID; + mHdmiStdId = DEFAULT_HDMI_STD_ID; + + //All layer is on + mFlagLayerEnable[HDMI_LAYER_VIDEO] = true; + mFlagLayerEnable[HDMI_LAYER_GRAPHIC_0] = true; + mFlagLayerEnable[HDMI_LAYER_GRAPHIC_1] = true; + + mHdmiSizeOfResolutionValueList = 14; + + mHdmiResolutionValueList[0] = 1080960; + mHdmiResolutionValueList[1] = 1080950; + mHdmiResolutionValueList[2] = 1080930; + mHdmiResolutionValueList[3] = 1080924; + mHdmiResolutionValueList[4] = 1080160; + mHdmiResolutionValueList[5] = 1080150; + mHdmiResolutionValueList[6] = 720960; + mHdmiResolutionValueList[7] = 7209601; + mHdmiResolutionValueList[8] = 720950; + mHdmiResolutionValueList[9] = 7209501; + mHdmiResolutionValueList[10] = 5769501; + mHdmiResolutionValueList[11] = 5769502; + mHdmiResolutionValueList[12] = 4809601; + mHdmiResolutionValueList[13] = 4809602; + +#if defined(BOARD_USES_CEC) + mCECThread = new CECThread(this); +#endif + + SecBuffer zeroBuf; + for (int i = 0; i < HDMI_FIMC_OUTPUT_BUF_NUM; i++) + mFimcReservedMem[i] = zeroBuf; +#if defined(BOARD_USE_V4L2) + for (int i = 0; i < HDMI_LAYER_MAX; i++) + for (int j = 0; j < MAX_BUFFERS_MIXER; j++) + mMixerBuffer[i][j] = zeroBuf; +#endif + + memset(&mDstRect, 0 , sizeof(struct v4l2_rect)); +} + +SecHdmi::~SecHdmi() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (mFlagCreate == true) + LOGE("%s::this is not Destroyed fail", __func__); + else + disconnect(); +} + +bool SecHdmi::create(int width, int height) +{ + Mutex::Autolock lock(mLock); + unsigned int fimc_buf_size = 0; + unsigned int gralloc_buf_size = 0; + mFimcCurrentOutBufIndex = 0; + int stride; + int vstride; + int BufNum = 0; +#if defined(BOARD_USE_V4L2_ION) + int IonClient = -1; + int IonFd = -1; + void *ion_base_addr = NULL; +#endif + +/* + * Video plaback (I420): output buffer size of FIMC3 is (1920 x 1088 x 1.5) + * Video plaback (NV12): FIMC3 is not used. + * Camera preview (YV12): output buffer size of FIMC3 is (640 x 480 x 1.5) + * UI mode (ARGB8888) : output buffer size of FIMC3 is (480 x 800 x 1.5) + */ +#ifndef SUPPORT_1080P_FIMC_OUT + setDisplaySize(width, height); +#endif + + stride = ALIGN(HDMI_MAX_WIDTH, 16); + vstride = ALIGN(HDMI_MAX_HEIGHT, 16); + + fimc_buf_size = stride * vstride * HDMI_FIMC_BUFFER_BPP_SIZE; + gralloc_buf_size = GRALLOC_BUF_SIZE * SIZE_1K; +#if defined(BOARD_USES_FIMGAPI) + g2d_reserved_memory_size = stride * vstride * HDMI_G2D_BUFFER_BPP_SIZE; +#endif + +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (mFlagCreate == true) { + LOGE("%s::Already Created fail", __func__); + goto CREATE_FAIL; + } + + if (mDefaultFBFd <= 0) { + if ((mDefaultFBFd = fb_open(DEFAULT_FB)) < 0) { + LOGE("%s:Failed to open default FB", __func__); + return false; + } + } + +#ifdef BOARD_USE_V4L2 + BufNum = HDMI_FIMC_OUTPUT_BUF_NUM; +#else + BufNum = 1; +#endif + + if (mSecFimc.create(SecFimc::DEV_3, SecFimc::MODE_SINGLE_BUF, BufNum) == false) { + LOGE("%s::SecFimc create() fail", __func__); + goto CREATE_FAIL; + } + +#if defined(BOARD_USE_V4L2_ION) + IonClient = ion_client_create(); + if (IonClient < 0) { + LOGE("%s::ion_client_create() failed", __func__); + goto CREATE_FAIL; + } +#if defined(BOARD_USES_FIMGAPI) + IonFd = ion_alloc(IonClient, g2d_reserved_memory_size * HDMI_G2D_OUTPUT_BUF_NUM, 0, ION_HEAP_EXYNOS_MASK); + + if (IonFd < 0) { + LOGE("%s::ION memory allocation failed", __func__); + } else { + ion_base_addr = ion_map(IonFd, ALIGN(g2d_reserved_memory_size * HDMI_G2D_OUTPUT_BUF_NUM, PAGE_SIZE), 0); + if (ion_base_addr == MAP_FAILED) + LOGE("%s::ION mmap failed", __func__); + } + + for (int i = 0; i < HDMI_G2D_OUTPUT_BUF_NUM; i++) + g2d_reserved_memory[i] = ion_base_addr + (g2d_reserved_memory_size * i); +#endif +#else +#ifndef BOARD_USE_V4L2 + for (int i = 0; i < HDMI_FIMC_OUTPUT_BUF_NUM; i++) + mFimcReservedMem[i].phys.p = mSecFimc.getMemAddr()->phys.p + gralloc_buf_size + (fimc_buf_size * i); +#endif + +#if defined(BOARD_USES_FIMGAPI) +#if defined(BOARD_USES_HDMI_SUBTITLES) + for (int i = 0; i < HDMI_G2D_OUTPUT_BUF_NUM; i++) + g2d_reserved_memory[i] = mFimcReservedMem[HDMI_FIMC_OUTPUT_BUF_NUM - 1].phys.p + fimc_buf_size + (g2d_reserved_memory_size * i); +#else + for (int i = 0; i < HDMI_G2D_OUTPUT_BUF_NUM; i++) + g2d_reserved_memory[i] = mSecFimc.getMemAddr()->phys.p + gralloc_buf_size + (g2d_reserved_memory_size * i); +#endif +#endif +#endif + + v4l2_std_id std_id; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::mHdmiOutputMode(%d) \n", __func__, mHdmiOutputMode); +#endif + if (mHdmiOutputMode == COMPOSITE_OUTPUT_MODE) { + std_id = composite_std_2_v4l2_std_id(mCompositeStd); + if ((int)std_id < 0) { + LOGE("%s::composite_std_2_v4l2_std_id(%d) fail\n", __func__, mCompositeStd); + goto CREATE_FAIL; + } + if (m_setCompositeResolution(mCompositeStd) == false) { + LOGE("%s::m_setCompositeResolution(%d) fail\n", __func__, mCompositeStd); + goto CREATE_FAIL; + } + } else if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USE_V4L2) + unsigned int preset_id; + + if (hdmi_resolution_2_preset_id(mHdmiResolutionValue, &mHdmiDstWidth, &mHdmiDstHeight, &preset_id) < 0) { + LOGE("%s::hdmi_resolution_2_preset_id(%d) fail\n", __func__, mHdmiResolutionValue); + goto CREATE_FAIL; + } +#else + if (hdmi_resolution_2_std_id(mHdmiResolutionValue, &mHdmiDstWidth, &mHdmiDstHeight, &std_id) < 0) { + LOGE("%s::hdmi_resolution_2_std_id(%d) fail\n", __func__, mHdmiResolutionValue); + goto CREATE_FAIL; + } +#endif + } + + mFlagCreate = true; + + return true; + +CREATE_FAIL : + + if (mSecFimc.flagCreate() == true && + mSecFimc.destroy() == false) + LOGE("%s::fimc destory fail", __func__); + + return false; +} + +bool SecHdmi::destroy(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Already Destroyed fail \n", __func__); + goto DESTROY_FAIL; + } + + for (int layer = HDMI_LAYER_BASE + 1; layer <= HDMI_LAYER_GRAPHIC_0; layer++) { + if (mFlagHdmiStart[layer] == true && m_stopHdmi(layer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail \n", __func__, layer); + goto DESTROY_FAIL; + } + + if (hdmi_deinit_layer(layer) < 0) { + LOGE("%s::hdmi_deinit_layer(%d) fail \n", __func__, layer); + goto DESTROY_FAIL; + } + } + +#if !defined(BOARD_USE_V4L2) + tvout_deinit(); +#endif + + if (mSecFimc.flagCreate() == true && mSecFimc.destroy() == false) { + LOGE("%s::fimc destory fail \n", __func__); + goto DESTROY_FAIL; + } + +#ifdef USE_LCD_ADDR_IN_HERE + { + if (0 < mDefaultFBFd) { + close(mDefaultFBFd); + mDefaultFBFd = -1; + } + } +#endif //USE_LCD_ADDR_IN_HERE + +#if defined(BOARD_USE_V4L2_ION) + if (mFBaddr != NULL) + ion_unmap((void *)mFBaddr, ALIGN(mFBsize * 4 * 2, PAGE_SIZE)); + + if (mFBionfd > 0) + ion_free(mFBionfd); + + mFBaddr = NULL; + mFBionfd = -1; + mFBsize = 0; +#endif + +#if defined(BOARD_USE_V4L2_ION) && defined(BOARD_USES_FIMGAPI) + ion_unmap((void *)g2d_reserved_memory[0], ALIGN(g2d_reserved_memory_size * HDMI_G2D_OUTPUT_BUF_NUM, PAGE_SIZE)); +#endif + + mFlagCreate = false; + + return true; + +DESTROY_FAIL : + + return false; +} + +bool SecHdmi::connect(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + { + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (mFlagConnected == true) { + LOGD("%s::Already Connected.. \n", __func__); + return true; + } + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (m_flagHWConnected() == false) { + LOGD("%s::m_flagHWConnected() fail \n", __func__); + return false; + } + +#if defined(BOARD_USES_EDID) + if (!EDIDOpen()) + LOGE("EDIDInit() failed!\n"); + + if (!EDIDRead()) { + LOGE("EDIDRead() failed!\n"); + if (!EDIDClose()) + LOGE("EDIDClose() failed!\n"); + } +#endif + +#if defined(BOARD_USES_CEC) + if (!(mCECThread->mFlagRunning)) + mCECThread->start(); +#endif + } + } + + if (this->setHdmiOutputMode(mHdmiOutputMode, true) == false) + LOGE("%s::setHdmiOutputMode(%d) fail \n", __func__, mHdmiOutputMode); + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (this->setHdmiResolution(mHdmiResolutionValue, true) == false) + LOGE("%s::setHdmiResolution(%d) fail \n", __func__, mHdmiResolutionValue); + + if (this->setHdcpMode(mHdcpMode, false) == false) + LOGE("%s::setHdcpMode(%d) fail \n", __func__, mHdcpMode); + + mHdmiInfoChange = true; + mFlagConnected = true; + +#if defined(BOARD_USES_EDID) + // show display.. + display_menu(); +#endif + } + + return true; +} + +bool SecHdmi::disconnect(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (mFlagConnected == false) { + LOGE("%s::Already Disconnected.. \n", __func__); + return true; + } + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USES_CEC) + if (mCECThread->mFlagRunning) + mCECThread->stop(); +#endif + +#if defined(BOARD_USES_EDID) + if (!EDIDClose()) { + LOGE("EDIDClose() failed!\n"); + return false; + } +#endif + } + + for (int layer = SecHdmi::HDMI_LAYER_BASE + 1; layer <= SecHdmi::HDMI_LAYER_GRAPHIC_0; layer++) { + if (mFlagHdmiStart[layer] == true && m_stopHdmi(layer) == false) { + LOGE("%s::hdmiLayer(%d) layer fail \n", __func__, layer); + return false; + } + } + +#if defined(BOARD_USE_V4L2) + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (hdmi_deinit_layer(layer) < 0) + LOGE("%s::hdmi_deinit_layer(%d) fail", __func__, layer); + } +#else + tvout_deinit(); +#endif + + mFlagConnected = false; + + mHdmiOutputMode = DEFAULT_OUPUT_MODE; + mHdmiResolutionValue = DEFAULT_HDMI_RESOLUTION_VALUE; +#if defined(BOARD_USE_V4L2) + mHdmiPresetId = DEFAULT_HDMI_PRESET_ID; +#else + mHdmiStdId = DEFAULT_HDMI_STD_ID; +#endif + mCompositeStd = DEFAULT_COMPOSITE_STD; + mAudioMode = 2; + mCurrentHdmiOutputMode = -1; + mCurrentHdmiResolutionValue = 0; + mCurrentAudioMode = -1; + mFimcCurrentOutBufIndex = 0; + + return true; +} + +bool SecHdmi::flagConnected(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + return mFlagConnected; +} + +bool SecHdmi::flush(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, unsigned int srcCrAddr, + int dstX, int dstY, + int hdmiLayer, + int num_of_hwc_layer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s [srcW=%d, srcH=%d, srcColorFormat=0x%x, srcYAddr=0x%x, srcCbAddr=0x%x, srcCrAddr=0x%x, dstX=%d, dstY=%d, hdmiLayer=%d]", + __func__, srcW, srcH, srcColorFormat, srcYAddr, srcCbAddr, srcCrAddr, dstX, dstY, hdmiLayer); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + +#if defined(BOARD_USE_V4L2) + if (hdmiLayer == HDMI_LAYER_VIDEO) { + mDstWidth[hdmiLayer] = mHdmiDstWidth; + mDstHeight[hdmiLayer] = mHdmiDstHeight; + } else { + if (num_of_hwc_layer == 0) { + struct v4l2_rect rect; + int tempSrcW, tempSrcH; + + if (mG2DUIRotVal == 0 || mG2DUIRotVal == 180) { + tempSrcW = srcW; + tempSrcH = srcH; + } else { + tempSrcW = srcH; + tempSrcH = srcW; + } + + hdmi_cal_rect(tempSrcW, tempSrcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + mDstWidth[hdmiLayer] = rect.width; + mDstHeight[hdmiLayer] = rect.height; + mDstWidth[HDMI_LAYER_VIDEO] = 0; + mDstHeight[HDMI_LAYER_VIDEO] = 0; + } else { + mDstWidth[hdmiLayer] = mHdmiDstWidth; + mDstHeight[hdmiLayer] = mHdmiDstHeight; + } + } +#ifdef DEBUG_MSG_ENABLE + LOGE("m_reset param(%d, %d, %d, %d)", + mDstWidth[hdmiLayer], mDstHeight[hdmiLayer], \ + mPrevDstWidth[hdmiLayer], mPrevDstHeight[hdmiLayer]); +#endif +#endif + + if (srcW != mSrcWidth[hdmiLayer] || + srcH != mSrcHeight[hdmiLayer] || + srcColorFormat != mSrcColorFormat[hdmiLayer] || + mHdmiDstWidth != mHdmiResolutionWidth[hdmiLayer] || + mHdmiDstHeight != mHdmiResolutionHeight[hdmiLayer] || +#if defined(BOARD_USE_V4L2) + mDstWidth[hdmiLayer] != mPrevDstWidth[hdmiLayer] || + mDstHeight[hdmiLayer] != mPrevDstHeight[hdmiLayer] || +#endif + mHdmiInfoChange == true) { +#ifdef DEBUG_MSG_ENABLE + LOGD("m_reset param(%d, %d, %d, %d, %d, %d, %d)", + srcW, mSrcWidth[hdmiLayer], \ + srcH, mSrcHeight[hdmiLayer], \ + srcColorFormat,mSrcColorFormat[hdmiLayer], \ + hdmiLayer); +#endif + + if (m_reset(srcW, srcH, srcColorFormat, hdmiLayer, num_of_hwc_layer) == false) { + LOGE("%s::m_reset(%d, %d, %d, %d, %d) fail", __func__, srcW, srcH, srcColorFormat, hdmiLayer, num_of_hwc_layer); + return false; + } + } + + if (srcYAddr == 0) { +#if defined(BOARD_USE_V4L2_ION) + unsigned int FB_size = ALIGN(srcW, 16) * ALIGN(srcH, 16) * HDMI_FB_BPP_SIZE; + void *virFBAddr = 0; + struct s3c_fb_user_ion_client ion_handle; + + if (mFBaddr != NULL) { + ion_unmap((void *)mFBaddr, ALIGN(mFBsize * 2, PAGE_SIZE)); + ion_free(mFBionfd); + } + + // get framebuffer virtual address for LCD + if (ioctl(mDefaultFBFd, S3CFB_GET_ION_USER_HANDLE, &ion_handle) < 0) { + LOGE("%s:ioctl(S3CFB_GET_ION_USER_HANDLE) fail", __func__); + return false; + } + + virFBAddr = ion_map(ion_handle.fd, ALIGN(FB_size * 2, PAGE_SIZE), 0); + if (virFBAddr == MAP_FAILED) { + LOGE("%s::ion_map fail", __func__); + ion_free(ion_handle.fd); + mFBaddr = NULL; + return false; + } + + if ((mFBIndex % 2) == 0) + srcYAddr = (unsigned int)virFBAddr; + else + srcYAddr = (unsigned int)virFBAddr + FB_size; + + srcCbAddr = srcYAddr; + + mFBIndex++; + mFBaddr = virFBAddr; + mFBsize = FB_size; + mFBionfd = ion_handle.fd; +#else + unsigned int phyFBAddr = 0; + + // get physical framebuffer address for LCD + if (ioctl(mDefaultFBFd, S3CFB_GET_FB_PHY_ADDR, &phyFBAddr) == -1) { + LOGE("%s:ioctl(S3CFB_GET_FB_PHY__ADDR) fail", __func__); + return false; + } + + /* + * when early suspend, FIMD IP off. + * so physical framebuffer address for LCD is 0x00000000 + * so JUST RETURN. + */ + if (phyFBAddr == 0) { + LOGE("%s::S3CFB_GET_FB_PHY_ADDR fail", __func__); + return true; + } + srcYAddr = phyFBAddr; + srcCbAddr = srcYAddr; +#endif + } + + if (hdmiLayer == HDMI_LAYER_VIDEO) { + if (srcColorFormat == HAL_PIXEL_FORMAT_YCbCr_420_SP || + srcColorFormat == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP) { +#if defined(BOARD_USE_V4L2) + mMixerBuffer[hdmiLayer][0].virt.extP[0] = (char *)srcYAddr; + mMixerBuffer[hdmiLayer][0].virt.extP[1] = (char *)srcCbAddr; +#else + hdmi_set_v_param(hdmiLayer, + srcW, srcH, V4L2_PIX_FMT_NV12, + srcYAddr, srcCbAddr, + mHdmiDstWidth, mHdmiDstHeight); +#endif + } else if (srcColorFormat == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED) { +#if defined(BOARD_USE_V4L2) + mMixerBuffer[hdmiLayer][0].virt.extP[0] = (char *)srcYAddr; + mMixerBuffer[hdmiLayer][0].virt.extP[1] = (char *)srcCbAddr; +#else + hdmi_set_v_param(hdmiLayer, + srcW, srcH, V4L2_PIX_FMT_NV12T, + srcYAddr, srcCbAddr, + mHdmiDstWidth, mHdmiDstHeight); +#endif + } else if (srcColorFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP || + srcColorFormat == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP) { +#if defined(BOARD_USE_V4L2) + mMixerBuffer[hdmiLayer][0].virt.extP[0] = (char *)srcYAddr; + mMixerBuffer[hdmiLayer][0].virt.extP[1] = (char *)srcCbAddr; +#else + hdmi_set_v_param(hdmiLayer, + srcW, srcH, V4L2_PIX_FMT_NV21, + srcYAddr, srcCbAddr, + mHdmiDstWidth, mHdmiDstHeight); +#endif + } else { + if (mSecFimc.setSrcAddr(srcYAddr, srcCbAddr, srcCrAddr, srcColorFormat) == false) { + LOGE("%s::setSrcAddr(%d, %d, %d) fail", + __func__, srcYAddr, srcCbAddr, srcCrAddr); + return false; + } + + int y_size = 0; + if (mUIRotVal == 0 || mUIRotVal == 180) + y_size = ALIGN(ALIGN(srcW,128) * ALIGN(srcH, 32), SZ_8K); + else + y_size = ALIGN(ALIGN(srcH,128) * ALIGN(srcW, 32), SZ_8K); + + mHdmiSrcYAddr = mFimcReservedMem[mFimcCurrentOutBufIndex].phys.extP[0]; +#ifdef BOARD_USE_V4L2 + mHdmiSrcCbCrAddr = mFimcReservedMem[mFimcCurrentOutBufIndex].phys.extP[1]; +#else + mHdmiSrcCbCrAddr = mFimcReservedMem[mFimcCurrentOutBufIndex].phys.extP[0] + y_size; +#endif + if (mSecFimc.setDstAddr(mHdmiSrcYAddr, mHdmiSrcCbCrAddr, 0, mFimcCurrentOutBufIndex) == false) { + LOGE("%s::mSecFimc.setDstAddr(%d, %d) fail \n", + __func__, mHdmiSrcYAddr, mHdmiSrcCbCrAddr); + return false; + } + + if (mSecFimc.draw(0, mFimcCurrentOutBufIndex) == false) { + LOGE("%s::mSecFimc.draw() fail \n", __func__); + return false; + } +#if defined(BOARD_USE_V4L2) + mMixerBuffer[hdmiLayer][0].virt.extP[0] = (char *)mHdmiSrcYAddr; + mMixerBuffer[hdmiLayer][0].virt.extP[1] = (char *)mHdmiSrcCbCrAddr; +#else + if (mUIRotVal == 0 || mUIRotVal == 180) + hdmi_set_v_param(hdmiLayer, + srcW, srcH, V4L2_PIX_FMT_NV12T, + mHdmiSrcYAddr, mHdmiSrcCbCrAddr, + mHdmiDstWidth, mHdmiDstHeight); + else + hdmi_set_v_param(hdmiLayer, + srcH, srcW, V4L2_PIX_FMT_NV12T, + mHdmiSrcYAddr, mHdmiSrcCbCrAddr, + mHdmiDstWidth, mHdmiDstHeight); +#endif + mFimcCurrentOutBufIndex++; + if (mFimcCurrentOutBufIndex >= HDMI_FIMC_OUTPUT_BUF_NUM) + mFimcCurrentOutBufIndex = 0; + } + + } else { + if (srcColorFormat != HAL_PIXEL_FORMAT_BGRA_8888 && + srcColorFormat != HAL_PIXEL_FORMAT_RGBA_8888 && + srcColorFormat != HAL_PIXEL_FORMAT_RGB_565) { + if (mSecFimc.setSrcAddr(srcYAddr, srcCbAddr, srcCrAddr, srcColorFormat) == false) { + LOGE("%s::setSrcAddr(%d, %d, %d) fail", + __func__, srcYAddr, srcCbAddr, srcCrAddr); + return false; + } + + if (mSecFimc.draw(0, mFimcCurrentOutBufIndex) == false) { + LOGE("%s::mSecFimc.draw() failed", __func__); + return false; + } +#if defined(BOARD_USE_V4L2) + if (hdmi_set_g_scaling(hdmiLayer, + HAL_PIXEL_FORMAT_BGRA_8888, + mDstRect.width, mDstRect.height, + mHdmiSrcYAddr, &mMixerBuffer[hdmiLayer][0], + mDstRect.left , mDstRect.top, + mHdmiDstWidth, mHdmiDstHeight, + mG2DUIRotVal, + num_of_hwc_layer) < 0) + return false; +#else + if (hdmi_gl_set_param(hdmiLayer, + HAL_PIXEL_FORMAT_BGRA_8888, + mDstRect.width, mDstRect.height, + mHdmiSrcYAddr, mHdmiSrcCbCrAddr, + mDstRect.left , mDstRect.top, + mHdmiDstWidth, mHdmiDstHeight, + mG2DUIRotVal) < 0) +#endif + return false; + } else { +#if CHECK_GRAPHIC_LAYER_TIME + nsecs_t start, end; + start = systemTime(); +#endif + if (num_of_hwc_layer == 0) { /* UI only mode */ + struct v4l2_rect rect; + + if (mG2DUIRotVal == 0 || mG2DUIRotVal == 180) + hdmi_cal_rect(srcW, srcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + else + hdmi_cal_rect(srcH, srcW, mHdmiDstWidth, mHdmiDstHeight, &rect); + + rect.left = ALIGN(rect.left, 16); + +#if defined(BOARD_USE_V4L2) + if (hdmi_set_g_scaling(hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, &mMixerBuffer[hdmiLayer][0], + rect.left, rect.top, + rect.width, rect.height, + mG2DUIRotVal, + num_of_hwc_layer) < 0) + return false; +#else + if (hdmi_gl_set_param(hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, srcCbAddr, + rect.left, rect.top, + rect.width, rect.height, + mG2DUIRotVal) < 0) + return false; +#endif + } else { /* Video Playback Mode */ +#if defined(BOARD_USE_V4L2) + if (hdmi_set_g_scaling(hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, &mMixerBuffer[hdmiLayer][0], + dstX, dstY, + mHdmiDstWidth, mHdmiDstHeight, + mG2DUIRotVal, + num_of_hwc_layer) < 0) + return false; +#else + if (hdmi_gl_set_param(hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, srcCbAddr, + dstX, dstY, + mHdmiDstWidth, mHdmiDstHeight, + mG2DUIRotVal) < 0) + return false; +#endif + } +#if CHECK_GRAPHIC_LAYER_TIME + end = systemTime(); + LOGD("[UI] hdmi_gl_set_param[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + } + } + + if (mFlagConnected) { +#if defined(BOARD_USE_V4L2) + unsigned int num_of_plane; + + if (hdmi_get_src_plane(srcColorFormat, &num_of_plane) < 0) { + LOGE("%s::hdmi_get_src_plane(%d) fail", __func__, srcColorFormat); + return false; + } + + if (mFlagHdmiStart[hdmiLayer] == false && m_startHdmi(hdmiLayer, num_of_plane) == false) { + LOGE("%s::hdmiLayer(%d) fail", __func__, hdmiLayer); + return false; + } +#else + if (mFlagHdmiStart[hdmiLayer] == false && m_startHdmi(hdmiLayer) == false) { + LOGE("%s::hdmiLayer(%d) fail", __func__, hdmiLayer); + return false; + } +#endif + } + + return true; +} + +bool SecHdmi::clear(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s || hdmiLayer = %d", __func__, hdmiLayer); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + if (mFlagHdmiStart[hdmiLayer] == true && m_stopHdmi(hdmiLayer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail \n", __func__, hdmiLayer); + return false; + } + return true; +} + +bool SecHdmi::setHdmiOutputMode(int hdmiOutputMode, bool forceRun) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmiOutputMode = %d, forceRun = %d", __func__, hdmiOutputMode, forceRun); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdmiOutputMode == hdmiOutputMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiOutputMode(%d) \n", __func__, hdmiOutputMode); +#endif + return true; + } + + int newHdmiOutputMode = hdmiOutputMode; + + int v4l2OutputType = hdmi_outputmode_2_v4l2_output_type(hdmiOutputMode); + if (v4l2OutputType < 0) { + LOGD("%s::hdmi_outputmode_2_v4l2_output_type(%d) fail\n", __func__, hdmiOutputMode); + return false; + } + +#if defined(BOARD_USES_EDID) + int newV4l2OutputType = hdmi_check_output_mode(v4l2OutputType); + if (newV4l2OutputType != v4l2OutputType) { + newHdmiOutputMode = hdmi_v4l2_output_type_2_outputmode(newV4l2OutputType); + if (newHdmiOutputMode < 0) { + LOGD("%s::hdmi_v4l2_output_type_2_outputmode(%d) fail\n", __func__, newV4l2OutputType); + return false; + } + + LOGD("%s::calibration mode(%d -> %d)... \n", __func__, hdmiOutputMode, newHdmiOutputMode); + mHdmiInfoChange = true; + } +#endif + + if (mHdmiOutputMode != newHdmiOutputMode) { + mHdmiOutputMode = newHdmiOutputMode; + mHdmiInfoChange = true; + } + + return true; +} + +bool SecHdmi::setHdmiResolution(unsigned int hdmiResolutionValue, bool forceRun) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s:: hdmiResolutionValue = %d, forceRun = %d", __func__, hdmiResolutionValue, forceRun); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdmiResolutionValue == hdmiResolutionValue) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiResolutionValue(%d) \n", __func__, hdmiResolutionValue); +#endif + return true; + } + + unsigned int newHdmiResolutionValue = hdmiResolutionValue; + int w = 0; + int h = 0; + +#if defined(BOARD_USES_EDID) + // find perfect resolutions.. +#if defined(BOARD_USE_V4L2) + unsigned int preset_id; + if (hdmi_resolution_2_preset_id(newHdmiResolutionValue, &w, &h, &preset_id) < 0 || + hdmi_check_resolution(preset_id) < 0) { + bool flagFoundIndex = false; + int resolutionValueIndex = m_resolutionValueIndex(newHdmiResolutionValue); + + for (int i = resolutionValueIndex + 1; i < mHdmiSizeOfResolutionValueList; i++) { + if (hdmi_resolution_2_preset_id(mHdmiResolutionValueList[i], &w, &h, &preset_id) == 0 && + hdmi_check_resolution(preset_id) == 0) { + newHdmiResolutionValue = mHdmiResolutionValueList[i]; + flagFoundIndex = true; + break; + } + } + + if (flagFoundIndex == false) { + LOGE("%s::hdmi cannot control this resolution(%d) fail \n", __func__, hdmiResolutionValue); + // Set resolution to 480P + newHdmiResolutionValue = mHdmiResolutionValueList[mHdmiSizeOfResolutionValueList-2]; + } else { + LOGD("%s::HDMI resolutions size is calibrated(%d -> %d)..\n", __func__, hdmiResolutionValue, newHdmiResolutionValue); + } + } +#else + v4l2_std_id std_id; + if (hdmi_resolution_2_std_id(newHdmiResolutionValue, &w, &h, &std_id) < 0 || + hdmi_check_resolution(std_id) < 0) { + bool flagFoundIndex = false; + int resolutionValueIndex = m_resolutionValueIndex(newHdmiResolutionValue); + + for (int i = resolutionValueIndex + 1; i < mHdmiSizeOfResolutionValueList; i++) { + if (hdmi_resolution_2_std_id(mHdmiResolutionValueList[i], &w, &h, &std_id) == 0 && + hdmi_check_resolution(std_id) == 0) { + newHdmiResolutionValue = mHdmiResolutionValueList[i]; + flagFoundIndex = true; + break; + } + } + + if (flagFoundIndex == false) { + LOGE("%s::hdmi cannot control this resolution(%d) fail \n", __func__, hdmiResolutionValue); + // Set resolution to 480P + newHdmiResolutionValue = mHdmiResolutionValueList[mHdmiSizeOfResolutionValueList-2]; + } else { + LOGD("%s::HDMI resolutions size is calibrated(%d -> %d)..\n", __func__, hdmiResolutionValue, newHdmiResolutionValue); + } + } +#endif + else { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::find resolutions(%d) at once\n", __func__, hdmiResolutionValue); +#endif + } +#endif + + if (mHdmiResolutionValue != newHdmiResolutionValue) { + mHdmiResolutionValue = newHdmiResolutionValue; + mHdmiInfoChange = true; + } + + return true; +} + +bool SecHdmi::setHdcpMode(bool hdcpMode, bool forceRun) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdcpMode == hdcpMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdcpMode(%d) \n", __func__, hdcpMode); +#endif + return true; + } + + mHdcpMode = hdcpMode; + mHdmiInfoChange = true; + + return true; +} + +bool SecHdmi::setUIRotation(unsigned int rotVal, unsigned int hwcLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (rotVal % 90 != 0) { + LOGE("%s::Invalid rotation value(%d)", __func__, rotVal); + return false; + } + + /* G2D rotation */ + if (rotVal != mG2DUIRotVal) { + mG2DUIRotVal = rotVal; + mHdmiInfoChange = true; + } + + /* FIMC rotation */ + if (hwcLayer == 0) { /* Rotate in UI only mode */ + if (rotVal != mUIRotVal) { + mSecFimc.setRotVal(rotVal); + mUIRotVal = rotVal; + mHdmiInfoChange = true; + } + } else { /* Don't rotate video layer when video is played. */ + rotVal = 0; + if (rotVal != mUIRotVal) { + mSecFimc.setRotVal(rotVal); + mUIRotVal = rotVal; + mHdmiInfoChange = true; + } + } + + return true; +} + +bool SecHdmi::setDisplaySize(int width, int height) +{ + mDisplayWidth = width; + mDisplayHeight = height; + + return true; +} + +bool SecHdmi::m_reset(int w, int h, int colorFormat, int hdmiLayer, int hwcLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called", __func__); +#endif + v4l2_std_id std_id = 0; + mFimcCurrentOutBufIndex = 0; + + int srcW = w; + int srcH = h; + +#if defined(BOARD_USE_V4L2) + if (mFlagHdmiStart[hdmiLayer] == true && m_stopHdmi(hdmiLayer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail", __func__, hdmiLayer); + return false; + } +#else + // stop all.. + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (mFlagHdmiStart[layer] == true && m_stopHdmi(layer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail", __func__, layer); + return false; + } + } +#endif + +#if defined(BOARD_USE_V4L2) + if (hdmi_deinit_layer(hdmiLayer) < 0) + LOGE("%s::hdmi_deinit_layer(%d) fail", __func__, hdmiLayer); + + mHdmiFd[hdmiLayer] = hdmi_init_layer(hdmiLayer); + if (mHdmiFd[hdmiLayer] < 0) + LOGE("%s::hdmi_init_layer(%d) fail", __func__, hdmiLayer); + + if (tvout_std_v4l2_init(mHdmiFd[hdmiLayer], mHdmiPresetId) < 0) + LOGE("%s::tvout_std_v4l2_init fail", __func__); +#endif + + if (w != mSrcWidth [hdmiLayer] || + h != mSrcHeight [hdmiLayer] || + mHdmiDstWidth != mHdmiResolutionWidth[hdmiLayer] || + mHdmiDstHeight != mHdmiResolutionHeight[hdmiLayer] || +#if defined(BOARD_USE_V4L2) + mDstWidth[hdmiLayer] != mPrevDstWidth[hdmiLayer] || + mDstHeight[hdmiLayer] != mPrevDstHeight[hdmiLayer] || +#endif + colorFormat != mSrcColorFormat[hdmiLayer]) { + int preVideoSrcColorFormat = mSrcColorFormat[hdmiLayer]; + int videoSrcColorFormat = colorFormat; + + if (preVideoSrcColorFormat != HAL_PIXEL_FORMAT_YCbCr_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED) { + LOGI("%s: Unsupported preVideoSrcColorFormat = 0x%x\n", __func__, preVideoSrcColorFormat); + preVideoSrcColorFormat = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + } + + if (hdmiLayer == HDMI_LAYER_VIDEO) { + if (colorFormat != HAL_PIXEL_FORMAT_YCbCr_420_SP && + colorFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP && + colorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP && + colorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP && + colorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s call mSecFimc.setSrcParams\n", __func__); +#endif + unsigned int full_wdith = ALIGN(w, 16); + unsigned int full_height = ALIGN(h, 2); + + if (mSecFimc.setSrcParams(full_wdith, full_height, 0, 0, + (unsigned int*)&w, (unsigned int*)&h, colorFormat, true) == false) { + LOGE("%s::mSecFimc.setSrcParams(%d, %d, %d) fail \n", + __func__, w, h, colorFormat); + return false; + } + + mFimcDstColorFormat = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s call mSecFimc.setDstParams\n", __func__); +#endif + if (mUIRotVal == 0 || mUIRotVal == 180) { + if (mSecFimc.setDstParams((unsigned int)w, (unsigned int)h, 0, 0, + (unsigned int*)&w, (unsigned int*)&h, mFimcDstColorFormat, true) == false) { + LOGE("%s::mSecFimc.setDstParams(%d, %d, %d) fail \n", + __func__, w, h, mFimcDstColorFormat); + return false; + } +#if defined(BOARD_USE_V4L2) + hdmi_set_v_param(mHdmiFd[hdmiLayer], hdmiLayer, + mFimcDstColorFormat, srcW, srcH, + &mMixerBuffer[hdmiLayer][0], + 0, 0, mHdmiDstWidth, mHdmiDstHeight); +#endif + } else { + if (mSecFimc.setDstParams((unsigned int)h, (unsigned int)w, 0, 0, + (unsigned int*)&h, (unsigned int*)&w, mFimcDstColorFormat, true) == false) { + LOGE("%s::mSecFimc.setDstParams(%d, %d, %d) fail \n", + __func__, w, h, mFimcDstColorFormat); + return false; + } +#if defined(BOARD_USE_V4L2) + hdmi_set_v_param(mHdmiFd[hdmiLayer], hdmiLayer, + mFimcDstColorFormat, srcH, srcW, + &mMixerBuffer[hdmiLayer][0], + 0, 0, mHdmiDstWidth, mHdmiDstHeight); +#endif + } + } +#if defined(BOARD_USE_V4L2) + else { + hdmi_set_v_param(mHdmiFd[hdmiLayer], hdmiLayer, + colorFormat, srcW, srcH, + &mMixerBuffer[hdmiLayer][0], + 0, 0, mHdmiDstWidth, mHdmiDstHeight); + } +#endif + mPrevDstWidth[hdmiLayer] = mHdmiDstWidth; + mPrevDstHeight[hdmiLayer] = mHdmiDstHeight; + } else { +#if defined(BOARD_USE_V4L2) + struct v4l2_rect rect; + int tempSrcW, tempSrcH; + + if (mG2DUIRotVal == 0 || mG2DUIRotVal == 180) { + tempSrcW = srcW; + tempSrcH = srcH; + } else { + tempSrcW = srcH; + tempSrcH = srcW; + } + + hdmi_cal_rect(tempSrcW, tempSrcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + rect.left = ALIGN(rect.left, 16); + + if (hwcLayer == 0) { /* UI only mode */ + hdmi_set_g_param(mHdmiFd[hdmiLayer], hdmiLayer, + colorFormat, srcW, srcH, + &mMixerBuffer[hdmiLayer][0], + rect.left, rect.top, rect.width, rect.height); + mPrevDstWidth[hdmiLayer] = rect.width; + mPrevDstHeight[hdmiLayer] = rect.height; + mPrevDstWidth[HDMI_LAYER_VIDEO] = 0; + mPrevDstHeight[HDMI_LAYER_VIDEO] = 0; + } else { /* Video Playback + UI Mode */ + hdmi_set_g_param(mHdmiFd[hdmiLayer], hdmiLayer, + colorFormat, srcW, srcH, + &mMixerBuffer[hdmiLayer][0], + 0, 0, mHdmiDstWidth, mHdmiDstHeight); + mPrevDstWidth[hdmiLayer] = mHdmiDstWidth; + mPrevDstHeight[hdmiLayer] = mHdmiDstHeight; + } +#endif + } + + if (preVideoSrcColorFormat != videoSrcColorFormat) + mHdmiInfoChange = true; + + mSrcWidth[hdmiLayer] = srcW; + mSrcHeight[hdmiLayer] = srcH; + mSrcColorFormat[hdmiLayer] = colorFormat; + + mHdmiResolutionWidth[hdmiLayer] = mHdmiDstWidth; + mHdmiResolutionHeight[hdmiLayer] = mHdmiDstHeight; + +#ifdef DEBUG_MSG_ENABLE + LOGD("m_reset saved param(%d, %d, %d, %d, %d, %d, %d) \n", + srcW, mSrcWidth[hdmiLayer], \ + srcH, mSrcHeight[hdmiLayer], \ + colorFormat,mSrcColorFormat[hdmiLayer], \ + hdmiLayer); +#endif + } + + if (mHdmiInfoChange == true) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("mHdmiInfoChange: %d\n", mHdmiInfoChange); +#endif + // stop all.. +#if defined(BOARD_USES_CEC) + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (mCECThread->mFlagRunning) + mCECThread->stop(); + } +#endif + + if (m_setHdmiOutputMode(mHdmiOutputMode) == false) { + LOGE("%s::m_setHdmiOutputMode() fail \n", __func__); + return false; + } + if (mHdmiOutputMode == COMPOSITE_OUTPUT_MODE) { + std_id = composite_std_2_v4l2_std_id(mCompositeStd); + if ((int)std_id < 0) { + LOGE("%s::composite_std_2_v4l2_std_id(%d) fail\n", __func__, mCompositeStd); + return false; + } + if (m_setCompositeResolution(mCompositeStd) == false) { + LOGE("%s::m_setCompositeRsolution() fail \n", __func__); + return false; + } + } else if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (m_setHdmiResolution(mHdmiResolutionValue) == false) { + LOGE("%s::m_setHdmiResolution() fail \n", __func__); + return false; + } + + if (m_setHdcpMode(mHdcpMode) == false) { + LOGE("%s::m_setHdcpMode() fail \n", __func__); + return false; + } +#if !defined(BOARD_USE_V4L2) + std_id = mHdmiStdId; +#endif + } + +#if !defined(BOARD_USE_V4L2) + fp_tvout = tvout_init(std_id); + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (hdmi_deinit_layer(layer) < 0) + LOGE("%s::hdmi_init_layer(%d) fail \n", __func__, layer); + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (hdmi_init_layer(layer) < 0) + LOGE("%s::hdmi_init_layer(%d) fail \n", __func__, layer); + } +#endif + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USES_CEC) + if (!(mCECThread->mFlagRunning)) + mCECThread->start(); +#endif + + if (m_setAudioMode(mAudioMode) == false) + LOGE("%s::m_setAudioMode() fail \n", __func__); + } + + mHdmiInfoChange = false; +#ifdef BOARD_USE_V4L2 + for (int i = 0; i < HDMI_FIMC_OUTPUT_BUF_NUM; i++) + mFimcReservedMem[i] = *(mSecFimc.getMemAddr(i)); +#endif + } + + return true; +} + +#if defined(BOARD_USE_V4L2) +bool SecHdmi::m_startHdmi(int hdmiLayer, unsigned int num_of_plane) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + bool ret = true; + int buf_index = 0; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s: hdmiLayer(%d) called\n", __func__, hdmiLayer); +#endif + + if (mFlagLayerEnable[hdmiLayer]) { + static unsigned int index = 0; + + if (mFlagHdmiStart[hdmiLayer] == false) { + index = 0; + if (tvout_std_v4l2_qbuf(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, + index, num_of_plane, &mMixerBuffer[hdmiLayer][0]) < 0) { + LOGE("%s::tvout_std_v4l2_qbuf(index : %d) (mSrcBufNum : %d) failed", __func__, index, HDMI_NUM_MIXER_BUF); + return false; + } + index++; + + if (tvout_std_v4l2_streamon(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::tvout_std_v4l2_streamon() failed", __func__); + return false; + } + + mFlagHdmiStart[hdmiLayer] = true; + } else { + if (tvout_std_v4l2_qbuf(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, + index, num_of_plane, &mMixerBuffer[hdmiLayer][0]) < 0) { + LOGE("%s::tvout_std_v4l2_qbuf() failed", __func__); + return false; + } + + if (tvout_std_v4l2_dqbuf(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, &buf_index, num_of_plane) < 0) { + LOGE("%s::tvout_std_v4l2_dqbuf() failed", __func__); + return false; + } + index = buf_index; + } + } + + return true; +} +#else +bool SecHdmi::m_startHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + bool ret = true; + int buf_index = 0; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s: hdmiLayer(%d) called\n", __func__, hdmiLayer); +#endif + + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + tvout_v4l2_start_overlay(fp_tvout_v); + mFlagHdmiStart[hdmiLayer] = true; + break; + case HDMI_LAYER_GRAPHIC_0 : + if (mFlagLayerEnable[hdmiLayer]) { + if (ioctl(fp_tvout_g0, FBIOBLANK, (void *)FB_BLANK_UNBLANK) != -1) + mFlagHdmiStart[hdmiLayer] = true; + } + break; + case HDMI_LAYER_GRAPHIC_1 : + if (mFlagLayerEnable[hdmiLayer]) { + if (ioctl(fp_tvout_g1, FBIOBLANK, (void *)FB_BLANK_UNBLANK) != -1) + mFlagHdmiStart[hdmiLayer] = true; + } + break; + default : + LOGE("%s::unmathced layer(%d) fail", __func__, hdmiLayer); + ret = false; + break; + } + + return true; +} +#endif + +bool SecHdmi::m_stopHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + bool ret = true; + if (mFlagHdmiStart[hdmiLayer] == false) { + LOGD("%s::already HDMI(%d layer) stopped.. \n", __func__, hdmiLayer); + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s : layer[%d] called\n", __func__, hdmiLayer); +#endif + +#if defined(BOARD_USE_V4L2) + int fd; + + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + break; + case HDMI_LAYER_GRAPHIC_0 : + break; + case HDMI_LAYER_GRAPHIC_1 : +#if defined(BOARD_USES_FIMGAPI) + cur_g2d_address = 0; + g2d_buf_index = 0; +#endif + break; + default : + LOGE("%s::unmathced layer(%d) fail", __func__, hdmiLayer); + ret = false; + break; + } + + if (mFlagLayerEnable[hdmiLayer]) { + if (tvout_std_v4l2_streamoff(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::tvout_std_v4l2_streamon layer(%d) failed", __func__, hdmiLayer); + return false; + } + + /* clear buffer */ + if (tvout_std_v4l2_reqbuf(mHdmiFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, 0) < 0) { + LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[graphic layer] failed", __func__, 0); + return -1; + } + + mFlagHdmiStart[hdmiLayer] = false; + } +#else + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + tvout_v4l2_stop_overlay(fp_tvout_v); + mFlagHdmiStart[hdmiLayer] = false; + break; + case HDMI_LAYER_GRAPHIC_0 : + if (mFlagLayerEnable[hdmiLayer]) { + if (ioctl(fp_tvout_g0, FBIOBLANK, (void *)FB_BLANK_POWERDOWN) != -1) + mFlagHdmiStart[hdmiLayer] = false; + } + break; + case HDMI_LAYER_GRAPHIC_1 : +#if defined(BOARD_USES_FIMGAPI) + cur_g2d_address = 0; + g2d_buf_index = 0; +#endif + if (mFlagLayerEnable[hdmiLayer]) { + if (ioctl(fp_tvout_g1, FBIOBLANK, (void *)FB_BLANK_POWERDOWN) != -1) + mFlagHdmiStart[hdmiLayer] = false; + } + break; + default : + LOGE("%s::unmathced layer(%d) fail", __func__, hdmiLayer); + ret = false; + break; + } +#endif + + return true; +} + +bool SecHdmi::m_setHdmiOutputMode(int hdmiOutputMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdmiOutputMode == mCurrentHdmiOutputMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiOutputMode(%d) \n", __func__, hdmiOutputMode); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int v4l2OutputType = hdmi_outputmode_2_v4l2_output_type(hdmiOutputMode); + if (v4l2OutputType < 0) { + LOGE("%s::hdmi_outputmode_2_v4l2_output_type(%d) fail\n", __func__, hdmiOutputMode); + return false; + } + + output_type = v4l2OutputType; + + mCurrentHdmiOutputMode = hdmiOutputMode; + + return true; +} + +bool SecHdmi::m_setCompositeResolution(unsigned int compositeStdId) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int w = 0; + int h = 0; + + if (mHdmiOutputMode != COMPOSITE_OUTPUT_MODE) { + LOGE("%s:: not supported output type \n", __func__); + return false; + } + + switch (compositeStdId) { + case COMPOSITE_STD_NTSC_M: + case COMPOSITE_STD_NTSC_443: + w = 704; + h = 480; + break; + case COMPOSITE_STD_PAL_BDGHI: + case COMPOSITE_STD_PAL_M: + case COMPOSITE_STD_PAL_N: + case COMPOSITE_STD_PAL_Nc: + case COMPOSITE_STD_PAL_60: + w = 704; + h = 576; + break; + default: + LOGE("%s::unmathced composite_std(%d)", __func__, compositeStdId); + return false; + } + + t_std_id = composite_std_2_v4l2_std_id(mCompositeStd); + + mHdmiDstWidth = w; + mHdmiDstHeight = h; + + mCurrentHdmiResolutionValue = -1; + return true; +} + +bool SecHdmi::m_setHdmiResolution(unsigned int hdmiResolutionValue) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdmiResolutionValue == mCurrentHdmiResolutionValue) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiResolutionValue(%d) \n", __func__, hdmiResolutionValue); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int w = 0; + int h = 0; + +#if defined(BOARD_USE_V4L2) + unsigned int preset_id; +#else + v4l2_std_id std_id; +#endif + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USE_V4L2) + if (hdmi_resolution_2_preset_id(hdmiResolutionValue, &w, &h, &preset_id) < 0) { + LOGE("%s::hdmi_resolution_2_std_id(%d) fail\n", __func__, hdmiResolutionValue); + return false; + } + mHdmiPresetId = preset_id; +#else + if (hdmi_resolution_2_std_id(hdmiResolutionValue, &w, &h, &std_id) < 0) { + LOGE("%s::hdmi_resolution_2_std_id(%d) fail\n", __func__, hdmiResolutionValue); + return false; + } + mHdmiStdId = std_id; +#endif + } else { + LOGE("%s:: not supported output type \n", __func__); + return false; + } + +#if defined(BOARD_USE_V4L2) + g_preset_id = preset_id; +#else + t_std_id = std_id; +#endif + + mHdmiDstWidth = w; + mHdmiDstHeight = h; + + mCurrentHdmiResolutionValue = hdmiResolutionValue; + +#ifdef DEBUG_HDMI_HW_LEVEL +#if defined(BOARD_USE_V4L2) + LOGD("%s:: mHdmiDstWidth = %d, mHdmiDstHeight = %d, mHdmiPresetId = 0x%x, hdmiResolutionValue = 0x%x\n", + __func__, + mHdmiDstWidth, + mHdmiDstHeight, + mHdmiPresetId, + hdmiResolutionValue); +#else + LOGD("%s:: mHdmiDstWidth = %d, mHdmiDstHeight = %d, mHdmiStdId = 0x%x, hdmiResolutionValue = 0x%x\n", + __func__, + mHdmiDstWidth, + mHdmiDstHeight, + mHdmiStdId, + hdmiResolutionValue); +#endif +#endif + + return true; +} + +bool SecHdmi::m_setHdcpMode(bool hdcpMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdcpMode == mCurrentHdcpMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdcpMode(%d) \n", __func__, hdcpMode); +#endif + + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + if (hdcpMode == true) + g_hdcp_en = 1; + else + g_hdcp_en = 0; + + mCurrentHdcpMode = hdcpMode; + + return true; +} + +bool SecHdmi::m_setAudioMode(int audioMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (audioMode == mCurrentAudioMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same audioMode(%d) \n", __func__, audioMode); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + if (hdmi_check_audio() < 0) { + LOGE("%s::hdmi_check_audio() fail \n", __func__); + return false; + } + + mCurrentAudioMode = audioMode; + + return true; +} + +int SecHdmi::m_resolutionValueIndex(unsigned int ResolutionValue) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + int index = -1; + + for (int i = 0; i < mHdmiSizeOfResolutionValueList; i++) { + if (mHdmiResolutionValueList[i] == ResolutionValue) { + index = i; + break; + } + } + return index; +} + +bool SecHdmi::m_flagHWConnected(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + bool ret = true; + int hdmiStatus = hdmi_cable_status(); + + if (hdmiStatus <= 0) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmi_cable_status() fail \n", __func__); +#endif + ret = false; + } else { + ret = true; + } + + return ret; +} + +}; // namespace android diff --git a/exynos4/hal/libhdmi/SecHdmi/SecHdmiCommon.h b/exynos4/hal/libhdmi/SecHdmi/SecHdmiCommon.h new file mode 100644 index 0000000..203dfe4 --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/SecHdmiCommon.h @@ -0,0 +1,138 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +** +** @author Sangwoo, Park(sw5771.park@samsung.com) +** @date 2010-09-10 +** +*/ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#include + +#include "videodev2.h" +#if defined(BOARD_USE_V4L2) +#include "s5p_tvout_v4l2.h" +#else +#include "s5p_tvout.h" +#endif + +//#define DEBUG_MSG_ENABLE +//#define DEBUG_HDMI_HW_LEVEL +#define BOARD_USES_EDID +//#define BOARD_USES_CEC +#if defined(SAMSUNG_EXYNOS4x12) +//#define SUPPORT_G2D_UI_MODE +#endif + +#define DEFAULT_FB (0) +#define TVOUT_FB_G0 (10) +#define TVOUT_FB_G1 (11) + +#define MAX_BUFFERS_MIXER (1) +#define MAX_PLANES_MIXER (3) + +#define HDMI_NUM_MIXER_BUF (2) +#define GRALLOC_BUF_SIZE (32768) +#define SIZE_1K (1024) + +#define HDMI_FIMC_OUTPUT_BUF_NUM (4) +#define HDMI_G2D_OUTPUT_BUF_NUM (2) +#define HDMI_FIMC_BUFFER_BPP_SIZE (1.5) //NV12 Tiled is 1.5 bytes, RGB565 is 2, RGB888 is 4, Default is NV12 Tiled +#define HDMI_G2D_BUFFER_BPP_SIZE (4) //NV12 Tiled is 1.5 bytes, RGB565 is 2, RGB888 is 4 +#define HDMI_FB_BPP_SIZE (4) //ARGB888 is 4 +#define SUPPORT_1080P_FIMC_OUT +#define HDMI_MAX_WIDTH (1920) +#define HDMI_MAX_HEIGHT (1080) + +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +#if defined(STD_NTSC_M) + #define DEFAULT_OUPUT_MODE (COMPOSITE_OUTPUT_MODE) + #define DEFAULT_HDMI_RESOLUTION_VALUE (1080960) // 1080P_60 + #define DEFAULT_HDMI_PRESET_ID (V4L2_DV_1080P60) + #define DEFAULT_HDMI_STD_ID (V4L2_STD_1080P_60) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif (STD_1080P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_RGB) + #define DEFAULT_HDMI_RESOLUTION_VALUE (1080960) // 1080P_60 + #define DEFAULT_HDMI_PRESET_ID (V4L2_DV_1080P60) + #define DEFAULT_HDMI_STD_ID (V4L2_STD_1080P_60) + #define DEFALULT_DISPLAY_WIDTH (1920) + #define DEFALULT_DISPLAY_HEIGHT (1080) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif defined(STD_720P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (720960) // 720P_60 + #define DEFAULT_HDMI_PRESET_ID (V4L2_DV_720P60) + #define DEFAULT_HDMI_STD_ID (V4L2_STD_720P_60) + #define DEFALULT_DISPLAY_WIDTH (1280) + #define DEFALULT_DISPLAY_HEIGHT (720) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif defined(STD_480P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (4809601) // 480P_60_4_3 + #define DEFAULT_HDMI_PRESET_ID (V4L2_DV_480P60) + #define DEFAULT_HDMI_STD_ID (V4L2_STD_480P_60_16_9) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#else + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (4809602) // 480P_60_4_3 + #define DEFAULT_HDMI_PRESET_ID (V4L2_DV_480P60) + #define DEFAULT_HDMI_STD_ID (V4L2_STD_480P_60_4_3) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#endif + +enum hdp_cable_status { + HPD_CABLE_OUT = 0, // HPD_CABLE_OUT indicates HDMI cable out. + HPD_CABLE_IN // HPD_CABLE_IN indicates HDMI cable in. +}; + +enum state { + OFF = 0, + ON = 1, + NOT_SUPPORT = 2, +}; + +enum tv_mode { + HDMI_OUTPUT_MODE_YCBCR = 0, + HDMI_OUTPUT_MODE_RGB = 1, + HDMI_OUTPUT_MODE_DVI = 2, + COMPOSITE_OUTPUT_MODE = 3 +}; + +enum composite_std { + COMPOSITE_STD_NTSC_M = 0, + COMPOSITE_STD_PAL_BDGHI = 1, + COMPOSITE_STD_PAL_M = 2, + COMPOSITE_STD_PAL_N = 3, + COMPOSITE_STD_PAL_Nc = 4, + COMPOSITE_STD_PAL_60 = 5, + COMPOSITE_STD_NTSC_443 = 6 +}; + +enum hdmi_layer { + HDMI_LAYER_BASE = 0, + HDMI_LAYER_VIDEO, + HDMI_LAYER_GRAPHIC_0, + HDMI_LAYER_GRAPHIC_1, + HDMI_LAYER_MAX, +}; diff --git a/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp b/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp new file mode 100644 index 0000000..217ce51 --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp @@ -0,0 +1,2434 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOARD_USE_V4L2) +#include "sec_utils_v4l2.h" +#include "s5p_tvout_v4l2.h" +#include "videodev2.h" +#else +#include "sec_utils.h" +#include "s5p_tvout.h" +#endif +#include "SecFimc.h" +#if defined(BOARD_USES_FIMGAPI) +#include "sec_g2d_4x.h" +#include "FimgApi.h" +#endif + +#include "audio.h" +#include "video.h" +#include "../libhdmi/libsForhdmi/libedid/libedid.h" +#include "../libhdmi/libsForhdmi/libcec/libcec.h" + +#include "SecHdmiCommon.h" +#include "SecHdmiV4L2Utils.h" + +namespace android { + +unsigned int output_type = V4L2_OUTPUT_TYPE_DIGITAL; +#if defined(BOARD_USE_V4L2) +unsigned int g_preset_id = V4L2_DV_1080P30; +#endif +v4l2_std_id t_std_id = V4L2_STD_1080P_30; +int g_hpd_state = HPD_CABLE_OUT; +unsigned int g_hdcp_en = 0; + +int fp_tvout = -1; +int fp_tvout_v = -1; +int fp_tvout_g0 = -1; +int fp_tvout_g1 = -1; + +struct vid_overlay_param vo_param; + +#if defined(BOARD_USES_FIMGAPI) +unsigned int g2d_reserved_memory[HDMI_G2D_OUTPUT_BUF_NUM]; +unsigned int g2d_reserved_memory_size = 0; +unsigned int cur_g2d_address = 0; +unsigned int g2d_buf_index = 0; +#endif + +void display_menu(void) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + + LOGI("=============== HDMI Audio =============\n"); + + if (EDIDAudioModeSupport(&audio)) + LOGI("= 2CH_PCM 44100Hz audio supported =\n"); + + LOGI("========= HDMI Mode & Color Space =======\n"); + + video.mode = HDMI; + if (EDIDHDMIModeSupport(&video)) { + video.colorSpace = HDMI_CS_YCBCR444; + if (EDIDColorSpaceSupport(&video)) + LOGI("= 1. HDMI(YCbCr) =\n"); + + video.colorSpace = HDMI_CS_RGB; + if (EDIDColorSpaceSupport(&video)) + LOGI("= 2. HDMI(RGB) =\n"); + } else { + video.mode = DVI; + if (EDIDHDMIModeSupport(&video)) + LOGI("= 3. DVI =\n"); + } + + LOGI("=========== HDMI Rseolution ========\n"); + + /* 480P */ + video.resolution = v720x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 4. 480P_60_16_9 (0x04000000) =\n"); + + video.resolution = v640x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 5. 480P_60_4_3 (0x05000000) =\n"); + + /* 576P */ + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 6. 576P_50_16_9 (0x06000000) =\n"); + + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 7. 576P_50_4_3 (0x07000000) =\n"); + + /* 720P 60 */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 8. 720P_60 (0x08000000) =\n"); + + /* 720P_50 */ + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 9. 720P_50 (0x09000000) =\n"); + + /* 1080P_60 */ + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= a. 1080P_60 (0x0a000000) =\n"); + + /* 1080P_50 */ + video.resolution = v1920x1080p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= b. 1080P_50 (0x0b000000) =\n"); + + /* 1080I_60 */ + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= c. 1080I_60 (0x0c000000) =\n"); + + /* 1080I_50 */ + video.resolution = v1920x1080i_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= d. 1080I_50 (0x0d000000) =\n"); + + /* 1080P_30 */ + video.resolution = v1920x1080p_30Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= e. 1080P_30 (0x12000000) =\n"); + + LOGI("=========== HDMI 3D Format ========\n"); + + /* 720P_60_SBS_HALF */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= f. 720P_60_SBS_HALF (0x13000000) =\n"); + + /* 720P_59_SBS_HALF */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 10. 720P_59_SBS_HALF (0x14000000) =\n"); + + /* 720P_50_TB */ + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 11. 720P_50_TB (0x15000000) =\n"); + + /* 1080P_24_TB */ + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 12. 1080P_24_TB (0x16000000) =\n"); + + /* 1080P_23_TB */ + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 13. 1080P_24_TB (0x17000000) =\n"); + LOGI("=========================================\n"); +} + +int tvout_open(const char *fp_name) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int fp; + + fp = open(fp_name, O_RDWR); + if (fp < 0) + LOGE("drv (%s) open failed!!\n", fp_name); + + return fp; +} +#if defined(BOARD_USE_V4L2) +int tvout_std_v4l2_init(int fd, unsigned int preset_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: preset_id = 0x%x", __func__, preset_id); +#endif + + int ret; + struct v4l2_output output; + struct v4l2_dv_preset preset; + + unsigned int matched = 0, i = 0; + int output_index; + +/* + if (output_type >= V4L2_OUTPUT_TYPE_DIGITAL && + output_type <= V4L2_OUTPUT_TYPE_DVI) + if (ioctl(fd_tvout, VIDIOC_HDCP_ENABLE, g_hdcp_en) < 0) + LOGE("%s::VIDIOC_HDCP_ENABLE failed %d", __func__, errno); +*/ + + i = 0; + + do { + output.index = i; + ret = tvout_std_v4l2_enum_output(fd, &output); + LOGD("tvout_v4l2_enum_output():: output_type=%d output.index=%d output.name=%s", output.type, output.index, output.name); + if (output.type == output_type) { + matched = 1; + break; + } + i++; + } while (ret >=0); + + if (!matched) { + LOGE("%s::no matched output type [type=%d]", __func__, output_type); +// return -1; + } + + // set output +// tvout_std_v4l2_s_output(fp_tvout, output.index); +// output_index = 0; +// tvout_std_v4l2_g_output(fp_tvout, &output_index); + +// if (output.capabilities & V4L2_OUT_CAP_PRESETS) { + tvout_std_v4l2_enum_dv_presets(fd); + preset.preset = preset_id; + if (tvout_std_v4l2_s_dv_preset(fd, &preset) < 0 ) { + LOGE("%s::tvout_std_v4l2_s_dv_preset failed", __func__); + return -1; + } +// } + + return 0; +} + +int tvout_std_v4l2_querycap(int fd, char *node) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_capability v4l2cap; + + if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) { + LOGE("%s::VIDIOC_QUERYCAP failed", __func__); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("%s::%s is not support streaming", __func__, node); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) { + LOGE("%s::%s is not support video output mplane", __func__, node); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_enum_dv_presets(int fd) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_dv_enum_preset enum_preset; + int ret = -1; + + for (int index = 0; ; index++) { + enum_preset.index = index; + ret = ioctl(fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset); + + if (ret < 0) { + if (errno == EINVAL) + break; + LOGE("%s::VIDIOC_ENUM_DV_PRESETS", __func__); + return -1; + } +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::index=%d, preset=0x%08x, name=%s, w=%d, h=%d", + __func__, enum_preset.index, enum_preset.preset, enum_preset.name, enum_preset.width, enum_preset.height); +#endif + } + + return 0; +} + +int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + if (ioctl(fd, VIDIOC_S_DV_PRESET, preset) < 0) { + LOGE("%s::VIDIOC_S_DV_PRESET failed", __func__); + return -1; + } + + return 0; +} + +/* + ioctl VIDIOC_ENUMOUTPUT + To query the attributes of a video outputs applications initialize the index field of struct v4l2_output + and call the VIDIOC_ENUMOUTPUT ioctl with a pointer to this structure. Drivers fill the rest of the + structure or return an EINVAL error code when the index is out of bounds + */ +int tvout_std_v4l2_enum_output(int fd, struct v4l2_output *output) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fd, VIDIOC_ENUMOUTPUT, output); + + if (ret >=0) + LOGV("tvout_v4l2_enum_output" "enum. output [index = %d] :: type : 0x%08x , name = %s\n", + output->index,output->type,output->name); + + return ret; +} + +/* + ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT + To query the current video output applications call the VIDIOC_G_OUTPUT ioctl with a pointer to an + integer where the driver stores the number of the output, as in the struct v4l2_output index field. + This ioctl will fail only when there are no video outputs, returning the EINVAL error code + */ +int tvout_std_v4l2_s_output(int fd, int index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: index = 0x%x", __func__, index); +#endif + + int ret; + + ret = ioctl(fd, VIDIOC_S_OUTPUT, &index); + if (ret < 0) { + LOGE("tvout_v4l2_s_output" "VIDIOC_S_OUTPUT failed %d\n", errno); + return ret; + } + + return ret; +} + +int tvout_std_v4l2_g_output(int fd, int *index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fd, VIDIOC_G_OUTPUT, index); + if (ret < 0) { + LOGE("tvout_v4l2_g_output" "VIDIOC_G_OUTPUT failed %d\n", errno); + return ret; + } else { + LOGV("tvout_v4l2_g_output" "Current output index %d\n", *index); + } + + return ret; +} + +int tvout_std_v4l2_s_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, int w, int h, int colorformat, int num_planes) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_format fmt; + + fmt.type = type; +// if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { +// LOGE("%s::VIDIOC_G_FMT failed", __func__); +// return -1; +// } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + fmt.fmt.pix.width = w; + fmt.fmt.pix.height = h; + fmt.fmt.pix.pixelformat = colorformat; + fmt.fmt.pix.field = field; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt.fmt.pix_mp.width = w; + fmt.fmt.pix_mp.height = h; + fmt.fmt.pix_mp.pixelformat = colorformat; + fmt.fmt.pix_mp.field = field; + fmt.fmt.pix_mp.num_planes = num_planes; + break; + default: + LOGE("%s::invalid buffer type", __func__); + return -1; + break; + } + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field, int x, int y, int w, int h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_crop crop; + + crop.type = type; + crop.c.left = x; + crop.c.top = y; + crop.c.width = w; + crop.c.height = h; + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed", + __func__, x, y, w, h); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_s_ctrl(int fd, int id, int value) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_control vc; + + vc.id = id; + vc.value = value; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_requestbuffers reqbuf; + + reqbuf.type = type; + reqbuf.memory = memory; + reqbuf.count = num_bufs; + + if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { + LOGE("%s::VIDIOC_REQBUFS failed", __func__); + return -1; + } + + if (reqbuf.count < num_bufs) { + LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))", + __func__, reqbuf.count, num_bufs); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_querybuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, unsigned int num_planes, SecBuffer *secBuf) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_MIXER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + if (MAX_BUFFERS_MIXER <= buf_index || MAX_PLANES_MIXER <= num_planes) { + LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_planes); + return -1; + } + + buf.type = type; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_index; + buf.length = num_planes; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length); + return -1; + } + + for (unsigned int i = 0; i < num_planes; i++) { + if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) { + LOGE("%s::mmap failed", __func__); + LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset); + LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length); + LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + return -1; + } + secBuf->size.extS[i] = buf.m.planes[i].length; + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::vaddr[bufidx=%d][planeidx=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + LOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length); +#endif + } + + return 0; +} + +int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_MIXER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + buf.type = type; + buf.memory = memory; + buf.length = num_planes; + buf.index = buf_index; + buf.m.planes = planes; + + for (unsigned int i = 0; i < buf.length; i++) { + buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i]; + buf.m.planes[i].length = secBuf->size.extS[i]; + } + + if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QBUF failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_MIXER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + buf.type = type; + buf.memory = memory; + buf.length = num_planes; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { + LOGE("%s::VIDIOC_DQBUF failed", __func__); + return -1; + } + *buf_index = buf.index; + + return 0; +} + +int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { + LOGE("%s::VIDIOC_STREAMON failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { + LOGE("%s::VIDIOC_STREAMOFF failed", __func__); + return -1; + } + + return 0; +} +#else +int tvout_init(v4l2_std_id std_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: std_id = 0x%x", __func__, std_id); +#endif + + int ret; + struct v4l2_output output; + struct v4l2_standard std; + v4l2_std_id std_g_id; + struct tvout_param tv_g_param; + + unsigned int matched = 0, i = 0; + int output_index; + + // It was initialized already + if (fp_tvout <= 0) { + fp_tvout = tvout_open(TVOUT_DEV); + if (fp_tvout < 0) { + LOGE("tvout video drv open failed\n"); + return -1; + } + } + + if (output_type >= V4L2_OUTPUT_TYPE_DIGITAL && + output_type <= V4L2_OUTPUT_TYPE_DVI) + if (ioctl(fp_tvout, VIDIOC_HDCP_ENABLE, g_hdcp_en) < 0) + LOGE("tvout_init" "VIDIOC_HDCP_ENABLE failed %d\n", errno); + + /* ============== query capability============== */ + tvout_v4l2_querycap(fp_tvout); + + tvout_v4l2_enum_std(fp_tvout, &std, std_id); + + // set std + tvout_v4l2_s_std(fp_tvout, std_id); + tvout_v4l2_g_std(fp_tvout, &std_g_id); + + i = 0; + + do { + output.index = i; + ret = tvout_v4l2_enum_output(fp_tvout, &output); + if (output.type == output_type) { + matched = 1; + break; + } + i++; + } while (ret >=0); + + if (!matched) { + LOGE("no matched output type [type : 0x%08x]\n", output_type); + return -1; + } + + // set output + tvout_v4l2_s_output(fp_tvout, output.index); + output_index = 0; + tvout_v4l2_g_output(fp_tvout, &output_index); + + //set fmt param + vo_param.src.base_y = (void *)0x0; + vo_param.src.base_c = (void *)0x0; + vo_param.src.pix_fmt.width = 0; + vo_param.src.pix_fmt.height = 0; + vo_param.src.pix_fmt.field = V4L2_FIELD_NONE; + vo_param.src.pix_fmt.pixelformat = V4L2_PIX_FMT_NV12T; + + vo_param.src_crop.left = 0; + vo_param.src_crop.top = 0; + vo_param.src_crop.width = 0; + vo_param.src_crop.height = 0; + + return fp_tvout; +} + +int tvout_deinit() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + if (0 < fp_tvout) { + close(fp_tvout); + fp_tvout = -1; + } + return 0; +} + +int tvout_v4l2_querycap(int fp) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: fp = 0x%x", __func__, fp); +#endif + + struct v4l2_capability cap; + int ret; + + ret = ioctl(fp, VIDIOC_QUERYCAP, &cap); + + if (ret < 0) { + LOGE("tvout_v4l2_querycap" "VIDIOC_QUERYCAP failed %d\n", errno); + return ret; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("tvout_v4l2_querycap" "DRIVER : %s, CARD : %s, CAP.: 0x%08x\n", + cap.driver, cap.card, cap.capabilities); +#endif + + return ret; +} + +/* + ioctl VIDIOC_G_STD, VIDIOC_S_STD + To query and select the current video standard applications use the VIDIOC_G_STD and + VIDIOC_S_STD ioctls which take a pointer to a v4l2_std_id type as argument. VIDIOC_G_STD can + return a single flag or a set of flags as in struct v4l2_standard field id + */ + +int tvout_v4l2_g_std(int fp, v4l2_std_id *std_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_G_STD, std_id); + if (ret < 0) { + LOGE("tvout_v4l2_g_std" "VIDIOC_G_STD failed %d\n", errno); + return ret; + } + + return ret; +} + +int tvout_v4l2_s_std(int fp, v4l2_std_id std_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: std_id = 0x%x", __func__, std_id); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_S_STD, &std_id); + if (ret < 0) { + LOGE("tvout_v4l2_s_std" "VIDIOC_S_STD failed %d\n", errno); + return ret; + } + + return ret; +} + +/* + ioctl VIDIOC_ENUMSTD + To query the attributes of a video standard, especially a custom (driver defined) one, applications + initialize the index field of struct v4l2_standard and call the VIDIOC_ENUMSTD ioctl with a pointer + to this structure. Drivers fill the rest of the structure or return an EINVAL error code when the index + is out of bounds. + */ +int tvout_v4l2_enum_std(int fp, struct v4l2_standard *std, v4l2_std_id std_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + std->index = 0; + while (0 == ioctl (fp, VIDIOC_ENUMSTD, std)) { + if (std->id & std_id) + LOGV("tvout_v4l2_enum_std" "Current video standard: %s\n", std->name); + + std->index++; + } + + return 0; +} + +/* + ioctl VIDIOC_ENUMOUTPUT + To query the attributes of a video outputs applications initialize the index field of struct v4l2_output + and call the VIDIOC_ENUMOUTPUT ioctl with a pointer to this structure. Drivers fill the rest of the + structure or return an EINVAL error code when the index is out of bounds + */ +int tvout_v4l2_enum_output(int fp, struct v4l2_output *output) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_ENUMOUTPUT, output); + + if (ret >=0) + LOGV("tvout_v4l2_enum_output" "enum. output [index = %d] :: type : 0x%08x , name = %s\n", + output->index,output->type,output->name); + + return ret; +} + +/* + ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT + To query the current video output applications call the VIDIOC_G_OUTPUT ioctl with a pointer to an + integer where the driver stores the number of the output, as in the struct v4l2_output index field. + This ioctl will fail only when there are no video outputs, returning the EINVAL error code + */ +int tvout_v4l2_s_output(int fp, int index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s:: index = 0x%x", __func__, index); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_S_OUTPUT, &index); + if (ret < 0) { + LOGE("tvout_v4l2_s_output" "VIDIOC_S_OUTPUT failed %d\n", errno); + return ret; + } + + return ret; +} + +int tvout_v4l2_g_output(int fp, int *index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_G_OUTPUT, index); + if (ret < 0) { + LOGE("tvout_v4l2_g_output" "VIDIOC_G_OUTPUT failed %d\n", errno); + return ret; + } else { + LOGV("tvout_v4l2_g_output" "Current output index %d\n", *index); + } + + return ret; +} + +/* + ioctl VIDIOC_ENUM_FMT + To enumerate image formats applications initialize the type and index field of struct v4l2_fmtdesc + and call the VIDIOC_ENUM_FMT ioctl with a pointer to this structure. Drivers fill the rest of the + structure or return an EINVAL error code. All formats are enumerable by beginning at index zero + and incrementing by one until EINVAL is returned. + */ +int tvout_v4l2_enum_fmt(int fp, struct v4l2_fmtdesc *desc) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + desc->index = 0; + while (0 == ioctl(fp, VIDIOC_ENUM_FMT, desc)) { + LOGV("tvout_v4l2_enum_fmt" "enum. fmt [id : 0x%08x] :: type = 0x%08x, name = %s, pxlfmt = 0x%08x\n", + desc->index, + desc->type, + desc->description, + desc->pixelformat); + desc->index++; + } + + return 0; +} + +int tvout_v4l2_g_fmt(int fp, int buf_type, void* ptr) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + struct v4l2_format format; + struct v4l2_pix_format_s5p_tvout *fmt_param = (struct v4l2_pix_format_s5p_tvout*)ptr; + + format.type = (enum v4l2_buf_type)buf_type; + + ret = ioctl(fp, VIDIOC_G_FMT, &format); + if (ret < 0) { + LOGE("tvout_v4l2_g_fmt" "type : %d, VIDIOC_G_FMT failed %d\n", buf_type, errno); + return ret; + } else { + memcpy(fmt_param, format.fmt.raw_data, sizeof(struct v4l2_pix_format_s5p_tvout)); + LOGV("tvout_v4l2_g_fmt" "get. fmt [base_c : 0x%08x], [base_y : 0x%08x] type = 0x%08x, width = %d, height = %d\n", + fmt_param->base_c, + fmt_param->base_y, + fmt_param->pix_fmt.pixelformat, + fmt_param->pix_fmt.width, + fmt_param->pix_fmt.height); + } + + return 0; +} + +int tvout_v4l2_s_fmt(int fp, int buf_type, void *ptr) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_format format; + int ret; + + format.type = (enum v4l2_buf_type)buf_type; + switch (buf_type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + format.fmt.win = *((struct v4l2_window *) ptr); + break; + + case V4L2_BUF_TYPE_PRIVATE: { + struct v4l2_vid_overlay_src *fmt_param = + (struct v4l2_vid_overlay_src *) ptr; + + memcpy(format.fmt.raw_data, fmt_param, + sizeof(struct v4l2_vid_overlay_src)); + break; + } + case V4L2_BUF_TYPE_VIDEO_OUTPUT: { + struct v4l2_pix_format_s5p_tvout *fmt_param = + (struct v4l2_pix_format_s5p_tvout *)ptr; + memcpy(format.fmt.raw_data, fmt_param, + sizeof(struct v4l2_pix_format_s5p_tvout)); + break; + } + default: + break; + } + + ret = ioctl(fp, VIDIOC_S_FMT, &format); + if (ret < 0) { + LOGE("tvout_v4l2_s_fmt [tvout_v4l2_s_fmt] : type : %d, VIDIOC_S_FMT failed %d\n", + buf_type, errno); + return ret; + } + return 0; + +} + +int tvout_v4l2_g_fbuf(int fp, struct v4l2_framebuffer *frame) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_G_FBUF, frame); + if (ret < 0) { + LOGE("tvout_v4l2_g_fbuf" "VIDIOC_STREAMON failed %d\n", errno); + return ret; + } + + LOGV("tvout_v4l2_g_fbuf" "get. fbuf: base = 0x%08X, pixel format = %d\n", + frame->base, + frame->fmt.pixelformat); + return 0; +} + +int tvout_v4l2_s_fbuf(int fp, struct v4l2_framebuffer *frame) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, VIDIOC_S_FBUF, frame); + if (ret < 0) { + LOGE("tvout_v4l2_s_fbuf" "VIDIOC_STREAMON failed %d\n", errno); + return ret; + } + return 0; +} + +int tvout_v4l2_s_baseaddr(int fp, void *base_addr) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + + ret = ioctl(fp, S5PTVFB_WIN_SET_ADDR, base_addr); + if (ret < 0) { + LOGE("tvout_v4l2_baseaddr" "VIDIOC_S_BASEADDR failed %d\n", errno); + return ret; + } + return 0; +} + +int tvout_v4l2_g_crop(int fp, unsigned int type, struct v4l2_rect *rect) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret; + struct v4l2_crop crop; + crop.type = (enum v4l2_buf_type)type; + ret = ioctl(fp, VIDIOC_G_CROP, &crop); + if (ret < 0) { + LOGE("tvout_v4l2_g_crop" "VIDIOC_G_CROP failed %d\n", errno); + return ret; + } + + rect->left = crop.c.left; + rect->top = crop.c.top; + rect->width = crop.c.width; + rect->height = crop.c.height; + + LOGV("tvout_v4l2_g_crop" "get. crop : left = %d, top = %d, width = %d, height = %d\n", + rect->left, + rect->top, + rect->width, + rect->height); + return 0; +} + +int tvout_v4l2_s_crop(int fp, unsigned int type, struct v4l2_rect *rect) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_crop crop; + int ret; + + crop.type = (enum v4l2_buf_type)type; + + crop.c.left = rect->left; + crop.c.top = rect->top; + crop.c.width = rect->width; + crop.c.height = rect->height; + + ret = ioctl(fp, VIDIOC_S_CROP, &crop); + if (ret < 0) { + LOGE("tvout_v4l2_s_crop" "VIDIOC_S_CROP failed %d\n", errno); + return ret; + } + + return 0; +} + +int tvout_v4l2_start_overlay(int fp) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret, start = 1; + + ret = ioctl(fp, VIDIOC_OVERLAY, &start); + if (ret < 0) { + LOGE("tvout_v4l2_start_overlay" "VIDIOC_OVERLAY failed\n"); + return ret; + } + + return ret; +} + +int tvout_v4l2_stop_overlay(int fp) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int ret, stop =0; + + ret = ioctl(fp, VIDIOC_OVERLAY, &stop); + if (ret < 0) { + LOGE("tvout_v4l2_stop_overlay" "VIDIOC_OVERLAY failed\n"); + return ret; + } + + return ret; +} +#endif + +int hdmi_init_layer(int layer) +{ + int fd = -1; +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s (layer = %d) called", __func__, layer); +#endif + + switch (layer) { + case HDMI_LAYER_VIDEO : + if (fp_tvout_v <= 0) { + fp_tvout_v = tvout_open(TVOUT_DEV_V); + if (fp_tvout_v < 0) { + LOGE("tvout video layer open failed\n"); + return -1; + } + fd = fp_tvout_v; + } + break; + case HDMI_LAYER_GRAPHIC_0 : + if (fp_tvout_g0 <= 0) { +#if defined(BOARD_USE_V4L2) + fp_tvout_g0 = tvout_open(TVOUT_DEV_G0); +#else + fp_tvout_g0 = fb_open(TVOUT_FB_G0); +#endif + if (fp_tvout_g0 < 0) { + LOGE("tvout graphic layer 0 open failed\n"); + return -1; + } + fd = fp_tvout_g0; + } + break; + case HDMI_LAYER_GRAPHIC_1 : + if (fp_tvout_g1 <= 0) { +#if defined(BOARD_USE_V4L2) + fp_tvout_g1 = tvout_open(TVOUT_DEV_G1); +#else + fp_tvout_g1 = fb_open(TVOUT_FB_G1); +#endif + if (fp_tvout_g1 < 0) { + LOGE("tvout graphic layer 1 open failed\n"); + return -1; + } + fd = fp_tvout_g1; + } + break; + default : + LOGE("%s::unmathced layer(%d) fail", __func__, layer); + fd = -1; + break; + } + + return fd; +} + +int hdmi_deinit_layer(int layer) +{ + int ret = 0; +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s(layer = %d) called", __func__, layer); +#endif + switch (layer) { + case HDMI_LAYER_VIDEO : + if (0 < fp_tvout_v) { + close(fp_tvout_v); + fp_tvout_v = -1; + } + break; + case HDMI_LAYER_GRAPHIC_0 : + if (0 < fp_tvout_g0) { + close(fp_tvout_g0); + fp_tvout_g0 = -1; + } + break; + case HDMI_LAYER_GRAPHIC_1 : + if (0 < fp_tvout_g1) { + close(fp_tvout_g1); + fp_tvout_g1 = -1; + } + break; + default : + LOGE("%s::unmathced layer(%d) fail", __func__, layer); + ret = -1; + break; + } + + return ret; +} + +#define ROUND_UP(value, boundary) ((((uint32_t)(value)) + \ + (((uint32_t) boundary)-1)) & \ + (~(((uint32_t) boundary)-1))) + +void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect) +{ + if (dst_w * src_h <= dst_h * src_w) { + dst_rect->left = 0; + dst_rect->top = (dst_h - ((dst_w * src_h) / src_w)) >> 1; + dst_rect->width = dst_w; + dst_rect->height = ((dst_w * src_h) / src_w); + } else { + dst_rect->left = (dst_w - ((dst_h * src_w) / src_h)) >> 1; + dst_rect->top = 0; + dst_rect->width = ((dst_h * src_w) / src_h); + dst_rect->height = dst_h; + } +} + +#if defined(BOARD_USE_V4L2) +int hdmi_get_src_plane(int srcColorFormat, unsigned int *num_of_plane) +{ + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat); + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGB565X: + *num_of_plane = 1; + break; + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_NV21M: + *num_of_plane = 2; + break; + default: + LOGE("%s::invalid color type", __func__); + return -1; + } + + return 0; +} +#endif + +#if defined(BOARD_USE_V4L2) +int hdmi_set_v_param(int fd, int layer, + int srcColorFormat, + int src_w, int src_h, + SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat); + int round_up_src_w; + int round_up_src_h; + unsigned int num_of_plane; + struct v4l2_rect rect; + + /* src_w, src_h round up to DWORD because of VP restriction */ +#if defined(SAMSUNG_EXYNOS4x12) + round_up_src_w = ROUND_UP(src_w, 16); +#else defined(SAMSUNG_EXYNOS4210) + round_up_src_w = ROUND_UP(src_w, 8); +#endif + round_up_src_h = ROUND_UP(src_h, 8); + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + dstBuffer->size.s = (round_up_src_w * round_up_src_h * 3) >> 1; + num_of_plane = 1; + break; + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_NV21M: + dstBuffer->size.extS[0] = (round_up_src_w * round_up_src_h * 3) >> 1; + dstBuffer->size.extS[1] = (round_up_src_w * round_up_src_h * 3) >> 2; + num_of_plane = 2; + break; + default: + LOGE("%s::invalid color type", __func__); + return false; + break; + } + + hdmi_cal_rect(src_w, src_h, dst_w, dst_h, &rect); + rect.left = ALIGN(rect.left, 16); + + /* set format for VP input */ + if (tvout_std_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, round_up_src_w, round_up_src_h, v4l2ColorFormat, num_of_plane) < 0) { + LOGE("%s::tvout_std_v4l2_s_fmt()[video layer] failed", __func__); + return -1; + } + + /* set crop for VP input */ + if (tvout_std_v4l2_s_crop(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY, V4L2_FIELD_ANY, 0, 0, src_w, src_h) < 0) { + LOGE("%s::tvout_std_v4l2_s_crop()[video layer] failed", __func__); + return -1; + } + + /* set crop for VP output */ + if (tvout_std_v4l2_s_crop(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.left, rect.top, rect.width, rect.height) < 0) { + LOGE("%s::tvout_std_v4l2_s_crop()[video layer] failed", __func__); + return -1; + } + + /* request buffer for VP input */ + if (tvout_std_v4l2_reqbuf(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, HDMI_NUM_MIXER_BUF) < 0) { + LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[video layer] failed", __func__, HDMI_NUM_MIXER_BUF); + return -1; + } + + return 0; +} + +int hdmi_set_g_param(int fd, int layer, + int srcColorFormat, + int src_w, int src_h, + SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_rect rect; + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat); + + rect.left = dst_x; + rect.top = dst_y; + +#if defined(BOARD_USES_FIMGAPI) + rect.width = dst_w; + rect.height = dst_h; +#else + rect.width = src_w; + rect.height = src_h; +#endif + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + dstBuffer->size.s = rect.width * rect.height << 2; + break; + case V4L2_PIX_FMT_RGB565X: + dstBuffer->size.s = rect.width * rect.height << 1; + break; + default: + LOGE("%s::invalid color type", __func__); + return false; + break; + } + + /* set format for mixer graphic layer input device*/ + if (tvout_std_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.width, rect.height, v4l2ColorFormat, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_fmt() [layer=%d] failed", __func__, layer); + return -1; + } + + /* set crop for mixer graphic layer input device*/ + if (tvout_std_v4l2_s_crop(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.left, rect.top, rect.width, rect.height) < 0) { + LOGE("%s::tvout_std_v4l2_s_crop() [layer=%d] failed", __func__, layer); + return -1; + } + + /* request buffer for mixer graphic layer input device */ + if (tvout_std_v4l2_reqbuf(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, HDMI_NUM_MIXER_BUF) < 0) { + LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d) [layer=%d] failed", __func__, HDMI_NUM_MIXER_BUF, layer); + return -1; + } + + /* enable alpha blending for mixer graphic layer */ + if (tvout_std_v4l2_s_ctrl(fd, V4L2_CID_TV_LAYER_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl() [layer=%d] failed", __func__, layer); + return -1; + } + + /* enable per-pixel blending for mixer graphic layer */ + if (tvout_std_v4l2_s_ctrl(fd, V4L2_CID_TV_PIXEL_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] failed", __func__, layer); + return false; + } + + /* set global alpha value for mixer graphic layer */ + if (tvout_std_v4l2_s_ctrl(fd, V4L2_CID_TV_LAYER_BLEND_ALPHA, 255) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl() [layer=%d] failed", __func__, layer); + return -1; + } + + return 0; +} + +int hdmi_set_g_scaling(int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_address, SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal, unsigned int hwc_layer) +{ +#if defined(BOARD_USES_FIMGAPI) + int dst_color_format; + int dst_bpp; + unsigned char *dst_addr; + fimg2d_blit BlitParam; + rotation g2d_rotation; + + fimg2d_addr srcAddr; + fimg2d_image srcImage; + fimg2d_rect srcRect; + + fimg2d_addr dstAddr; + fimg2d_image dstImage; + fimg2d_rect dstRect; + + fimg2d_clip dstClip; + fimg2d_scale Scaling; + + switch (g_preset_id) { + case V4L2_DV_1080P60: + case V4L2_DV_1080P30: + case V4L2_DV_1080I60: + case V4L2_DV_720P60_SB_HALF: + case V4L2_DV_720P59_94_SB_HALF: + case V4L2_DV_1080P24_TB: + case V4L2_DV_1080P23_98_TB: + dst_color_format = CF_ARGB_8888; + dst_bpp = 4; + break; + case V4L2_DV_480P60: + case V4L2_DV_576P50: + case V4L2_DV_720P60: + case V4L2_DV_720P50_TB: + default: + dst_color_format = CF_ARGB_4444; + dst_bpp = 2; + break; + } + + static unsigned int prev_src_addr = 0; + + if ((cur_g2d_address == 0) || (src_address != prev_src_addr)) { + dst_addr = (unsigned char *)g2d_reserved_memory[g2d_buf_index]; + + g2d_buf_index++; + if (g2d_buf_index >= HDMI_G2D_OUTPUT_BUF_NUM) + g2d_buf_index = 0; + + cur_g2d_address = (unsigned int)dst_addr; + prev_src_addr = src_address; + + srcAddr = {(addr_space)ADDR_USER, (unsigned long)src_address, src_w * src_h * 4, 1, 0}; + srcImage = {srcAddr, srcAddr, src_w, src_h, src_w*4, AX_RGB, CF_ARGB_8888}; + srcRect = {0, 0, src_w, src_h}; + + dstAddr = {(addr_space)ADDR_USER, (unsigned long)dst_addr, dst_w * dst_h * dst_bpp, 1, 0}; + dstImage = {dstAddr, dstAddr, dst_w, dst_h, dst_w*dst_bpp, AX_RGB, (color_format)dst_color_format}; + dstRect = {0, 0, dst_w, dst_h}; + dstClip = {0, 0, 0, dst_w, dst_h}; + + if (rotVal == 0 || rotVal == 180) + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_w, dst_h}; + else + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_h, dst_w}; + + switch (rotVal) { + case 0: + g2d_rotation = ORIGIN; + break; + case 90: + g2d_rotation = ROT_90; + break; + case 180: + g2d_rotation = ROT_180; + break; + case 270: + g2d_rotation = ROT_270; + break; + default: + LOGE("%s::invalid rotVal(%d) fail", __func__, rotVal); + return -1; + break; + } + + BlitParam = {BLIT_OP_SRC, NON_PREMULTIPLIED, 0xff, 0, g2d_rotation, &Scaling, 0, 0, &dstClip, 0, &srcImage, &dstImage, NULL, &srcRect, &dstRect, NULL, 0}; + + if (stretchFimgApi(&BlitParam) < 0) { + LOGE("%s::stretchFimgApi() fail", __func__); + return -1; + } + +#ifdef DEBUG_MSG_ENABLE + LOGD("hdmi_set_g_scaling:: \n \\ + layer=%d,\n \\ + srcColorFormat=%d,\n \\ + src_w=%d, src_h=%d,\n\\ + src_address=0x%x, dst_addr=0x%x,\n\\ + dst_x=%d, dst_y=%d, dst_w=%d, dst_h=%d ", + layer, + srcColorFormat, + src_w, src_h, + src_address, dst_addr, + dst_x, dst_y, dst_w, dst_h); +#endif + dstBuffer->virt.p = (char *)dst_addr; + } +#else + dstBuffer->virt.p = (char *)src_address; +#endif + + return 0; +} +#else +int hdmi_set_v_param(int layer, + int src_w, int src_h, int colorFormat, + unsigned int src_y_address, unsigned int src_c_address, + int dst_w, int dst_h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int round_up_src_w; + int round_up_src_h; + if (fp_tvout_v <= 0) { + LOGE("fp_tvout is < 0 fail\n"); + return -1; + } + + /* src_w, src_h round up to DWORD because of VP restriction */ +#if defined(SAMSUNG_EXYNOS4x12) + round_up_src_w = ROUND_UP(src_w, 16); +#else defined(SAMSUNG_EXYNOS4210) + round_up_src_w = ROUND_UP(src_w, 8); +#endif + round_up_src_h = ROUND_UP(src_h, 8); + + vo_param.src.base_y = (void *)src_y_address; + vo_param.src.base_c = (void *)src_c_address; + vo_param.src.pix_fmt.width = round_up_src_w; + vo_param.src.pix_fmt.height = round_up_src_h; + vo_param.src.pix_fmt.field = V4L2_FIELD_NONE; + vo_param.src.pix_fmt.pixelformat = colorFormat; + + tvout_v4l2_s_fmt(fp_tvout_v, V4L2_BUF_TYPE_PRIVATE, &vo_param.src); + + vo_param.src_crop.width = src_w; + vo_param.src_crop.height = src_h; + + tvout_v4l2_s_crop(fp_tvout_v, V4L2_BUF_TYPE_PRIVATE, &vo_param.src_crop); + + if (dst_w * src_h <= dst_h * src_w) { + vo_param.dst_win.w.left = 0; + vo_param.dst_win.w.top = (dst_h - ((dst_w * src_h) / src_w)) >> 1; + vo_param.dst_win.w.width = dst_w; + vo_param.dst_win.w.height = ((dst_w * src_h) / src_w); + } else { + vo_param.dst_win.w.left = (dst_w - ((dst_h * src_w) / src_h)) >> 1; + vo_param.dst_win.w.top = 0; + vo_param.dst_win.w.width = ((dst_h * src_w) / src_h); + vo_param.dst_win.w.height = dst_h; + } + + vo_param.dst.fmt.priv = 10; + vo_param.dst_win.global_alpha = 255; + tvout_v4l2_s_fbuf(fp_tvout_v, &vo_param.dst); + tvout_v4l2_s_fmt(fp_tvout_v, V4L2_BUF_TYPE_VIDEO_OVERLAY, &vo_param.dst_win); + + return 0; +} + +int hdmi_gl_set_param(int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_y_address, unsigned int src_c_address, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal) +{ +#if defined(BOARD_USES_FIMGAPI) + int dst_color_format; + int dst_bpp; + unsigned char *dst_addr; + fimg2d_blit BlitParam; + rotation g2d_rotation; + + fimg2d_addr srcAddr; + fimg2d_image srcImage; + fimg2d_rect srcRect; + + fimg2d_addr dstAddr; + fimg2d_image dstImage; + fimg2d_rect dstRect; + + fimg2d_clip dstClip; + fimg2d_scale Scaling; + + struct fb_var_screeninfo var; + struct s5ptvfb_user_window window; + + int fp_tvout_g; + + if(layer == HDMI_LAYER_GRAPHIC_0) + fp_tvout_g = fp_tvout_g0; + else + fp_tvout_g = fp_tvout_g1; + + switch (t_std_id) { + case V4L2_STD_1080P_60: + case V4L2_STD_1080P_30: + case V4L2_STD_1080I_60: + case V4L2_STD_TVOUT_720P_60_SBS_HALF: + case V4L2_STD_TVOUT_720P_59_SBS_HALF: + case V4L2_STD_TVOUT_1080P_24_TB: + case V4L2_STD_TVOUT_1080P_23_TB: + dst_color_format = CF_ARGB_8888; + dst_bpp = 4; + var.bits_per_pixel = 32; + var.transp.length = 8; + break; + case V4L2_STD_480P_60_16_9: + case V4L2_STD_576P_50_16_9: + case V4L2_STD_720P_60: + case V4L2_STD_TVOUT_720P_50_TB: + default: + dst_color_format = CF_ARGB_4444; + dst_bpp = 2; + var.bits_per_pixel = 16; + var.transp.length = 4; + break; + } + + static unsigned int prev_src_addr = 0; + + if ((cur_g2d_address == 0) || (src_y_address != prev_src_addr)) { + dst_addr = (unsigned char *)g2d_reserved_memory[g2d_buf_index]; + + g2d_buf_index++; + if (g2d_buf_index >= HDMI_G2D_OUTPUT_BUF_NUM) + g2d_buf_index = 0; + + cur_g2d_address = (unsigned int)dst_addr; + prev_src_addr = src_y_address; + + srcAddr = {(addr_space)ADDR_PHYS, (unsigned long)src_y_address, src_w*src_h*4, 1, 0}; + srcImage = {srcAddr, srcAddr, src_w, src_h, src_w*4, AX_RGB, CF_ARGB_8888}; + srcRect = {0, 0, src_w, src_h}; + + dstAddr = {(addr_space)ADDR_PHYS, (unsigned long)dst_addr, dst_w*dst_h*dst_bpp, 1, 0}; + dstImage = {dstAddr, dstAddr, dst_w, dst_h, dst_w*dst_bpp, AX_RGB, (color_format)dst_color_format}; + dstRect = {0, 0, dst_w, dst_h}; + dstClip = {0, 0, 0, dst_w, dst_h}; + + if (rotVal == 0 || rotVal == 180) + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_w, dst_h}; + else + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_h, dst_w}; + + switch (rotVal) { + case 0: + g2d_rotation = ORIGIN; + break; + case 90: + g2d_rotation = ROT_90; + break; + case 180: + g2d_rotation = ROT_180; + break; + case 270: + g2d_rotation = ROT_270; + break; + default: + LOGE("%s::invalid rotVal(%d) fail", __func__, rotVal); + return -1; + break; + } + + BlitParam = {BLIT_OP_SRC, NON_PREMULTIPLIED, 0xff, 0, g2d_rotation, &Scaling, 0, 0, &dstClip, 0, &srcImage, &dstImage, NULL, &srcRect, &dstRect, NULL, 0}; + + if (stretchFimgApi(&BlitParam) < 0) { + LOGE("%s::stretchFimgApi() fail", __func__); + return -1; + } + + var.xres = dst_w; + var.yres = dst_h; + + var.xres_virtual = var.xres; + var.yres_virtual = var.yres; + var.xoffset = 0; + var.yoffset = 0; + var.width = 0; + var.height = 0; + var.activate = FB_ACTIVATE_FORCE; + + window.x = dst_x; + window.y = dst_y; + + tvout_v4l2_s_baseaddr(fp_tvout_g, (void *)dst_addr); + put_vscreeninfo(fp_tvout_g, &var); + + if (ioctl(fp_tvout_g, S5PTVFB_WIN_POSITION, &window) < 0) { + LOGE("%s::S5PTVFB_WIN_POSITION ioctl failed.", __func__); + return -1; + } + } + + return 0; +#else + struct fb_var_screeninfo var; + struct s5ptvfb_user_window window; + + struct overlay_param ov_param; + + // set base address for grp layer0 of mixer + int fp_tvout_g; + +#ifdef DEBUG_MSG_ENABLE + LOGD("hdmi_gl_set_param:: \n \\ + layer=%d,\n \\ + srcColorFormat=%d,\n \\ + src_w=%d, src_h=%d,\n\\ + src_y_address=0x%x, src_c_address=0x%x,\n\\ + dst_x=%d, dst_y=%d, dst_w=%d, dst_h=%d ", + layer, + srcColorFormat, + src_w, src_h, + src_y_address, src_c_address, + dst_x, dst_y, dst_w, dst_h); +#endif + + if (layer == HDMI_LAYER_GRAPHIC_0) + fp_tvout_g = fp_tvout_g0; + else + fp_tvout_g = fp_tvout_g1; + + var.xres = src_w; + var.yres = src_h; + var.xres_virtual = var.xres; + var.yres_virtual = var.yres; + var.xoffset = 0; + var.yoffset = 0; + var.width = src_w; + var.height = src_h; + var.activate = FB_ACTIVATE_FORCE; + if (srcColorFormat == HAL_PIXEL_FORMAT_RGB_565) { + var.bits_per_pixel = 16; + var.transp.length = 0; + } + else { + var.bits_per_pixel = 32; + var.transp.length = 8; + } + + window.x = dst_x; + window.y = dst_y; + + tvout_v4l2_s_baseaddr(fp_tvout_g, (void *)src_y_address); + put_vscreeninfo(fp_tvout_g, &var); + if (ioctl(fp_tvout_g, S5PTVFB_WIN_POSITION, &window) < 0) { + LOGE("%s:: S5PTVFB_WIN_POSITION ioctl failed.", __func__); + return -1; + } + + return 0; +#endif +} +#endif + +int hdmi_cable_status() +{ +#if defined(BOARD_USE_V4L2) +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int cable_status = 0; + int fd = 0; + struct v4l2_control ctrl; + + fd = open(TVOUT_DEV_G0, O_RDWR); + if (fd <= 0) { + LOGE("%s: graphic layer 0 drv open failed", __func__); + return -1; + } + + ctrl.id = V4L2_CID_TV_HPD_STATUS; + + if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) { + LOGE("Get HPD_STATUS fail"); + cable_status = -1; + } else { + cable_status = ctrl.value; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("HPD_STATUS = %d", cable_status); +#endif + + close(fd); + + return cable_status; +#else + int cable_status = 0; + int fp_hpd = 0; + + fp_hpd = open(HPD_DEV, O_RDWR); + if (fp_hpd <= 0) { + LOGE("hpd drv open failed\n"); + return -1; + } + + //Delay about 0.3s + usleep(500000); + if (ioctl(fp_hpd, HPD_GET_STATE, &cable_status) < 0) { + LOGE("hpd drv HPD_GET_STATE ioctl failed\n"); + cable_status = -1; + } + + close(fp_hpd); + + return cable_status; +#endif +} + +int hdmi_outputmode_2_v4l2_output_type(int output_mode) +{ + int v4l2_output_type = -1; + + switch (output_mode) { + case HDMI_OUTPUT_MODE_YCBCR: + v4l2_output_type = V4L2_OUTPUT_TYPE_DIGITAL; + break; + case HDMI_OUTPUT_MODE_RGB: + v4l2_output_type = V4L2_OUTPUT_TYPE_HDMI_RGB; + break; + case HDMI_OUTPUT_MODE_DVI: + v4l2_output_type = V4L2_OUTPUT_TYPE_DVI; + break; + case COMPOSITE_OUTPUT_MODE: + v4l2_output_type = V4L2_OUTPUT_TYPE_COMPOSITE; + break; + default: + LOGE("%s::unmathced HDMI_mode(%d)", __func__, output_mode); + v4l2_output_type = -1; + break; + } + + return v4l2_output_type; +} + +int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type) +{ + int outputMode = -1; + + switch (v4l2_output_type) { + case V4L2_OUTPUT_TYPE_DIGITAL: + outputMode = HDMI_OUTPUT_MODE_YCBCR; + break; + case V4L2_OUTPUT_TYPE_HDMI_RGB: + outputMode = HDMI_OUTPUT_MODE_RGB; + break; + case V4L2_OUTPUT_TYPE_DVI: + outputMode = HDMI_OUTPUT_MODE_DVI; + break; + case V4L2_OUTPUT_TYPE_COMPOSITE: + outputMode = COMPOSITE_OUTPUT_MODE; + break; + default: + LOGE("%s::unmathced v4l2_output_type(%d)", __func__, v4l2_output_type); + outputMode = -1; + break; + } + + return outputMode; +} + +int composite_std_2_v4l2_std_id(int std) +{ + int std_id = -1; + + switch (std) { + case COMPOSITE_STD_NTSC_M: + std_id = V4L2_STD_NTSC_M; + break; + case COMPOSITE_STD_NTSC_443: + std_id = V4L2_STD_NTSC_443; + break; + case COMPOSITE_STD_PAL_BDGHI: + std_id = V4L2_STD_PAL_BDGHI; + break; + case COMPOSITE_STD_PAL_M: + std_id = V4L2_STD_PAL_M; + break; + case COMPOSITE_STD_PAL_N: + std_id = V4L2_STD_PAL_N; + break; + case COMPOSITE_STD_PAL_Nc: + std_id = V4L2_STD_PAL_Nc; + break; + case COMPOSITE_STD_PAL_60: + std_id = V4L2_STD_PAL_60; + break; + default: + LOGE("%s::unmathced composite_std(%d)", __func__, std); + break; + } + + return std_id; +} + +int hdmi_check_output_mode(int v4l2_output_type) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + int calbirate_v4l2_mode = v4l2_output_type; + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + + switch (v4l2_output_type) { + case V4L2_OUTPUT_TYPE_DIGITAL : + video.mode = HDMI; + if (!EDIDHDMIModeSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; + LOGI("Change mode into DVI\n"); + break; + } + + video.colorSpace = HDMI_CS_YCBCR444; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; + LOGI("Change mode into HDMI_RGB\n"); + } + break; + + case V4L2_OUTPUT_TYPE_HDMI_RGB: + video.mode = HDMI; + if (!EDIDHDMIModeSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; + LOGI("Change mode into DVI\n"); + break; + } + + video.colorSpace = HDMI_CS_RGB; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; + LOGI("Change mode into HDMI_YCBCR\n"); + } + break; + + case V4L2_OUTPUT_TYPE_DVI: + video.mode = DVI; + if (!EDIDHDMIModeSupport(&video)) { + video.colorSpace = HDMI_CS_YCBCR444; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; + LOGI("Change mode into HDMI_RGB\n"); + } else { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; + LOGI("Change mode into HDMI_YCBCR\n"); + } + break; + } + + break; + + default: + break; + } + return calbirate_v4l2_mode; +} + +#if defined(BOARD_USE_V4L2) +int hdmi_check_resolution(unsigned int preset_id) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + + switch (preset_id) { + case V4L2_DV_480P60: + video.resolution = v720x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_576P50: + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_720P60: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_720P50: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080P60: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080P50: + video.resolution = v1920x1080p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080I60: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080I50: + video.resolution = v1920x1080i_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_480P59_94: + video.resolution = v720x480p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_720P59_94: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080I59_94: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080P59_94: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_1080P30: + video.resolution = v1920x1080p_30Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_DV_720P60_SB_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_DV_720P59_94_SB_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_DV_720P50_TB: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_DV_1080P24_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_DV_1080P23_98_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + default: + LOGE("%s::unmathced preset_id(%d)", __func__, preset_id); + return -1; + break; + } + + if (!EDIDVideoResolutionSupport(&video)) { +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::EDIDVideoResolutionSupport(%d) fail (not suppoted preset_id) \n", __func__, preset_id); +#endif + return -1; + } + + return 0; +} + +int hdmi_resolution_2_preset_id(unsigned int resolution, int * w, int * h, unsigned int *preset_id) +{ + int ret = 0; + + switch (resolution) { + case 1080960: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P60; + break; + case 1080950: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P50; + break; + case 1080930: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P30; + break; + case 1080924: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P24_TB; + break; + case 1080160: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080I60; + break; + case 1080150: + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080I50; + break; + case 720960: + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P60; + break; + case 7209601: + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P60_SB_HALF; + break; + case 720950: + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P50; + break; + case 7209501: + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P50_TB; + break; + case 5769501: + *w = 720; + *h = 576; + *preset_id = V4L2_DV_576P50; + break; + case 5769502: + *w = 720; + *h = 576; + *preset_id = V4L2_DV_576P50; + break; + case 4809601: + *w = 720; + *h = 480; + *preset_id = V4L2_DV_480P60; + break; + case 4809602: + *w = 720; + *h = 480; + *preset_id = V4L2_DV_480P60; + break; + default: + LOGE("%s::unmathced resolution(%d)", __func__, resolution); + ret = -1; + break; + } + + return ret; +} +#else +int hdmi_check_resolution(v4l2_std_id std_id) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + + switch (std_id) { + case V4L2_STD_480P_60_16_9: + video.resolution = v720x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_480P_60_4_3: + video.resolution = v640x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_576P_50_16_9: + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_576P_50_4_3: + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_60: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_50: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_60: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_50: + video.resolution = v1920x1080p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_60: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_50: + video.resolution = v1920x1080i_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_480P_59: + video.resolution = v720x480p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_59: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_59: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_59: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_30: + video.resolution = v1920x1080p_30Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_TVOUT_720P_60_SBS_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_STD_TVOUT_720P_59_SBS_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_STD_TVOUT_720P_50_TB: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_STD_TVOUT_1080P_24_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_STD_TVOUT_1080P_23_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + default: + LOGE("%s::unmathced std_id(%lld)", __func__, std_id); + return -1; + break; + } + + if (!EDIDVideoResolutionSupport(&video)) { +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::EDIDVideoResolutionSupport(%llx) fail (not suppoted std_id) \n", __func__, std_id); +#endif + return -1; + } + + return 0; +} + +int hdmi_resolution_2_std_id(unsigned int resolution, int * w, int * h, v4l2_std_id * std_id) +{ + int ret = 0; + + switch (resolution) { + case 1080960: + *std_id = V4L2_STD_1080P_60; + *w = 1920; + *h = 1080; + break; + case 1080950: + *std_id = V4L2_STD_1080P_50; + *w = 1920; + *h = 1080; + break; + case 1080930: + *std_id = V4L2_STD_1080P_30; + *w = 1920; + *h = 1080; + break; + case 1080924: + *std_id = V4L2_STD_TVOUT_1080P_24_TB; + *w = 1920; + *h = 1080; + break; + case 1080160: + *std_id = V4L2_STD_1080I_60; + *w = 1920; + *h = 1080; + break; + case 1080150: + *std_id = V4L2_STD_1080I_50; + *w = 1920; + *h = 1080; + break; + case 720960: + *std_id = V4L2_STD_720P_60; + *w = 1280; + *h = 720; + break; + case 7209601: + *std_id = V4L2_STD_TVOUT_720P_60_SBS_HALF; + *w = 1280; + *h = 720; + break; + case 720950: + *std_id = V4L2_STD_720P_50; + *w = 1280; + *h = 720; + break; + case 7209501: + *std_id = V4L2_STD_TVOUT_720P_50_TB; + *w = 1280; + *h = 720; + break; + case 5769501: + *std_id = V4L2_STD_576P_50_16_9; + *w = 720; + *h = 576; + break; + case 5769502: + *std_id = V4L2_STD_576P_50_4_3; + *w = 720; + *h = 576; + break; + case 4809601: + *std_id = V4L2_STD_480P_60_16_9; + *w = 720; + *h = 480; + break; + case 4809602: + *std_id = V4L2_STD_480P_60_4_3; + *w = 720; + *h = 480; + break; + default: + LOGE("%s::unmathced resolution(%d)", __func__, resolution); + ret = -1; + break; + } + + return ret; +} +#endif + +int hdmi_enable_hdcp(unsigned int hdcp_en) +{ + if (ioctl(fp_tvout, VIDIOC_HDCP_ENABLE, hdcp_en) < 0) { + LOGD("%s::VIDIOC_HDCP_ENABLE(%d) fail \n", __func__, hdcp_en); + return -1; + } + + return 0; +} + +int hdmi_check_audio(void) +{ + struct HDMIAudioParameter audio; + enum state audio_state = ON; + int ret = 0; + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + +#if defined(BOARD_USES_EDID) + if (!EDIDAudioModeSupport(&audio)) + audio_state = NOT_SUPPORT; + else + audio_state = ON; +#endif + if (audio_state == ON) { + if (ioctl(fp_tvout, VIDIOC_INIT_AUDIO, 1) < 0) { + LOGE("%s::VIDIOC_INIT_AUDIO(1) fail", __func__); + ret = -1; + } + } else { + if (ioctl(fp_tvout, VIDIOC_INIT_AUDIO, 0) < 0) { + LOGE("%s::VIDIOC_INIT_AUDIO(0) fail", __func__); + ret = -1; + } + } + + return ret; +} + +} diff --git a/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h b/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h new file mode 100644 index 0000000..a4aa69c --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h @@ -0,0 +1,132 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HDMI_HAL_V4L2_UTILS_H__ +#define __HDMI_HAL_V4L2_UTILS_H__ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#if defined(BOARD_USE_V4L2) +#include "SecBuffer.h" +#endif +#include "fimd_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +namespace android { + +void display_menu(void); + +int tvout_open(const char *fp_name); +#if defined(BOARD_USE_V4L2) +int tvout_std_v4l2_init(int fd, unsigned int preset_id); +int tvout_std_v4l2_querycap(int fd, char *node); +int tvout_std_v4l2_enum_dv_presets(int fd); +int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset); +int tvout_std_v4l2_enum_output(int fd, struct v4l2_output *output); +int tvout_std_v4l2_s_output(int fd, int index); +int tvout_std_v4l2_g_output(int fd, int *index); +int tvout_std_v4l2_s_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, int w, int h, int colorformat, int num_planes); +int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field field, int x, int y, int w, int h); +int tvout_std_v4l2_s_ctrl(int fd, int id, int value); +int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs); +int tvout_std_v4l2_querybuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, unsigned int num_planes, SecBuffer *secBuf); +int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf); +int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes); +int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type); +int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type); +#else +int tvout_init(v4l2_std_id std_id); +int tvout_deinit(); +int tvout_v4l2_querycap(int fp); +int tvout_v4l2_g_std(int fp, v4l2_std_id *std_id); +int tvout_v4l2_s_std(int fp, v4l2_std_id std_id); +int tvout_v4l2_enum_std(int fp, struct v4l2_standard *std, v4l2_std_id std_id); +int tvout_v4l2_enum_output(int fp, struct v4l2_output *output); +int tvout_v4l2_s_output(int fp, int index); +int tvout_v4l2_g_output(int fp, int *index); +int tvout_v4l2_enum_fmt(int fp, struct v4l2_fmtdesc *desc); +int tvout_v4l2_g_fmt(int fp, int buf_type, void* ptr); +int tvout_v4l2_s_fmt(int fp, int buf_type, void *ptr); +int tvout_v4l2_g_fbuf(int fp, struct v4l2_framebuffer *frame); +int tvout_v4l2_s_fbuf(int fp, struct v4l2_framebuffer *frame); +int tvout_v4l2_s_baseaddr(int fp, void *base_addr); +int tvout_v4l2_g_crop(int fp, unsigned int type, struct v4l2_rect *rect); +int tvout_v4l2_s_crop(int fp, unsigned int type, struct v4l2_rect *rect); +int tvout_v4l2_start_overlay(int fp); +int tvout_v4l2_stop_overlay(int fp); +#endif + +int hdmi_init_layer(int layer); +int hdmi_deinit_layer(int layer); +#if defined(BOARD_USE_V4L2) +int hdmi_set_v_param(int fd, int layer, + int srcColorFormat, + int src_w, int src_h, + SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h); +int hdmi_set_g_param(int fd, int layer, + int srcColorFormat, + int src_w, int src_h, + SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h); +int hdmi_set_g_scaling(int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_address, SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal, unsigned int hwc_layer); +#else +int hdmi_set_v_param(int layer, + int src_w, int src_h, int colorFormat, + unsigned int src_y_address, unsigned int src_c_address, + int dst_w, int dst_h); +int hdmi_gl_set_param(int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_y_address, unsigned int src_c_address, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal); +#endif +void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect); +#if defined(BOARD_USE_V4L2) +int hdmi_get_src_plane(int srcColorFormat, unsigned int *num_of_plane); +#endif +int hdmi_cable_status(); +int hdmi_outputmode_2_v4l2_output_type(int output_mode); +int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type); +int composite_std_2_v4l2_std_id(int std); + +int hdmi_check_output_mode(int v4l2_output_type); +#if defined(BOARD_USE_V4L2) +int hdmi_check_resolution(unsigned int preset_id); +int hdmi_resolution_2_preset_id(unsigned int resolution, int * w, int * h, unsigned int *preset_id); +#else +int hdmi_check_resolution(v4l2_std_id std_id); +int hdmi_resolution_2_std_id(unsigned int resolution, int *w, int *h, v4l2_std_id *std_id); +#endif +int hdmi_enable_hdcp(unsigned int hdcp_en); +int hdmi_check_audio(void); + +#ifdef __cplusplus +} +#endif + +} //namespace android + +#endif //__HDMI_HAL_V4L2_UTILS_H__ diff --git a/exynos4/hal/libhdmi/SecHdmi/fimd_api.c b/exynos4/hal/libhdmi/SecHdmi/fimd_api.c new file mode 100644 index 0000000..0e07ef3 --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/fimd_api.c @@ -0,0 +1,229 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fimd_api.h" + +int fb_open(int win) +{ + char node[20]; + int fp = -1; + + sprintf(node, "%s%d", PFX_NODE_FB, win); + + fp = open(node, O_RDWR); + if (fp < 0) + LOGE("%s: fb[%d] open failed", __func__, win); + + return fp; +} + +int fb_close(int fp) +{ + if (fp) + close(fp); + else + LOGE("%s: fb is not allocated %d", __func__, fp); + + return 0; +} + +int get_fscreeninfo(int fp, struct fb_fix_screeninfo *fix) +{ + int ret = -1; + + ret = ioctl(fp, FBIOGET_FSCREENINFO, fix); + if (ret) + LOGE("%s: FBIOGET_FSCREENINFO failed", __func__); + + return ret; +} + +int get_vscreeninfo(int fp, struct fb_var_screeninfo *var) +{ + int ret = -1; + + ret = ioctl(fp, FBIOGET_VSCREENINFO, var); + if (ret) + LOGE("%s:: FBIOGET_VSCREENINFO failed", __func__); + + return ret; +} + +int put_vscreeninfo(int fp, struct fb_var_screeninfo *var) +{ + int ret = -1; + + ret = ioctl(fp, FBIOPUT_VSCREENINFO, var); + if (ret) + LOGE("%s:: FBIOPUT_VSCREENINFO failed", __func__); + + return ret; +} + +int get_bytes_per_pixel(int bits_per_pixel) +{ + return (bits_per_pixel == 24 || bits_per_pixel == 25 || + bits_per_pixel == 28) ? 4 : bits_per_pixel / 8; +} + +char *fb_mmap(__u32 size, int fp) +{ + char *buffer; + + buffer = (char *)mmap(0, size, PROT_READ | PROT_WRITE, + MAP_SHARED, fp, 0); + if (!buffer) { + LOGE("%s:: mmap failed", __func__); + return NULL; + } + + return buffer; +} + +int fb_ioctl(int fp, __u32 cmd, void *arg) +{ + int ret = -1; + + ret = ioctl(fp, cmd, arg); + if (ret < 0) + LOGE("%s:: ioctl (%d) failed", __func__, cmd); + + return ret; +} + +int fb_on(int fp) +{ + int ret = -1; + + ret = ioctl(fp, FBIOBLANK, FB_BLANK_UNBLANK); + if (ret) + LOGE("%s:: FBIOBLANK failed", __func__); + + return ret; +} + +int fb_off(int fp) +{ + int ret = -1; + + ret = ioctl(fp, FBIOBLANK, FB_BLANK_POWERDOWN); + if (ret) + LOGE("%s:: FBIOBLANK failed", __func__); + + return ret; +} + +int fb_off_all() +{ + int fp, i; + + for (i = 0; i < TOTAL_FB_NUM; i++) { + fp = fb_open(i); + if (fp < 0) + return -1; + + if (ioctl(fp, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) + LOGE("%s:: FBIOBLANK failed", __func__); + + fb_off(fp); + fb_close(fp); + } + + return 0; +} + +char *fb_init_display(int fp, int width, int height, int left_x, int top_y, + int bpp) +{ + struct fb_var_screeninfo var; + struct s5ptvfb_user_window window; + int fb_size; + char *fb = NULL; + + var.xres = width; + var.yres = height; + var.bits_per_pixel = bpp; + window.x = left_x; + window.y = top_y; + + var.xres_virtual = var.xres; + var.yres_virtual = var.yres; + var.xoffset = 0; + var.yoffset = 0; + var.width = 0; + var.height = 0; + var.transp.length = 0; + var.activate = FB_ACTIVATE_FORCE; + fb_size = var.xres_virtual * var.yres_virtual * bpp / 8; + + /* FBIOPUT_VSCREENINFO should be first */ + put_vscreeninfo(fp, &var); + fb_ioctl(fp, S5PTVFB_WIN_POSITION, &window); + + /* draw image */ + fb = fb_mmap(fb_size, fp); + memset(fb, 0x0, fb_size); + + return fb; +} + +int simple_draw(char *dest, const char *src, int img_width, + struct fb_var_screeninfo *var) +{ + int bytes_per_pixel = get_bytes_per_pixel(var->bits_per_pixel); + unsigned int y; + + for (y = 0; y < var->yres; y++) + memcpy(dest + y * var->xres * bytes_per_pixel, + src + y * img_width * bytes_per_pixel, + var->xres * bytes_per_pixel); + + return 0; +} + +int draw(char *dest, const char *src, int img_width, + struct fb_var_screeninfo *var) +{ + int bytes_per_pixel = get_bytes_per_pixel(var->bits_per_pixel); + unsigned int y; + + if (var->bits_per_pixel == 16) { + memcpy(dest, src, var->xres * var->yres * 2); + } else { + for (y = 0; y < var->yres; y++) + memcpy(dest + y * var->xres * bytes_per_pixel, + src + y * img_width * bytes_per_pixel, + var->xres * bytes_per_pixel); + } + + return 0; +} diff --git a/exynos4/hal/libhdmi/SecHdmi/fimd_api.h b/exynos4/hal/libhdmi/SecHdmi/fimd_api.h new file mode 100644 index 0000000..a8561a4 --- /dev/null +++ b/exynos4/hal/libhdmi/SecHdmi/fimd_api.h @@ -0,0 +1,51 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FIMD_API_H__ +#define __FIMD_API_H__ + +#include +#include "s5p_tvout.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TOTAL_FB_NUM 5 + +int fb_open(int win); +int fb_close(int fp); +int fb_on(int fp); +int fb_off(int fp); +int fb_off_all(void); +char *fb_init_display(int fp, int width, int height,\ + int left_x, int top_y, int bpp); +int fb_ioctl(int fp, __u32 cmd, void *arg); +char *fb_mmap(__u32 size, int fp); +int simple_draw(char *dest, const char *src,\ + int img_width, struct fb_var_screeninfo *var); +int draw(char *dest, const char *src,\ + int img_width, struct fb_var_screeninfo *var); +int get_fscreeninfo(int fp, struct fb_fix_screeninfo *fix); +int get_vscreeninfo(int fp, struct fb_var_screeninfo *var); +int put_vscreeninfo(int fp, struct fb_var_screeninfo *var); +int get_bytes_per_pixel(int bits_per_pixel); + +#ifdef __cplusplus +} +#endif + +#endif /* __FIMD_API_H__ */ diff --git a/exynos4/hal/libhdmi/libhdmiservice/Android.mk b/exynos4/hal/libhdmi/libhdmiservice/Android.mk new file mode 100644 index 0000000..ebfa9d5 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/Android.mk @@ -0,0 +1,126 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) + +# +# libTVOut +# + +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES := \ + SecTVOutService.cpp \ + ISecTVOut.cpp \ + MessageQueue.cpp + +LOCAL_C_INCLUDES := \ + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libcutils + +LOCAL_C_INCLUDES += $(TARGET_HAL_PATH)/include +LOCAL_C_INCLUDES += $(TARGET_HAL_PATH)/libhdmi +LOCAL_C_INCLUDES += $(TARGET_HAL_PATH)/libfimc +LOCAL_SHARED_LIBRARIES += libhdmi libfimc + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +ifeq ($(TARGET_SOC),exynos4210) + LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) + LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +LOCAL_CFLAGS += -DBOARD_USES_HDMI + +ifeq ($(BOARD_USE_V4L2),true) + LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +ifeq ($(BOARD_USE_V4L2_ION),true) + LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION +endif + +LOCAL_MODULE := libTVOut + +include $(BUILD_SHARED_LIBRARY) + +# +# libhdmiclient +# + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES:= \ + SecHdmiClient.cpp + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libTVOut + +ifeq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_OS),linux) +ifeq ($(TARGET_ARCH),x86) +LOCAL_LDLIBS += -lpthread -ldl -lrt +endif +endif +endif + +ifeq ($(WITH_MALLOC_LEAK_CHECK),true) + LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK +endif + +ifeq ($(TARGET_SOC),exynos4210) + LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) + LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +LOCAL_CFLAGS += -DBOARD_USES_HDMI + +ifeq ($(BOARD_USE_V4L2),true) + LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +ifeq ($(BOARD_USE_V4L2_ION),true) + LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION +endif + +LOCAL_MODULE:= libhdmiclient + +include $(BUILD_SHARED_LIBRARY) + +endif +endif diff --git a/exynos4/hal/libhdmi/libhdmiservice/Barrier.h b/exynos4/hal/libhdmi/libhdmiservice/Barrier.h new file mode 100644 index 0000000..6f8507e --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/Barrier.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BARRIER_H +#define ANDROID_BARRIER_H + +#include +#include +#include + +namespace android { + +class Barrier +{ +public: + inline Barrier() : state(CLOSED) { } + inline ~Barrier() { } + void open() { + Mutex::Autolock _l(lock); + state = OPENED; + cv.broadcast(); + } + void close() { + Mutex::Autolock _l(lock); + state = CLOSED; + } + void wait() const { + Mutex::Autolock _l(lock); + while (state == CLOSED) { + cv.wait(lock); + } + } +private: + enum { OPENED, CLOSED }; + mutable Mutex lock; + mutable Condition cv; + volatile int state; +}; + +}; // namespace android + +#endif // ANDROID_BARRIER_H diff --git a/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.cpp b/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.cpp new file mode 100644 index 0000000..a013bf1 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.cpp @@ -0,0 +1,111 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#include +#include +#include +#include +#include "ISecTVOut.h" + +namespace android { + + enum { + SET_HDMI_STATUS = IBinder::FIRST_CALL_TRANSACTION, + SET_HDMI_MODE, + SET_HDMI_RESOLUTION, + SET_HDMI_HDCP, + SET_HDMI_ROTATE, + SET_HDMI_HWCLAYER, + BLIT_2_HDMI + }; + + void BpSecTVOut::setHdmiCableStatus(uint32_t status) + { + Parcel data, reply; + data.writeInt32(status); + remote()->transact(SET_HDMI_STATUS, data, &reply); + } + + void BpSecTVOut::setHdmiMode(uint32_t mode) + { + Parcel data, reply; + data.writeInt32(mode); + remote()->transact(SET_HDMI_MODE, data, &reply); + } + + void BpSecTVOut::setHdmiResolution(uint32_t resolution) + { + Parcel data, reply; + data.writeInt32(resolution); + remote()->transact(SET_HDMI_RESOLUTION, data, &reply); + } + + void BpSecTVOut::setHdmiHdcp(uint32_t resolution) + { + Parcel data, reply; + data.writeInt32(resolution); + remote()->transact(SET_HDMI_HDCP, data, &reply); + } + + void BpSecTVOut::setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) + { + Parcel data, reply; + data.writeInt32(rotVal); + data.writeInt32(hwcLayer); + remote()->transact(SET_HDMI_ROTATE, data, &reply); + } + + void BpSecTVOut::setHdmiHwcLayer(uint32_t hwcLayer) + { + Parcel data, reply; + data.writeInt32(hwcLayer); + remote()->transact(SET_HDMI_HWCLAYER, data, &reply); + } + + void BpSecTVOut::blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) + { + Parcel data, reply; + data.writeInt32(w); + data.writeInt32(h); + data.writeInt32(colorFormat); + data.writeInt32(physYAddr); + data.writeInt32(physCbAddr); + data.writeInt32(physCrAddr); + data.writeInt32(dstX); + data.writeInt32(dstY); + data.writeInt32(hdmiLayer); + data.writeInt32(num_of_hwc_layer); + remote()->transact(BLIT_2_HDMI, data, &reply); + } + + IMPLEMENT_META_INTERFACE(SecTVOut, "android.os.ISecTVOut"); +}; diff --git a/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.h b/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.h new file mode 100644 index 0000000..5506b57 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/ISecTVOut.h @@ -0,0 +1,74 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef ISECTVOUT_H +#define ISECTVOUT_H +#include +#include +#include + +namespace android { + class ISecTVOut: public IInterface + { + public: + DECLARE_META_INTERFACE(SecTVOut); + virtual void setHdmiCableStatus(uint32_t status) = 0; + virtual void setHdmiMode(uint32_t mode) = 0; + virtual void setHdmiResolution(uint32_t resolution) = 0; + virtual void setHdmiHdcp(uint32_t enHdcp) = 0; + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) = 0; + virtual void setHdmiHwcLayer(uint32_t hwcLayer) = 0; + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) = 0; + }; + //-------------------------------------------------------------- + class BpSecTVOut: public BpInterface + { + public: + BpSecTVOut(const sp& impl): BpInterface(impl){} + virtual void setHdmiCableStatus(uint32_t status); + virtual void setHdmiMode(uint32_t mode); + virtual void setHdmiResolution(uint32_t resolution); + virtual void setHdmiHdcp(uint32_t enHdcp); + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer); + virtual void setHdmiHwcLayer(uint32_t hwcLayer); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer); + }; +}; +#endif diff --git a/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.cpp b/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.cpp new file mode 100644 index 0000000..aebe1b8 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "MessageQueue.h" + +namespace android { + +// --------------------------------------------------------------------------- + +void MessageList::insert(const sp& node) +{ + LIST::iterator cur(mList.begin()); + LIST::iterator end(mList.end()); + while (cur != end) { + if (*node < **cur) { + mList.insert(cur, node); + return; + } + ++cur; + } + mList.insert(++end, node); +} + +void MessageList::remove(MessageList::LIST::iterator pos) +{ + mList.erase(pos); +} + +// --------------------------------------------------------------------------- + +MessageQueue::MessageQueue() + : mInvalidate(false) +{ + mInvalidateMessage = new MessageBase(INVALIDATE); +} + +MessageQueue::~MessageQueue() +{ +} + +sp MessageQueue::waitMessage(nsecs_t timeout) +{ + sp result; + + bool again; + do { + const nsecs_t timeoutTime = systemTime() + timeout; + while (true) { + Mutex::Autolock _l(mLock); + nsecs_t now = systemTime(); + nsecs_t nextEventTime = -1; + + LIST::iterator cur(mMessages.begin()); + if (cur != mMessages.end()) { + result = *cur; + } + + if (result != 0) { + if (result->when <= now) { + // there is a message to deliver + mMessages.remove(cur); + break; + } + nextEventTime = result->when; + result = 0; + } + + // see if we have an invalidate message + if (mInvalidate) { + mInvalidate = false; + mInvalidateMessage->when = now; + result = mInvalidateMessage; + break; + } + + if (timeout >= 0) { + if (timeoutTime < now) { + // we timed-out, return a NULL message + result = 0; + break; + } + if (nextEventTime > 0) { + if (nextEventTime > timeoutTime) { + nextEventTime = timeoutTime; + } + } else { + nextEventTime = timeoutTime; + } + } + + if (nextEventTime >= 0) { + //LOGD("nextEventTime = %lld ms", nextEventTime); + if (nextEventTime > 0) { + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + const nsecs_t reltime = nextEventTime - systemTime(); + if (reltime > 0) { + mCondition.waitRelative(mLock, reltime); + } + } + } else { + //LOGD("going to wait"); + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + mCondition.wait(mLock); + } + } + // here we're not holding the lock anymore + + if (result == 0) + break; + + again = result->handler(); + if (again) { + // the message has been processed. release our reference to it + // without holding the lock. + result->notify(); + result = 0; + } + + } while (again); + + return result; +} + +status_t MessageQueue::postMessage( + const sp& message, nsecs_t relTime, uint32_t flags) +{ + return queueMessage(message, relTime, flags); +} + +status_t MessageQueue::invalidate() { + Mutex::Autolock _l(mLock); + mInvalidate = true; + mCondition.signal(); + return NO_ERROR; +} + +status_t MessageQueue::queueMessage( + const sp& message, nsecs_t relTime, uint32_t flags) +{ + Mutex::Autolock _l(mLock); + message->when = systemTime() + relTime; + mMessages.insert(message); + + //LOGD("MessageQueue::queueMessage time = %lld ms", message->when); + //dumpLocked(message); + + mCondition.signal(); + return NO_ERROR; +} + +void MessageQueue::dump(const sp& message) +{ + Mutex::Autolock _l(mLock); + dumpLocked(message); +} + +void MessageQueue::dumpLocked(const sp& message) +{ + LIST::const_iterator cur(mMessages.begin()); + LIST::const_iterator end(mMessages.end()); + int c = 0; + while (cur != end) { + const char tick = (*cur == message) ? '>' : ' '; + LOGD("%c %d: msg{.what=%08x, when=%lld}", + tick, c, (*cur)->what, (*cur)->when); + ++cur; + c++; + } +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.h b/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.h new file mode 100644 index 0000000..890f809 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/MessageQueue.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MESSAGE_QUEUE_H +#define ANDROID_MESSAGE_QUEUE_H + +#include +#include +#include + +#include +#include +#include + +#include "Barrier.h" + +namespace android { + +// --------------------------------------------------------------------------- + +class MessageBase; + +class MessageList +{ + List< sp > mList; + typedef List< sp > LIST; +public: + inline LIST::iterator begin() { return mList.begin(); } + inline LIST::const_iterator begin() const { return mList.begin(); } + inline LIST::iterator end() { return mList.end(); } + inline LIST::const_iterator end() const { return mList.end(); } + inline bool isEmpty() const { return mList.empty(); } + void insert(const sp& node); + void remove(LIST::iterator pos); +}; + +// ============================================================================ + +class MessageBase : + public LightRefBase +{ +public: + nsecs_t when; + uint32_t what; + int32_t arg0; + + MessageBase() : when(0), what(0), arg0(0) { } + MessageBase(uint32_t what, int32_t arg0=0) + : when(0), what(what), arg0(arg0) { } + + // return true if message has a handler + virtual bool handler() { return false; } + + // waits for the handler to be processed + void wait() const { barrier.wait(); } + + // releases all waiters. this is done automatically if + // handler returns true + void notify() const { barrier.open(); } + +protected: + virtual ~MessageBase() { } + +private: + mutable Barrier barrier; + friend class LightRefBase; +}; + +inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { + return lhs.when < rhs.when; +} + +// --------------------------------------------------------------------------- + +class MessageQueue +{ + typedef List< sp > LIST; +public: + + MessageQueue(); + ~MessageQueue(); + + // pre-defined messages + enum { + INVALIDATE = '_upd' + }; + + sp waitMessage(nsecs_t timeout = -1); + + status_t postMessage(const sp& message, + nsecs_t reltime=0, uint32_t flags = 0); + + status_t invalidate(); + + void dump(const sp& message); + +private: + status_t queueMessage(const sp& message, + nsecs_t reltime, uint32_t flags); + void dumpLocked(const sp& message); + + Mutex mLock; + Condition mCondition; + MessageList mMessages; + bool mInvalidate; + sp mInvalidateMessage; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif /* ANDROID_MESSAGE_QUEUE_H */ diff --git a/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp b/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp new file mode 100644 index 0000000..c5cca78 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp @@ -0,0 +1,148 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#define LOG_TAG "libhdmiclient" + +#include "SecHdmiClient.h" + +namespace android { + +static sp g_SecTVOutService = 0; + +SecHdmiClient::SecHdmiClient() +{ + g_SecTVOutService = m_getSecTVOutService(); + mEnable = 0; +} + +SecHdmiClient::~SecHdmiClient() +{ +} + +SecHdmiClient * SecHdmiClient::getInstance(void) +{ + static SecHdmiClient singleton; + return &singleton; +} + +void SecHdmiClient::setHdmiCableStatus(int status) +{ + //LOGD("%s HDMI status: %d\n", __func__, status); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiCableStatus(status); +} + +void SecHdmiClient::setHdmiMode(int mode) +{ + //LOGD("%s HDMI Mode: %d\n", __func__, mode); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiMode(mode); +} + +void SecHdmiClient::setHdmiResolution(int resolution) +{ + //LOGD("%s HDMI Resolution: %d\n", __func__, resolution); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiResolution(resolution); +} + +void SecHdmiClient::setHdmiHdcp(int enHdcp) +{ + //LOGD("%s HDMI HDCP: %d\n", __func__, enHdcp); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiHdcp(enHdcp); +} + +void SecHdmiClient::setHdmiRotate(int rotVal, uint32_t hwcLayer) +{ + //LOGD("%s HDMI ROTATE: %d\n", __func__, rotVal); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiRotate(rotVal, hwcLayer); +} + +void SecHdmiClient::setHdmiHwcLayer(uint32_t hwcLayer) +{ + //LOGD("%s HDMI HWCLAYER: %d\n", __func__, hwcLayer); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiHwcLayer(hwcLayer); +} + +void SecHdmiClient::setHdmiEnable(uint32_t enable) +{ + //LOGD("%s HDMI ENABLE: %d\n", __func__, enable); + + if (g_SecTVOutService != 0) + mEnable = enable; +} + +void SecHdmiClient::blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) +{ + if (g_SecTVOutService != 0 && mEnable == 1) + g_SecTVOutService->blit2Hdmi(w, h, colorFormat, physYAddr, physCbAddr, physCrAddr, dstX, dstY, hdmiLayer, num_of_hwc_layer); +} + +sp SecHdmiClient::m_getSecTVOutService(void) +{ + int ret = 0; + + if (g_SecTVOutService == 0) { + sp binder; + sp sc; + sp sm = defaultServiceManager(); + int getSvcTimes = 0; + for(getSvcTimes = 0; getSvcTimes < GETSERVICETIMEOUT; getSvcTimes++) { + binder = sm->getService(String16("SecTVOutService")); + if (binder == 0) { + LOGW("SecTVOutService not published, waiting..."); + usleep(500000); // 0.5 s + } else { + break; + } + } + // grab the lock again for updating g_surfaceFlinger + if (getSvcTimes < GETSERVICETIMEOUT) { + sc = interface_cast(binder); + g_SecTVOutService = sc; + } else { + LOGW("Failed to get SecTVOutService... SecHdmiClient will get it later.."); + } + } + return g_SecTVOutService; +} + +} diff --git a/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.h b/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.h new file mode 100644 index 0000000..ebee763 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/SecHdmiClient.h @@ -0,0 +1,86 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef __SEC_HDMI_CLIENT_H__ +#define __SEC_HDMI_CLIENT_H__ + +#include "utils/Log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ISecTVOut.h" + +#define GETSERVICETIMEOUT (5) + +namespace android { + +class SecHdmiClient +{ +public: + enum HDMI_MODE + { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + +private: + SecHdmiClient(); + virtual ~SecHdmiClient(); + uint32_t mEnable; + +public: + static SecHdmiClient * getInstance(void); + void setHdmiCableStatus(int status); + void setHdmiMode(int mode); + void setHdmiResolution(int resolution); + void setHdmiHdcp(int enHdcp); + void setHdmiRotate(int rotVal, uint32_t hwcLayer); + void setHdmiHwcLayer(uint32_t hwcLayer); + void setHdmiEnable(uint32_t enable); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer); + +private: + sp m_getSecTVOutService(void); + +}; + +}; + +#endif diff --git a/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.cpp b/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.cpp new file mode 100644 index 0000000..de98810 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.cpp @@ -0,0 +1,387 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#define LOG_TAG "SecTVOutService" + +#include +#include +#include +#include +#include +#include "SecTVOutService.h" +#include + +namespace android { +#define DEFAULT_LCD_WIDTH 800 +#define DEFAULT_LCD_HEIGHT 480 + +#define DIRECT_VIDEO_RENDERING (1) +#define DIRECT_UI_RENDERING (0) + + enum { + SET_HDMI_STATUS = IBinder::FIRST_CALL_TRANSACTION, + SET_HDMI_MODE, + SET_HDMI_RESOLUTION, + SET_HDMI_HDCP, + SET_HDMI_ROTATE, + SET_HDMI_HWCLAYER, + BLIT_2_HDMI + }; + + int SecTVOutService::HdmiFlushThread() + { + while (!mExitHdmiFlushThread) { + nsecs_t timeout = -1; + sp msg = mHdmiEventQueue.waitMessage(timeout); + } + + return 0; + } + + int SecTVOutService::instantiate() + { + LOGD("SecTVOutService instantiate"); + int r = defaultServiceManager()->addService(String16( "SecTVOutService"), new SecTVOutService ()); + LOGD("SecTVOutService r=%d", r); + + return r; + } + + SecTVOutService::SecTVOutService () { + LOGV("SecTVOutService created"); + mHdmiCableInserted = false; +#ifdef SUPPORT_G2D_UI_MODE + mUILayerMode = SecHdmi::HDMI_LAYER_GRAPHIC_1; +#else + mUILayerMode = SecHdmi::HDMI_LAYER_VIDEO; +#endif + mHwcLayer = 0; + mExitHdmiFlushThread = false; + + setLCDsize(); + if (mSecHdmi.create(mLCD_width, mLCD_height) == false) + LOGE("%s::mSecHdmi.create() fail", __func__); + else + setHdmiStatus(1); + + mHdmiFlushThread = new HDMIFlushThread(this); + } + + void SecTVOutService::setLCDsize(void) { + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + 0 }; + + int fd = -1; + int i = 0; + char name[64]; + + while ((fd==-1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + if (fd > 0) { + struct fb_var_screeninfo info; + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) != -1) { + mLCD_width = info.xres; + mLCD_height = info.yres; + } else { + mLCD_width = DEFAULT_LCD_WIDTH; + mLCD_height = DEFAULT_LCD_HEIGHT; + } + close(fd); + } + return; + } + + SecTVOutService::~SecTVOutService () { + LOGV ("SecTVOutService destroyed"); + + if (mHdmiFlushThread != NULL) { + mHdmiFlushThread->requestExit(); + mExitHdmiFlushThread = true; + mHdmiFlushThread->requestExitAndWait(); + mHdmiFlushThread.clear(); + } + } + + status_t SecTVOutService::onTransact(uint32_t code, const Parcel & data, Parcel * reply, uint32_t flags) + { + switch (code) { + case SET_HDMI_STATUS: { + int status = data.readInt32(); + setHdmiStatus(status); + } break; + + case SET_HDMI_MODE: { + int mode = data.readInt32(); + setHdmiMode(mode); + } break; + + case SET_HDMI_RESOLUTION: { + int resolution = data.readInt32(); + setHdmiResolution(resolution); + } break; + + case SET_HDMI_HDCP: { + int enHdcp = data.readInt32(); + setHdmiHdcp(enHdcp); + } break; + + case SET_HDMI_ROTATE: { + int rotVal = data.readInt32(); + int hwcLayer = data.readInt32(); + setHdmiRotate(rotVal, hwcLayer); + } break; + + case SET_HDMI_HWCLAYER: { + int hwcLayer = data.readInt32(); + setHdmiHwcLayer((uint32_t)hwcLayer); + } break; + + case BLIT_2_HDMI: { + uint32_t w = data.readInt32(); + uint32_t h = data.readInt32(); + uint32_t colorFormat = data.readInt32(); + uint32_t physYAddr = data.readInt32(); + uint32_t physCbAddr = data.readInt32(); + uint32_t physCrAddr = data.readInt32(); + uint32_t dstX = data.readInt32(); + uint32_t dstY = data.readInt32(); + uint32_t hdmiLayer = data.readInt32(); + uint32_t num_of_hwc_layer = data.readInt32(); + + blit2Hdmi(w, h, colorFormat, physYAddr, physCbAddr, physCrAddr, dstX, dstY, hdmiLayer, num_of_hwc_layer); + } break; + + default : + LOGE ( "onTransact::default"); + return BBinder::onTransact (code, data, reply, flags); + } + + return NO_ERROR; + } + + void SecTVOutService::setHdmiStatus(uint32_t status) + { + + LOGD("%s HDMI cable status = %d", __func__, status); + { + Mutex::Autolock _l(mLock); + + bool hdmiCableInserted = (bool)status; + + if (mHdmiCableInserted == hdmiCableInserted) + return; + + if (hdmiCableInserted == true) { + if (mSecHdmi.connect() == false) { + LOGE("%s::mSecHdmi.connect() fail", __func__); + hdmiCableInserted = false; + } + } else { + if (mSecHdmi.disconnect() == false) + LOGE("%s::mSecHdmi.disconnect() fail", __func__); + } + + mHdmiCableInserted = hdmiCableInserted; + } + + if (hdmiCableInserted() == true) + this->blit2Hdmi(mLCD_width, mLCD_height, HAL_PIXEL_FORMAT_BGRA_8888, 0, 0, 0, 0, 0, HDMI_MODE_UI, 0); + } + + void SecTVOutService::setHdmiMode(uint32_t mode) + { + LOGD("%s TV mode = %d", __func__, mode); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdmiOutputMode(mode)) == false) { + LOGE("%s::mSecHdmi.setHdmiOutputMode() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiResolution(uint32_t resolution) + { + //LOGD("%s TV resolution = %d", __func__, resolution); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdmiResolution(resolution)) == false) { + LOGE("%s::mSecHdmi.setHdmiResolution() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiHdcp(uint32_t hdcp_en) + { + LOGD("%s TV HDCP = %d", __func__, hdcp_en); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdcpMode(hdcp_en)) == false) { + LOGE("%s::mSecHdmi.setHdcpMode() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) + { + //LOGD("%s TV ROTATE = %d", __func__, rotVal); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setUIRotation(rotVal, hwcLayer)) == false) { + LOGE("%s::mSecHdmi.setUIRotation() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiHwcLayer(uint32_t hwcLayer) + { + //LOGD("%s TV HWCLAYER = %d", __func__, hwcLayer); + Mutex::Autolock _l(mLock); + + mHwcLayer = hwcLayer; + return; + } + + void SecTVOutService::blit2Hdmi(uint32_t w, uint32_t h, uint32_t colorFormat, + uint32_t pPhyYAddr, uint32_t pPhyCbAddr, uint32_t pPhyCrAddr, + uint32_t dstX, uint32_t dstY, + uint32_t hdmiMode, + uint32_t num_of_hwc_layer) + { + Mutex::Autolock _l(mLock); + + if (hdmiCableInserted() == false) + return; + + int hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; +#if defined(CHECK_UI_TIME) || defined(CHECK_VIDEO_TIME) + nsecs_t start, end; +#endif + + sp msg; + + switch (hdmiMode) { + case HDMI_MODE_UI : + if (mHwcLayer >= 2) + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_0; + else if (mHwcLayer == 1) + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; + else +#ifdef SUPPORT_G2D_UI_MODE + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; +#else + hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; +#endif + +#ifdef SUPPORT_G2D_UI_MODE + if (mHwcLayer == 0) { + if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_VIDEO) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_VIDEO); + if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_0) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_0); + } +#endif + + if (mUILayerMode != hdmiLayer) { + if (mSecHdmi.clear(mUILayerMode) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, mUILayerMode); + } + + mUILayerMode = hdmiLayer; + +#if !defined(BOARD_USES_HDMI_SUBTITLES) + if (mHwcLayer == 0) +#endif +#if (DIRECT_UI_RENDERING == 1) + { +#ifdef CHECK_UI_TIME + start = systemTime(); +#endif + if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, + mUILayerMode, mHwcLayer) == false) + LOGE("%s::mSecHdmi.flush() on HDMI_MODE_UI fail", __func__); +#ifdef CHECK_UI_TIME + end = systemTime(); + LOGD("[UI] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + } +#else + { + msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, + dstX, dstY, mUILayerMode, mHwcLayer, HDMI_MODE_UI); + + /* post to HdmiEventQueue */ + mHdmiEventQueue.postMessage(msg, 0, 0); + } +#endif + break; + + case HDMI_MODE_VIDEO : +#if !defined(BOARD_USES_HDMI_SUBTITLES) +#ifdef SUPPORT_G2D_UI_MODE + if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_0) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_0); + if (mSecHdmi.clear(SecHdmi::HDMI_LAYER_GRAPHIC_1) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, SecHdmi::HDMI_LAYER_GRAPHIC_1); +#endif +#endif + +#if (DIRECT_VIDEO_RENDERING == 1) +#ifdef CHECK_VIDEO_TIME + start = systemTime(); +#endif + if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, + SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer) == false) + LOGE("%s::mSecHdmi.flush() on HDMI_MODE_VIDEO fail", __func__); +#ifdef CHECK_VIDEO_TIME + end = systemTime(); + LOGD("[Video] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif +#else + msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, + dstX, dstY, SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer, HDMI_MODE_VIDEO); + + /* post to HdmiEventQueue */ + mHdmiEventQueue.postMessage(msg, 0, 0); +#endif + break; + + default: + LOGE("unmatched HDMI_MODE : %d", hdmiMode); + break; + } + + return; + } + + bool SecTVOutService::hdmiCableInserted(void) + { + return mHdmiCableInserted; + } + +} diff --git a/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.h b/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.h new file mode 100644 index 0000000..1f5f251 --- /dev/null +++ b/exynos4/hal/libhdmi/libhdmiservice/SecTVOutService.h @@ -0,0 +1,174 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef SECTVOUTSERVICE_H +#define SECTVOUTSERVICE_H + +#include +#include +#include +#include + +#include "ISecTVOut.h" +#include "SecHdmi.h" +#include "sec_format.h" +#include "sec_utils.h" +#include "MessageQueue.h" + +namespace android { +//#define CHECK_VIDEO_TIME +//#define CHECK_UI_TIME + + class SecTVOutService : public BBinder + { + public : + enum { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + + mutable Mutex mLock; + + class HDMIFlushThread : public Thread { + SecTVOutService *mTVOutService; + public: + HDMIFlushThread(SecTVOutService *service): + Thread(false), + mTVOutService(service) { } + virtual void onFirstRef() { + run("HDMIFlushThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + mTVOutService->HdmiFlushThread(); + return false; + } + }; + + sp mHdmiFlushThread; + int HdmiFlushThread(); + + mutable MessageQueue mHdmiEventQueue; + bool mExitHdmiFlushThread; + + SecTVOutService(); + static int instantiate (); + virtual status_t onTransact(uint32_t, const Parcel &, Parcel *, uint32_t); + virtual ~SecTVOutService (); + + virtual void setHdmiStatus(uint32_t status); + virtual void setHdmiMode(uint32_t mode); + virtual void setHdmiResolution(uint32_t resolution); + virtual void setHdmiHdcp(uint32_t enHdcp); + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer); + virtual void setHdmiHwcLayer(uint32_t hwcLayer); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t pPhyYAddr, uint32_t pPhyCbAddr, uint32_t pPhyCrAddr, + uint32_t dstX, uint32_t dstY, + uint32_t hdmiMode, uint32_t num_of_hwc_layer); + bool hdmiCableInserted(void); + void setLCDsize(void); + + private: + SecHdmi mSecHdmi; + bool mHdmiCableInserted; + int mUILayerMode; + uint32_t mLCD_width, mLCD_height; + uint32_t mHwcLayer; + }; + + class SecHdmiEventMsg : public MessageBase { + public: + enum { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + + mutable Mutex mBlitLock; + + SecHdmi *pSecHdmi; + uint32_t mSrcWidth, mSrcHeight; + uint32_t mSrcColorFormat; + uint32_t mSrcYAddr, mSrcCbAddr, mSrcCrAddr; + uint32_t mDstX, mDstY; + uint32_t mHdmiMode; + uint32_t mHdmiLayer, mHwcLayer; + + SecHdmiEventMsg(SecHdmi *SecHdmi, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcColorFormat, + uint32_t srcYAddr, uint32_t srcCbAddr, uint32_t srcCrAddr, + uint32_t dstX, uint32_t dstY, uint32_t hdmiLayer, uint32_t hwcLayer, uint32_t hdmiMode) + : pSecHdmi(SecHdmi), mSrcWidth(srcWidth), mSrcHeight(srcHeight), mSrcColorFormat(srcColorFormat), + mSrcYAddr(srcYAddr), mSrcCbAddr(srcCbAddr), mSrcCrAddr(srcCrAddr), + mDstX(dstX), mDstY(dstY), mHdmiLayer(hdmiLayer), mHwcLayer(hwcLayer), mHdmiMode(hdmiMode) { + } + + virtual bool handler() { + Mutex::Autolock _l(mBlitLock); + bool ret = true; +#if defined(CHECK_UI_TIME) || defined(CHECK_VIDEO_TIME) + nsecs_t start, end; +#endif + + switch (mHdmiMode) { + case HDMI_MODE_UI: +#ifdef CHECK_UI_TIME + start = systemTime(); +#endif + if (pSecHdmi->flush(mSrcWidth, mSrcHeight, mSrcColorFormat, mSrcYAddr, mSrcCbAddr, mSrcCrAddr, + mDstX, mDstY, mHdmiLayer, mHwcLayer) == false) { + LOGE("%s::pSecHdmi->flush() fail on HDMI_MODE_UI", __func__); + ret = false; + } +#ifdef CHECK_UI_TIME + end = systemTime(); + LOGD("[UI] pSecHdmi->flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + break; + case HDMI_MODE_VIDEO: +#ifdef CHECK_VIDEO_TIME + start = systemTime(); +#endif + if (pSecHdmi->flush(mSrcWidth, mSrcHeight, mSrcColorFormat, mSrcYAddr, mSrcCbAddr, mSrcCrAddr, + mDstX, mDstY, mHdmiLayer, mHwcLayer) == false) { + LOGE("%s::pSecHdmi->flush() fail on HDMI_MODE_VIDEO", __func__); + ret = false; + } +#ifdef CHECK_VIDEO_TIME + end = systemTime(); + LOGD("[VIDEO] pSecHdmi->flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + break; + default: + LOGE("Undefined HDMI_MODE"); + ret = false; + break; + } + return ret; + } + }; + +}; +#endif diff --git a/exynos4/hal/libhdmi/libsForhdmi/Android.mk b/exynos4/hal/libhdmi/libsForhdmi/Android.mk new file mode 100644 index 0000000..237c53c --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/Android.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) +include $(all-subdir-makefiles) +endif diff --git a/exynos4/hal/libhdmi/libsForhdmi/libcec/Android.mk b/exynos4/hal/libhdmi/libsForhdmi/libcec/Android.mk new file mode 100644 index 0000000..9a4b721 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libcec/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := libcec.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +LOCAL_MODULE := libcec +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libhdmi/libsForhdmi/libcec/cec.h b/exynos4/hal/libhdmi/libsForhdmi/libcec/cec.h new file mode 100644 index 0000000..4b0d3af --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libcec/cec.h @@ -0,0 +1,11 @@ +#ifndef _LINUX_CEC_H_ +#define _LINUX_CEC_H_ + +#define CEC_IOC_MAGIC 'c' + +/** + * CEC device request code to set logical address. + */ +#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int) + +#endif /* _LINUX_CEC_H_ */ diff --git a/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.c b/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.c new file mode 100644 index 0000000..e688051 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.c @@ -0,0 +1,386 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* drv. header */ +#include "cec.h" + +#include "libcec.h" + +#define CEC_DEBUG 0 + +/** + * @def CEC_DEVICE_NAME + * Defines simbolic name of the CEC device. + */ +#define CEC_DEVICE_NAME "/dev/CEC" + +static struct { + enum CECDeviceType devtype; + unsigned char laddr; +} laddresses[] = { + { CEC_DEVICE_RECODER, 1 }, + { CEC_DEVICE_RECODER, 2 }, + { CEC_DEVICE_TUNER, 3 }, + { CEC_DEVICE_PLAYER, 4 }, + { CEC_DEVICE_AUDIO, 5 }, + { CEC_DEVICE_TUNER, 6 }, + { CEC_DEVICE_TUNER, 7 }, + { CEC_DEVICE_PLAYER, 8 }, + { CEC_DEVICE_RECODER, 9 }, + { CEC_DEVICE_TUNER, 10 }, + { CEC_DEVICE_PLAYER, 11 }, +}; + +static int CECSetLogicalAddr(unsigned int laddr); + +#ifdef CEC_DEBUG +inline static void CECPrintFrame(unsigned char *buffer, unsigned int size); +#endif + +static int fd = -1; + +/** + * Open device driver and assign CEC file descriptor. + * + * @return If success to assign CEC file descriptor, return 1; otherwise, return 0. + */ +int CECOpen() +{ + int res = 1; + + if (fd != -1) + CECClose(); + + if ((fd = open(CEC_DEVICE_NAME, O_RDWR)) < 0) { + LOGE("Can't open %s!\n", CEC_DEVICE_NAME); + res = 0; + } + + return res; +} + +/** + * Close CEC file descriptor. + * + * @return If success to close CEC file descriptor, return 1; otherwise, return 0. + */ +int CECClose() +{ + int res = 1; + + if (fd != -1) { + if (close(fd) != 0) { + LOGE("close() failed!\n"); + res = 0; + } + fd = -1; + } + + return res; +} + +/** + * Allocate logical address. + * + * @param paddr [in] CEC device physical address. + * @param devtype [in] CEC device type. + * + * @return new logical address, or 0 if an arror occured. + */ +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype) +{ + unsigned char laddr = CEC_LADDR_UNREGISTERED; + int i = 0; + + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + if (CECSetLogicalAddr(laddr) < 0) { + LOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + if (paddr == CEC_NOT_VALID_PHYSICAL_ADDRESS) + return CEC_LADDR_UNREGISTERED; + + /* send "Polling Message" */ + while (i < sizeof(laddresses)/sizeof(laddresses[0])) { + if (laddresses[i].devtype == devtype) { + unsigned char _laddr = laddresses[i].laddr; + unsigned char message = ((_laddr << 4) | _laddr); + if (CECSendMessage(&message, 1) != 1) { + laddr = _laddr; + break; + } + } + i++; + } + + if (laddr == CEC_LADDR_UNREGISTERED) { + LOGE("All LA addresses in use!!!\n"); + return CEC_LADDR_UNREGISTERED; + } + + if (CECSetLogicalAddr(laddr) < 0) { + LOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + /* broadcast "Report Physical Address" */ + unsigned char buffer[5]; + buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS; + buffer[2] = (paddr >> 8) & 0xFF; + buffer[3] = paddr & 0xFF; + buffer[4] = devtype; + + if (CECSendMessage(buffer, 5) != 5) { + LOGE("CECSendMessage() failed!\n"); + return 0; + } + + return laddr; +} + +/** + * Send CEC message. + * + * @param *buffer [in] pointer to buffer address where message located. + * @param size [in] message size. + * + * @return number of bytes written, or 0 if an arror occured. + */ +int CECSendMessage(unsigned char *buffer, int size) +{ + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + if (size > CEC_MAX_FRAME_SIZE) { + LOGE("size should not exceed %d\n", CEC_MAX_FRAME_SIZE); + return 0; + } + +#if CEC_DEBUG + LOGI("CECSendMessage() : "); + CECPrintFrame(buffer, size); +#endif + + return write(fd, buffer, size); +} + +/** + * Receive CEC message. + * + * @param *buffer [in] pointer to buffer address where message will be stored. + * @param size [in] buffer size. + * @param timeout [in] timeout in microseconds. + * + * @return number of bytes received, or 0 if an arror occured. + */ +int CECReceiveMessage(unsigned char *buffer, int size, long timeout) +{ + int bytes = 0; + fd_set rfds; + struct timeval tv; + int retval; + + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + tv.tv_sec = 0; + tv.tv_usec = timeout; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + retval = select(fd + 1, &rfds, NULL, NULL, &tv); + + if (retval == -1) { + return 0; + } else if (retval) { + bytes = read(fd, buffer, size); +#if CEC_DEBUG + LOGI("CECReceiveMessage() : size(%d)", bytes); + if(bytes > 0) + CECPrintFrame(buffer, bytes); +#endif + } + + return bytes; +} + +/** + * Set CEC logical address. + * + * @return 1 if success, otherwise, return 0. + */ +int CECSetLogicalAddr(unsigned int laddr) +{ + if (ioctl(fd, CEC_IOC_SETLADDR, &laddr)) { + LOGE("ioctl(CEC_IOC_SETLA) failed!\n"); + return 0; + } + + return 1; +} + +#if CEC_DEBUG +/** + * Print CEC frame. + */ +void CECPrintFrame(unsigned char *buffer, unsigned int size) +{ + if (size > 0) { + int i; + LOGI("fsize: %d ", size); + LOGI("frame: "); + for (i = 0; i < size; i++) + LOGI("0x%02x ", buffer[i]); + + LOGI("\n"); + } +} +#endif + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param lsrc [in] buffer size. + * + * @return 1 if message should be ignored, otherwise, return 0. + */ +//TODO: not finished +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc) +{ + int retval = 0; + + /* if a message coming from address 15 (unregistered) */ + if (lsrc == CEC_LADDR_UNREGISTERED) { + switch (opcode) { + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + retval = 1; + default: + break; + } + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param size [in] message size. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageSize(unsigned char opcode, int size) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + if (size != 1) + retval = 0; + break; + case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE: + if (size != 2) + retval = 0; + break; + case CEC_OPCODE_PLAY: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + case CEC_OPCODE_ROUTING_INFORMATION: + case CEC_OPCODE_SET_STREAM_PATH: + if (size != 3) + retval = 0; + break; + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_DEVICE_VENDOR_ID: + case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS: + if (size != 4) + retval = 0; + break; + case CEC_OPCODE_ROUTING_CHANGE: + if (size != 5) + retval = 0; + break; + /* CDC - 1.4 */ + case 0xf8: + if (!(size > 5 && size <= 16)) + retval = 0; + break; + default: + break; + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param broadcast [in] broadcast/direct message. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageMode(unsigned char opcode, int broadcast) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + if (!broadcast) + retval = 0; + break; + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_ABORT: + if (broadcast) + retval = 0; + break; + default: + break; + } + + return retval; +} diff --git a/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.h b/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.h new file mode 100644 index 0000000..5bbfc15 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libcec/libcec.h @@ -0,0 +1,209 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBCEC_H_ +#define _LIBCEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Maximum CEC frame size */ +#define CEC_MAX_FRAME_SIZE 16 +/** Not valid CEC physical address */ +#define CEC_NOT_VALID_PHYSICAL_ADDRESS 0xFFFF + +/** CEC broadcast address (as destination address) */ +#define CEC_MSG_BROADCAST 0x0F +/** CEC unregistered address (as initiator address) */ +#define CEC_LADDR_UNREGISTERED 0x0F + +/* + * CEC Messages + */ + +//@{ +/** @name Messages for the One Touch Play Feature */ +#define CEC_OPCODE_ACTIVE_SOURCE 0x82 +#define CEC_OPCODE_IMAGE_VIEW_ON 0x04 +#define CEC_OPCODE_TEXT_VIEW_ON 0x0D +//@} + +//@{ +/** @name Messages for the Routing Control Feature */ +#define CEC_OPCODE_INACTIVE_SOURCE 0x9D +#define CEC_OPCODE_REQUEST_ACTIVE_SOURCE 0x85 +#define CEC_OPCODE_ROUTING_CHANGE 0x80 +#define CEC_OPCODE_ROUTING_INFORMATION 0x81 +#define CEC_OPCODE_SET_STREAM_PATH 0x86 +//@} + +//@{ +/** @name Messages for the Standby Feature */ +#define CEC_OPCODE_STANDBY 0x36 +//@} + +//@{ +/** @name Messages for the One Touch Record Feature */ +#define CEC_OPCODE_RECORD_OFF 0x0B +#define CEC_OPCODE_RECORD_ON 0x09 +#define CEC_OPCODE_RECORD_STATUS 0x0A +#define CEC_OPCODE_RECORD_TV_SCREEN 0x0F +//@} + +//@{ +/** @name Messages for the Timer Programming Feature */ +#define CEC_OPCODE_CLEAR_ANALOGUE_TIMER 0x33 +#define CEC_OPCODE_CLEAR_DIGITAL_TIMER 0x99 +#define CEC_OPCODE_CLEAR_EXTERNAL_TIMER 0xA1 +#define CEC_OPCODE_SET_ANALOGUE_TIMER 0x34 +#define CEC_OPCODE_SET_DIGITAL_TIMER 0x97 +#define CEC_OPCODE_SET_EXTERNAL_TIMER 0xA2 +#define CEC_OPCODE_SET_TIMER_PROGRAM_TITLE 0x67 +#define CEC_OPCODE_TIMER_CLEARED_STATUS 0x43 +#define CEC_OPCODE_TIMER_STATUS 0x35 +//@} + +//@{ +/** @name Messages for the System Information Feature */ +#define CEC_OPCODE_CEC_VERSION 0x9E +#define CEC_OPCODE_GET_CEC_VERSION 0x9F +#define CEC_OPCODE_GIVE_PHYSICAL_ADDRESS 0x83 +#define CEC_OPCODE_GET_MENU_LANGUAGE 0x91 +//#define CEC_OPCODE_POLLING_MESSAGE +#define CEC_OPCODE_REPORT_PHYSICAL_ADDRESS 0x84 +#define CEC_OPCODE_SET_MENU_LANGUAGE 0x32 +//@} + +//@{ +/** @name Messages for the Deck Control Feature */ +#define CEC_OPCODE_DECK_CONTROL 0x42 +#define CEC_OPCODE_DECK_STATUS 0x1B +#define CEC_OPCODE_GIVE_DECK_STATUS 0x1A +#define CEC_OPCODE_PLAY 0x41 +//@} + +//@{ +/** @name Messages for the Tuner Control Feature */ +#define CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS 0x08 +#define CEC_OPCODE_SELECT_ANALOGUE_SERVICE 0x92 +#define CEC_OPCODE_SELECT_DIGITAL_SERVICE 0x93 +#define CEC_OPCODE_TUNER_DEVICE_STATUS 0x07 +#define CEC_OPCODE_TUNER_STEP_DECREMENT 0x06 +#define CEC_OPCODE_TUNER_STEP_INCREMENT 0x05 +//@} + +//@{ +/** @name Messages for the Vendor Specific Commands Feature */ +#define CEC_OPCODE_DEVICE_VENDOR_ID 0x87 +#define CEC_OPCODE_GET_DEVICE_VENDOR_ID 0x8C +#define CEC_OPCODE_VENDOR_COMMAND 0x89 +#define CEC_OPCODE_VENDOR_COMMAND_WITH_ID 0xA0 +#define CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN 0x8A +#define CEC_OPCODE_VENDOR_REMOVE_BUTTON_UP 0x8B +//@} + +//@{ +/** @name Messages for the OSD Display Feature */ +#define CEC_OPCODE_SET_OSD_STRING 0x64 +//@} + +//@{ +/** @name Messages for the Device OSD Transfer Feature */ +#define CEC_OPCODE_GIVE_OSD_NAME 0x46 +#define CEC_OPCODE_SET_OSD_NAME 0x47 +//@} + +//@{ +/** @name Messages for the Device Menu Control Feature */ +#define CEC_OPCODE_MENU_REQUEST 0x8D +#define CEC_OPCODE_MENU_STATUS 0x8E +#define CEC_OPCODE_USER_CONTROL_PRESSED 0x44 +#define CEC_OPCODE_USER_CONTROL_RELEASED 0x45 +//@} + +//@{ +/** @name Messages for the Remote Control Passthrough Feature */ +//@} + +//@{ +/** @name Messages for the Power Status Feature */ +#define CEC_OPCODE_GIVE_DEVICE_POWER_STATUS 0x8F +#define CEC_OPCODE_REPORT_POWER_STATUS 0x90 +//@} + +//@{ +/** @name Messages for General Protocol messages */ +#define CEC_OPCODE_FEATURE_ABORT 0x00 +#define CEC_OPCODE_ABORT 0xFF +//@} + +//@{ +/** @name Messages for the System Audio Control Feature */ +#define CEC_OPCODE_GIVE_AUDIO_STATUS 0x71 +#define CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7D +#define CEC_OPCODE_REPORT_AUDIO_STATUS 0x7A +#define CEC_OPCODE_SET_SYSTEM_AUDIO_MODE 0x72 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST 0x70 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS 0x7E +//@} + +//@{ +/** @name Messages for the Audio Rate Control Feature */ +#define CEC_OPCODE_SET_AUDIO_RATE 0x9A +//@} + +//@{ +/** @name CEC Operands */ + +//TODO: not finished + +#define CEC_DECK_CONTROL_MODE_STOP 0x03 +#define CEC_PLAY_MODE_PLAY_FORWARD 0x24 +//@} + +/** + * @enum CECDeviceType + * Type of CEC device + */ +enum CECDeviceType { + /** TV */ + CEC_DEVICE_TV, + /** Recording Device */ + CEC_DEVICE_RECODER, + /** Tuner */ + CEC_DEVICE_TUNER, + /** Playback Device */ + CEC_DEVICE_PLAYER, + /** Audio System */ + CEC_DEVICE_AUDIO, +}; + +int CECOpen(); +int CECClose(); +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype); +int CECSendMessage(unsigned char *buffer, int size); +int CECReceiveMessage(unsigned char *buffer, int size, long timeout); + +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc); +int CECCheckMessageSize(unsigned char opcode, int size); +int CECCheckMessageMode(unsigned char opcode, int broadcast); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBCEC_H_ */ diff --git a/exynos4/hal/libhdmi/libsForhdmi/libddc/Android.mk b/exynos4/hal/libhdmi/libsForhdmi/libddc/Android.mk new file mode 100644 index 0000000..38891be --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libddc/Android.mk @@ -0,0 +1,45 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := libddc.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_7) +LOCAL_CFLAGS += -DDDC_CH_I2C_7 +endif + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_1) +LOCAL_CFLAGS += -DDDC_CH_I2C_1 +endif + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_2) +LOCAL_CFLAGS += -DDDC_CH_I2C_2 +endif + +LOCAL_MODULE := libddc +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.c b/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.c new file mode 100644 index 0000000..12910fb --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.c @@ -0,0 +1,285 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "i2c-dev.h" + +#include "libddc.h" + +#define DDC_DEBUG 0 + +/** + * @brief DDC device name. + * User should change this. + */ +#ifdef DDC_CH_I2C_1 +#define DEV_NAME "/dev/i2c-1" +#endif + +#ifdef DDC_CH_I2C_2 +#define DEV_NAME "/dev/i2c-2" +#endif + +#ifdef DDC_CH_I2C_7 +#define DEV_NAME "/dev/i2c-7" +#endif + +/** + * DDC file descriptor + */ +static int ddc_fd = -1; + +/** + * Reference count of DDC file descriptor + */ +static unsigned int ref_cnt = 0; + +/** + * Check if DDC file is already opened or not + * @return If DDC file is already opened, return 1; Otherwise, return 0. + */ +static int DDCFileAvailable() +{ + return (ddc_fd < 0) ? 0 : 1; +} + +/** + * Initialze DDC library. Open DDC device + * @return If succeed in opening DDC device or it is already opened, return 1;@n + * Otherwise, return 0. + */ +int DDCOpen() +{ + int ret = 1; + + // check already open?? + if (ref_cnt > 0) { + ref_cnt++; + return 1; + } + + // open + if ((ddc_fd = open(DEV_NAME,O_RDWR)) < 0) { + LOGE("%s: Cannot open I2C_DDC : %s",__func__, DEV_NAME); + ret = 0; + } + + ref_cnt++; + return ret; +} + +/** + * Finalize DDC library. Close DDC device + * @return If succeed in closing DDC device or it is being used yet, return 1;@n + * Otherwise, return 0. + */ +int DDCClose() +{ + int ret = 1; + // check if fd is available + if (ref_cnt == 0) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 1; + } + + // close + if (ref_cnt > 1) { + ref_cnt--; + return 1; + } + + if (close(ddc_fd) < 0) { +#if DDC_DEBUG + LOGE("%s: Cannot close I2C_DDC : %s",__func__,DEV_NAME); +#endif + ret = 0; + } + + ref_cnt--; + ddc_fd = -1; + + return ret; +} + +/** + * Read data though DDC. For more information of DDC, refer DDC Spec. + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to store data + * @return If succeed in reading, return 1; Otherwise, return 0. + */ +int DDCRead(unsigned char addr, unsigned char offset, + unsigned int size, unsigned char* buffer) +{ + struct i2c_rdwr_ioctl_data msgset; + struct i2c_msg msgs[2]; + int ret = 1; + + if (!DDCFileAvailable()) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 0; + } + + // set offset + msgs[0].addr = addr>>1; + msgs[0].flags = 0; + msgs[0].len = 1; + msgs[0].buf = &offset; + + // read data + msgs[1].addr = addr>>1; + msgs[1].flags = I2C_M_RD; + msgs[1].len = size; + msgs[1].buf = buffer; + + // set rdwr ioctl data + msgset.nmsgs = 2; + msgset.msgs = msgs; + + // i2c fast read + if ((ret = ioctl(ddc_fd, I2C_RDWR, &msgset)) < 0) { + perror("ddc error:"); + ret = 0; + } + + return ret; +} + +/** + * Read data though E-DDC. For more information of E-DDC, refer E-DDC Spec. + * @param segpointer [in] Segment pointer + * @param segment [in] Segment number + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to store data + * @return If succeed in reading, return 1; Otherwise, return 0. + */ + +int EDDCRead(unsigned char segpointer, unsigned char segment, unsigned char addr, + unsigned char offset, unsigned int size, unsigned char* buffer) +{ + struct i2c_rdwr_ioctl_data msgset; + struct i2c_msg msgs[3]; + int ret = 1; + + if (!DDCFileAvailable()) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 0; + } + + // set segment pointer + msgs[0].addr = segpointer>>1; + // ignore ack only if segment is "0" + if (segment == 0) + msgs[0].flags = I2C_M_IGNORE_NAK; + else + msgs[0].flags = 0; + + msgs[0].len = 1; + msgs[0].buf = &segment; + + // set offset + msgs[1].addr = addr>>1; + msgs[1].flags = 0; + msgs[1].len = 1; + msgs[1].buf = &offset; + + // read data + msgs[2].addr = addr>>1; + msgs[2].flags = I2C_M_RD; + msgs[2].len = size; + msgs[2].buf = buffer; + + msgset.nmsgs = 3; + msgset.msgs = msgs; + + // eddc read + if (ioctl(ddc_fd, I2C_RDWR, &msgset) < 0) { +#if DDC_DEBUG + LOGE("%s: ioctl(I2C_RDWR) failed!!!", __func__); +#endif + ret = 0; + } + return ret; +} + +/** + * Write data though DDC. For more information of DDC, refer DDC Spec. + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to write + * @return If succeed in writing, return 1; Otherwise, return 0. + */ +int DDCWrite(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer) +{ + unsigned char* temp; + int bytes; + int retval = 0; + + // allocate temporary buffer + temp = (unsigned char*) malloc((size+1)*sizeof(unsigned char)); + if (!temp) { + LOGE("%s: not enough resources at %s", __FUNCTION__); + goto exit; + } + + temp[0] = offset; + memcpy(temp+1,buffer,size); + + if (!DDCFileAvailable()) { + LOGE("%s: I2C_DDC is not available!!!!", __func__); + goto exit; + } + + if (ioctl(ddc_fd, I2C_SLAVE, addr>>1) < 0) { + LOGE("%s: cannot set slave address 0x%02x", __func__,addr); + goto exit; + } + + // write temp buffer + if ((bytes = write(ddc_fd,temp,size+1)) != (size+1)) { + LOGE("%s: fail to write %d bytes, only write %d bytes",__func__, size, bytes); + goto exit; + } + + retval = 1; + +exit: + // free temp buffer + if (temp) + free(temp); + + return retval; +} diff --git a/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.h b/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.h new file mode 100644 index 0000000..368855b --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libddc/libddc.h @@ -0,0 +1,35 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBDDC_H_ +#define _LIBDDC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int DDCOpen(); +int DDCRead(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer); +int DDCWrite(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer); +int EDDCRead(unsigned char segpointer, unsigned char segment, unsigned char addr, + unsigned char offset, unsigned int size, unsigned char* buffer); +int DDCClose(); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDDC_H_ */ diff --git a/exynos4/hal/libhdmi/libsForhdmi/libedid/Android.mk b/exynos4/hal/libhdmi/libsForhdmi/libedid/Android.mk new file mode 100644 index 0000000..602ae4d --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libedid/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) +LOCAL_SHARED_LIBRARIES := liblog libddc +LOCAL_SRC_FILES := libedid.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +LOCAL_MODULE := libedid +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libhdmi/libsForhdmi/libedid/edid.h b/exynos4/hal/libhdmi/libsForhdmi/libedid/edid.h new file mode 100644 index 0000000..aea1309 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libedid/edid.h @@ -0,0 +1,181 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _EDID_H_ +#define _EDID_H_ + +//@{ +/** + * @name EDID Addresses + */ +#define EDID_ADDR (0xA0) +#define EDID_SEGMENT_POINTER (0x60) +//@} + +//@{ +/** + * @name EDID offset and bit values + */ +#define SIZEOFBYTE (8) +#define SIZEOFEDIDBLOCK (0x80) +#define EDID_EXTENSION_NUMBER_POS (0x7E) + +#define EDID_TIMING_EXT_TAG_ADDR_POS (0) +#define EDID_TIMING_EXT_REV_NUMBER_POS (1) +#define EDID_DETAILED_TIMING_OFFSET_POS (2) +#define EDID_DATA_BLOCK_START_POS (4) + +// for Extension Data Block +#define EDID_TIMING_EXT_TAG_VAL (0x02) +#define EDID_BLOCK_MAP_EXT_TAG_VAL (0xF0) + +#define EDID_SHORT_AUD_DEC_TAG_VAL (1<<5) +#define EDID_SHORT_VID_DEC_TAG_VAL (2<<5) +#define EDID_VSDB_TAG_VAL (3<<5) +#define EDID_SPEAKER_ALLOCATION_TAG_VAL (4<<5) +#define EDID_VESA_DTC_TAG_VAL (5<<5) +#define EDID_RESERVED_TAG_VAL (6<<5) + +#define EDID_EXTENDED_TAG_VAL (7<<5) +#define EDID_EXTENDED_COLORIMETRY_VAL (5) +#define EDID_EXTENDED_COLORIMETRY_BLOCK_LEN (3) + +#define EDID_TAG_CODE_MASK (1<<7 | 1<<6 | 1<<5) +#define EDID_DATA_BLOCK_SIZE_MASK (1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0) + +#define EDID_VSDB_MIN_LENGTH_VAL (5) + +// for Established Timings +#define EDID_ET_POS (0x23) +#define EDID_ET_640x480p_VAL (0x20) + +// for DTD +#define EDID_DTD_START_ADDR (0x36) +#define EDID_DTD_BYTE_LENGTH (18) +#define EDID_DTD_TOTAL_LENGTH (EDID_DTD_BYTE_LENGTH*4) + +#define EDID_DTD_PIXELCLOCK_POS1 (0) +#define EDID_DTD_PIXELCLOCK_POS2 (1) + +#define EDID_DTD_HBLANK_POS1 (3) +#define EDID_DTD_HBLANK_POS2 (4) +#define EDID_DTD_HBLANK_POS2_MASK (0xF) + +#define EDID_DTD_HACTIVE_POS1 (2) +#define EDID_DTD_HACTIVE_POS2 (4) +#define EDID_DTD_HACTIVE_POS2_MASK (0xF0) + +#define EDID_DTD_VBLANK_POS1 (6) +#define EDID_DTD_VBLANK_POS2 (7) +#define EDID_DTD_VBLANK_POS2_MASK (0x0F) + +#define EDID_DTD_VACTIVE_POS1 (5) +#define EDID_DTD_VACTIVE_POS2 (7) +#define EDID_DTD_VACTIVE_POS2_MASK (0xF0) + +#define EDID_DTD_INTERLACE_POS (17) +#define EDID_DTD_INTERLACE_MASK (1<<7) + +// for SVD +#define EDID_SVD_VIC_MASK (0x7F) + +// for CS +#define EDID_COLOR_SPACE_POS (3) +#define EDID_YCBCR444_CS_MASK (1<<5) +#define EDID_YCBCR422_CS_MASK (1<<4) + +// for Color Depth +#define EDID_DC_48_VAL (1<<6) +#define EDID_DC_36_VAL (1<<5) +#define EDID_DC_30_VAL (1<<4) +#define EDID_DC_YCBCR_VAL (1<<3) + +#define EDID_DC_POS (6) +#define EDID_DC_MASK (EDID_DC_48_VAL | EDID_DC_36_VAL| EDID_DC_30_VAL | EDID_DC_YCBCR_VAL) + +// for colorimetry +#define EDID_XVYCC601_MASK (1<<0) +#define EDID_XVYCC709_MASK (1<<1) +#define EDID_EXTENDED_MASK (1<<0|1<<1|1<<2) + +// for SAD +#define SHORT_AUD_DESCRIPTOR_LPCM (1<<0) +#define SHORT_AUD_DESCRIPTOR_AC3 (1<<1) +#define SHORT_AUD_DESCRIPTOR_MPEG1 (1<<2) +#define SHORT_AUD_DESCRIPTOR_MP3 (1<<3) +#define SHORT_AUD_DESCRIPTOR_MPEG2 (1<<4) +#define SHORT_AUD_DESCRIPTOR_AAC (1<<5) +#define SHORT_AUD_DESCRIPTOR_DTS (1<<6) +#define SHORT_AUD_DESCRIPTOR_ATRAC (1<<7) + +#define EDID_SAD_CODE_MASK (1<<6 | 1<<5 | 1<<4 | 1<<3) +#define EDID_SAD_CHANNEL_MASK (1<<2 | 1<<1 | 1<<0) +#define EDID_SAD_192KHZ_MASK (1<<6) +#define EDID_SAD_176KHZ_MASK (1<<5) +#define EDID_SAD_96KHZ_MASK (1<<4) +#define EDID_SAD_88KHZ_MASK (1<<3) +#define EDID_SAD_48KHZ_MASK (1<<2) +#define EDID_SAD_44KHZ_MASK (1<<1) +#define EDID_SAD_32KHZ_MASK (1<<0) + +#define EDID_SAD_WORD_24_MASK (1<<2) +#define EDID_SAD_WORD_20_MASK (1<<1) +#define EDID_SAD_WORD_16_MASK (1<<0) + +// for CEC +#define EDID_CEC_PHYICAL_ADDR (4) + +// for 3D +#define EDID_HDMI_EXT_POS (8) +#define EDID_HDMI_VIDEO_PRESENT_MASK (1<<5) + +// latency +#define EDID_HDMI_LATENCY_MASK (1<<7|1<<6) +#define EDID_HDMI_LATENCY_POS (6) + +#define EDID_HDMI_3D_PRESENT_POS (13) +#define EDID_HDMI_3D_PRESENT_MASK (1<<7) +#define EDID_HDMI_3D_MULTI_PRESENT_MASK (1<<6 | 1<<5) +#define EDID_HDMI_3D_MULTI_PRESENT_BIT 5 + +#define EDID_3D_STRUCTURE_ONLY_EXIST (1<<5) +#define EDID_3D_STRUCTURE_MASK_EXIST (1<<6) + +#define EDID_3D_STRUCTURE_FP (0) +#define EDID_3D_STRUCTURE_FA (1) +#define EDID_3D_STRUCTURE_LA (2) +#define EDID_3D_STRUCTURE_SSF (3) +#define EDID_3D_STRUCTURE_LD (4) +#define EDID_3D_STRUCTURE_LDGFX (5) +#define EDID_3D_STRUCTURE_TB (6) +#define EDID_3D_STRUCTURE_SSH (8) + +#define EDID_HDMI_EXT_LENGTH_POS (14) +#define EDID_HDMI_VSDB_VIC_LEN_BIT (5) +#define EDID_HDMI_VSDB_VIC_LEN_MASK (1<<7|1<<6|1<<5) +#define EDID_HDMI_VSDB_3D_LEN_MASK (1<<4|1<<3|1<<2|1<<1|1<<0) + +#define EDID_HDMI_2D_VIC_ORDER_MASK (1<<7|1<<6|1<<5|1<<4) +#define EDID_HDMI_3D_STRUCTURE_MASK (1<<3|1<<2|1<<1|1<<0) + +// for MAX TMDS +#define EDID_MAX_TMDS_POS (7) + +// for 3D Structure +#define NUM_OF_VIC_FOR_3D 16 +//@} + +#endif /* _EDID_H_ */ diff --git a/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.c b/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.c new file mode 100644 index 0000000..c4af587 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.c @@ -0,0 +1,1262 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include + +#include + +#include "edid.h" +#include "libedid.h" +#include "../libddc/libddc.h" + +//#define EDID_DEBUG 1 + +#ifdef EDID_DEBUG +#define DPRINTF(args...) LOGI(args) +#else +#define DPRINTF(args...) +#endif + +#define NUM_OF_VIC_FOR_3D 16 + +/** + * @var gEdidData + * Pointer to EDID data + */ +static unsigned char* gEdidData; + +/** + * @var gExtensions + * Number of EDID extensions + */ +static int gExtensions; + + +/** + * @var aVIC + * This contains first 16 VIC in EDID + */ +static unsigned char aVIC[NUM_OF_VIC_FOR_3D]; + +//! Structure for parsing video timing parameter in EDID +static const struct edid_params { + /** H Total */ + unsigned int HTotal; + + /** H Blank */ + unsigned int HBlank; + + /** V Total */ + unsigned int VTotal; + + /** V Blank */ + unsigned int VBlank; + + /** CEA VIC */ + unsigned char VIC; + + /** CEA VIC for 16:9 aspect ratio */ + unsigned char VIC16_9; + + /** 0 if progressive, 1 if interlaced */ + unsigned char interlaced; + + /** Pixel frequency */ + enum PixelFreq PixelClock; +} aVideoParams[] = +{ + { 800 , 160 , 525 , 45, 1 , 1 , 0, PIXEL_FREQ_25_200 ,}, // v640x480p_60Hz + { 858 , 138 , 525 , 45, 2 , 3 , 0, PIXEL_FREQ_27_027 ,}, // v720x480p_60Hz + { 1650, 370 , 750 , 30, 4 , 4 , 0, PIXEL_FREQ_74_250 ,}, // v1280x720p_60Hz + { 2200, 280 , 1125, 22, 5 , 5 , 1, PIXEL_FREQ_74_250 ,}, // v1920x1080i_60H + { 1716, 276 , 525 , 22, 6 , 7 , 1, PIXEL_FREQ_74_250 ,}, // v720x480i_60Hz + { 1716, 276 , 262 , 22, 8 , 9 , 0, PIXEL_FREQ_27_027 ,}, // v720x240p_60Hz + //{ 1716, 276 , 263 , 23, 8 , 9 , 0, PIXEL_FREQ_27_027 , }, // v720x240p_60Hz(mode 2) + { 3432, 552 , 525 , 22, 10, 11, 1, PIXEL_FREQ_54_054 , }, // v2880x480i_60Hz + { 3432, 552 , 262 , 22, 12, 13, 0, PIXEL_FREQ_54_054 , }, // v2880x240p_60Hz + //{ 3432, 552 , 263 , 23, 12, 13, 0, PIXEL_FREQ_54_054 , }, // v2880x240p_60Hz(mode 2) + { 1716, 276 , 525 , 45, 14, 15, 0, PIXEL_FREQ_54_054 , }, // v1440x480p_60Hz + { 2200, 280 , 1125, 45, 16, 16, 0, PIXEL_FREQ_148_500, }, // v1920x1080p_60H + { 864 , 144 , 625 , 49, 17, 18, 0, PIXEL_FREQ_27 , }, // v720x576p_50Hz + { 1980, 700 , 750 , 30, 19, 19, 0, PIXEL_FREQ_74_250 , }, // v1280x720p_50Hz + { 2640, 720 , 1125, 22, 20, 20, 1, PIXEL_FREQ_74_250 , }, // v1920x1080i_50H + { 1728, 288 , 625 , 24, 21, 22, 1, PIXEL_FREQ_27 , }, // v720x576i_50Hz + { 1728, 288 , 312 , 24, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz + //{ 1728, 288 , 313 , 25, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz(mode 2) + //{ 1728, 288 , 314 , 26, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz(mode 3) + { 3456, 576 , 625 , 24, 25, 26, 1, PIXEL_FREQ_54 , }, // v2880x576i_50Hz + { 3456, 576 , 312 , 24, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz + //{ 3456, 576 , 313 , 25, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz(mode 2) + //{ 3456, 576 , 314 , 26, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz(mode 3) + { 1728, 288 , 625 , 49, 29, 30, 0, PIXEL_FREQ_54 , }, // v1440x576p_50Hz + { 2640, 720 , 1125, 45, 31, 31, 0, PIXEL_FREQ_148_500,}, // v1920x1080p_50Hz + { 2750, 830 , 1125, 45, 32, 32, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_24Hz + { 2640, 720 , 1125, 45, 33, 33, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_25Hz + { 2200, 280 , 1125, 45, 34, 34, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_30Hz + { 3432, 552 , 525 , 45, 35, 36, 0, PIXEL_FREQ_108_108,}, // v2880x480p_60Hz + { 3456, 576 , 625 , 49, 37, 38, 0, PIXEL_FREQ_108 ,}, // v2880x576p_50Hz + { 2304, 384 , 1250, 85, 39, 39, 1, PIXEL_FREQ_72 ,}, // v1920x1080i_50Hz(1250) + { 2640, 720 , 1125, 22, 40, 40, 1, PIXEL_FREQ_148_500, }, // v1920x1080i_100Hz + { 1980, 700 , 750 , 30, 41, 41, 0, PIXEL_FREQ_148_500, }, // v1280x720p_100Hz + { 864 , 144 , 625 , 49, 42, 43, 0, PIXEL_FREQ_54 , }, // v720x576p_100Hz + { 1728, 288 , 625 , 24, 44, 45, 1, PIXEL_FREQ_54 , }, // v720x576i_100Hz + { 2200, 280 , 1125, 22, 46, 46, 1, PIXEL_FREQ_148_500, }, // v1920x1080i_120Hz + { 1650, 370 , 750 , 30, 47, 47, 0, PIXEL_FREQ_148_500, }, // v1280x720p_120Hz + { 858 , 138 , 525 , 54, 48, 49, 0, PIXEL_FREQ_54_054 , }, // v720x480p_120Hz + { 1716, 276 , 525 , 22, 50, 51, 1, PIXEL_FREQ_54_054 , }, // v720x480i_120Hz + { 864 , 144 , 625 , 49, 52, 53, 0, PIXEL_FREQ_108 , }, // v720x576p_200Hz + { 1728, 288 , 625 , 24, 54, 55, 1, PIXEL_FREQ_108 , }, // v720x576i_200Hz + { 858 , 138 , 525 , 45, 56, 57, 0, PIXEL_FREQ_108_108, }, // v720x480p_240Hz + { 1716, 276 , 525 , 22, 58, 59, 1, PIXEL_FREQ_108_108, }, // v720x480i_240Hz + // PHY Freq is not available yet + //{ 3300, 2020, 750 , 30, 60, 60, 0, PIXEL_FREQ_59_400 ,}, // v1280x720p24Hz + { 3960, 2680, 750 , 30, 61, 61, 0, PIXEL_FREQ_74_250 , }, // v1280x720p25Hz + { 3300, 2020, 750 , 30, 62, 62, 0, PIXEL_FREQ_74_250 ,}, // v1280x720p30Hz + // PHY Freq is not available yet + //{ 2200, 280 , 1125, 45, 63, 63, 0, PIXEL_FREQ_297, }, // v1920x1080p120Hz + //{ 2640, 720 , 1125, 45, 64, 64, 0, PIXEL_FREQ_297, }, // v1920x1080p100Hz + //{ 4400, 560 , 2250, 90, 1, 1, 0, 0, PIXEL_FREQ_297, }, // v4Kx2K30Hz +}; + +//! Structure for Checking 3D Mandatory Format in EDID +static const struct edid_3d_mandatory { + /** video Format */ + enum VideoFormat resolution; + + /** 3D Structure */ + enum HDMI3DVideoStructure hdmi_3d_format; +} edid_3d [] = +{ + { v1920x1080p_24Hz, HDMI_3D_FP_FORMAT }, // 1920x1080p @ 23.98/24Hz + { v1280x720p_60Hz, HDMI_3D_FP_FORMAT }, // 1280x720p @ 59.94/60Hz + { v1920x1080i_60Hz, HDMI_3D_SSH_FORMAT }, // 1920x1080i @ 59.94/60Hz + { v1920x1080p_24Hz, HDMI_3D_TB_FORMAT }, // 1920x1080p @ 23.98/24Hz + { v1280x720p_60Hz, HDMI_3D_TB_FORMAT }, // 1280x720p @ 59.94/60Hz + { v1280x720p_50Hz, HDMI_3D_FP_FORMAT }, // 1280x720p @ 50Hz + { v1920x1080i_50Hz, HDMI_3D_SSH_FORMAT }, // 1920x1080i @ 50Hz + { v1280x720p_50Hz, HDMI_3D_TB_FORMAT }, // 1280x720p @ 50Hz +}; + +/** + * Calculate a checksum. + * + * @param buffer [in] Pointer to data to calculate a checksum + * @param size [in] Sizes of data + * + * @return If checksum result is 0, return 1; Otherwise, return 0. + */ +static int CalcChecksum(const unsigned char* const buffer, const int size) +{ + unsigned char i,sum; + int ret = 1; + + // check parameter + if (buffer == NULL ) { + DPRINTF("invalid parameter : buffer\n"); + return 0; + } + for (sum = 0, i = 0 ; i < size; i++) + sum += buffer[i]; + + // check checksum + if (sum != 0) + ret = 0; + + return ret; +} + +/** + * Read EDID Block(128 bytes) + * + * @param blockNum [in] Number of block to read @n + * For example, EDID block = 0, EDID first Extension = 1, and so on. + * @param outBuffer [out] Pointer to buffer to store EDID data + * + * @return If fail to read, return 0; Otherwise, return 1. + */ +static int ReadEDIDBlock(const unsigned int blockNum, unsigned char* const outBuffer) +{ + int segNum, offset, dataPtr; + + // check parameter + if (outBuffer == NULL) { + DPRINTF("invalid parameter : outBuffer\n"); + return 0; + } + + // calculate + segNum = blockNum / 2; + offset = (blockNum % 2) * SIZEOFEDIDBLOCK; + dataPtr = (blockNum) * SIZEOFEDIDBLOCK; + + // read block + if (!EDDCRead(EDID_SEGMENT_POINTER, segNum, EDID_ADDR, offset, SIZEOFEDIDBLOCK, outBuffer)) { + DPRINTF("Fail to Read %dth EDID Block\n", blockNum); + return 0; + } + + if (!CalcChecksum(outBuffer, SIZEOFEDIDBLOCK)) { + DPRINTF("CheckSum fail : %dth EDID Block\n", blockNum); + return 0; + } + + // print data +#ifdef EDID_DEBUG + offset = 0; + do { + LOGI("0x%02X", outBuffer[offset++]); + if (offset % 16) + LOGI(" "); + else + LOGI("\n"); + } while (SIZEOFEDIDBLOCK > offset); +#endif // EDID_DEBUG + return 1; +} + +/** + * Check if EDID data is valid or not. + * + * @return if EDID data is valid, return 1; Otherwise, return 0. + */ +static inline int EDIDValid(void) +{ + return (gEdidData == NULL) ? 0 : 1; +} + +/** + * Search HDMI Vender Specific Data Block(VSDB) in EDID extension block. + * + * @param extension [in] the number of EDID extension block to check + * + * @return if there is a HDMI VSDB, return the offset from start of @n + * EDID extension block. if there is no VSDB, return 0. + */ +static int GetVSDBOffset(const int extension) +{ + unsigned int BlockOffset = extension*SIZEOFEDIDBLOCK; + unsigned int offset = BlockOffset + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen,DTDOffset; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + DTDOffset = gEdidData[BlockOffset + EDID_DETAILED_TIMING_OFFSET_POS]; + + // check if there is HDMI VSDB + while (offset < BlockOffset + DTDOffset) { + // find the block tag and length + // tag + tag = gEdidData[offset] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[offset] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is HDMI VSDB + // if so, check identifier value, if it's hdmi vsbd - return offset + if (tag == EDID_VSDB_TAG_VAL && + gEdidData[offset+1] == 0x03 && + gEdidData[offset+2] == 0x0C && + gEdidData[offset+3] == 0x0 && + blockLen > EDID_VSDB_MIN_LENGTH_VAL ) + return offset; + + // else find next block + offset += blockLen; + } + + // return error + return 0; +} + +/** + * Check if Sink supports the HDMI mode. + * @return If Sink supports HDMI mode, return 1; Otherwise, return 0. + */ +static int CheckHDMIMode(void) +{ + int i; + + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) + if (GetVSDBOffset(i) > 0) // if there is a VSDB, it means RX support HDMI mode + return 1; + + return 0; +} + +/** + * Check if EDID extension block is timing extension block or not. + * @param extension [in] The number of EDID extension block to check + * @return If the block is timing extension, return 1; Otherwise, return 0. + */ +static int IsTimingExtension(const int extension) +{ + int ret = 0; + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return ret; + } + + if (gEdidData[extension*SIZEOFEDIDBLOCK] == EDID_TIMING_EXT_TAG_VAL) { + // check extension revsion number + // revision num == 3 + if (gEdidData[extension*SIZEOFEDIDBLOCK + EDID_TIMING_EXT_REV_NUMBER_POS] == 3) + ret = 1; + // revison num != 3 && DVI mode + else if (!CheckHDMIMode() && + gEdidData[extension*SIZEOFEDIDBLOCK + EDID_TIMING_EXT_REV_NUMBER_POS] != 2) + ret = 1; + } + return ret; +} + +/** + * Check if the video format is contained in - @n + * Detailed Timing Descriptor(DTD) of EDID extension block. + * @param extension [in] Number of EDID extension block to check + * @param videoFormat [in] Video format to check + * @return If the video format is contained in DTD of EDID extension block, -@n + * return 1; Otherwise, return 0. + */ +static int IsContainVideoDTD(const int extension,const enum VideoFormat videoFormat) +{ + int i, StartOffset, EndOffset; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + // if edid block( 0th block ) + if (extension == 0) { + StartOffset = EDID_DTD_START_ADDR; + EndOffset = StartOffset + EDID_DTD_TOTAL_LENGTH; + } else { // if edid extension block + StartOffset = extension*SIZEOFEDIDBLOCK + gEdidData[extension*SIZEOFEDIDBLOCK + EDID_DETAILED_TIMING_OFFSET_POS]; + EndOffset = (extension+1)*SIZEOFEDIDBLOCK; + } + + // check DTD(Detailed Timing Description) + for (i = StartOffset; i < EndOffset; i+= EDID_DTD_BYTE_LENGTH) { + unsigned int hblank = 0, hactive = 0, vblank = 0, vactive = 0, interlaced = 0, pixelclock = 0; + unsigned int vHActive = 0, vVActive = 0, vVBlank = 0; + + // get pixel clock + pixelclock = (gEdidData[i+EDID_DTD_PIXELCLOCK_POS2] << SIZEOFBYTE); + pixelclock |= gEdidData[i+EDID_DTD_PIXELCLOCK_POS1]; + + if (!pixelclock) + continue; + + // get HBLANK value in pixels + hblank = gEdidData[i+EDID_DTD_HBLANK_POS2] & EDID_DTD_HBLANK_POS2_MASK; + hblank <<= SIZEOFBYTE; // lower 4 bits + hblank |= gEdidData[i+EDID_DTD_HBLANK_POS1]; + + // get HACTIVE value in pixels + hactive = gEdidData[i+EDID_DTD_HACTIVE_POS2] & EDID_DTD_HACTIVE_POS2_MASK; + hactive <<= (SIZEOFBYTE/2); // upper 4 bits + hactive |= gEdidData[i+EDID_DTD_HACTIVE_POS1]; + + // get VBLANK value in pixels + vblank = gEdidData[i+EDID_DTD_VBLANK_POS2] & EDID_DTD_VBLANK_POS2_MASK; + vblank <<= SIZEOFBYTE; // lower 4 bits + vblank |= gEdidData[i+EDID_DTD_VBLANK_POS1]; + + // get VACTIVE value in pixels + vactive = gEdidData[i+EDID_DTD_VACTIVE_POS2] & EDID_DTD_VACTIVE_POS2_MASK; + vactive <<= (SIZEOFBYTE/2); // upper 4 bits + vactive |= gEdidData[i+EDID_DTD_VACTIVE_POS1]; + + vHActive = aVideoParams[videoFormat].HTotal - aVideoParams[videoFormat].HBlank; + if (aVideoParams[videoFormat].interlaced == 1) { + if (aVideoParams[videoFormat].VIC == v1920x1080i_50Hz_1250) { // VTOP and VBOT are same + vVActive = (aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank*2)/2; + vVBlank = aVideoParams[videoFormat].VBlank; + } else { + vVActive = (aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank*2 - 1)/2; + vVBlank = aVideoParams[videoFormat].VBlank; + } + } else { + vVActive = aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank; + vVBlank = aVideoParams[videoFormat].VBlank; + } + + // get Interlaced Mode Value + interlaced = (int)(gEdidData[i+EDID_DTD_INTERLACE_POS] & EDID_DTD_INTERLACE_MASK); + if (interlaced) + interlaced = 1; + + DPRINTF("EDID: hblank = %d,vblank = %d, hactive = %d, vactive = %d\n" + ,hblank,vblank,hactive,vactive); + DPRINTF("REQ: hblank = %d,vblank = %d, hactive = %d, vactive = %d\n" + ,aVideoParams[videoFormat].HBlank + ,vVBlank,vHActive,vVActive); + + if (hblank == aVideoParams[videoFormat].HBlank && vblank == vVBlank // blank + && hactive == vHActive && vactive == vVActive) { //line + unsigned int EDIDpixelclock = aVideoParams[videoFormat].PixelClock; + EDIDpixelclock /= 100; pixelclock /= 100; + + if (pixelclock == EDIDpixelclock) { + DPRINTF("Sink Support the Video mode\n"); + return 1; + } + } + } + return 0; +} + +/** + * Check if a VIC(Video Identification Code) is contained in -@n + * EDID extension block. + * @param extension [in] Number of EDID extension block to check + * @param VIC [in] VIC to check + * @return If the VIC is contained in contained in EDID extension block, -@n + * return 1; Otherwise, return 0. + */ +static int IsContainVIC(const int extension, const int VIC) +{ + unsigned int StartAddr = extension*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + // while + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + DPRINTF("tag = %d\n",tag); + DPRINTF("blockLen = %d\n",blockLen-1); + + // check if it is short video description + if (tag == EDID_SHORT_VID_DEC_TAG_VAL) { + // if so, check SVD + unsigned int i; + for (i = 1; i < blockLen; i++) { + DPRINTF("EDIDVIC = %d\n",gEdidData[ExtAddr+i] & EDID_SVD_VIC_MASK); + DPRINTF("VIC = %d\n",VIC); + + // check VIC with SVDB + if (VIC == (gEdidData[ExtAddr+i] & EDID_SVD_VIC_MASK)) { + DPRINTF("Sink Device supports requested video mode\n"); + return 1; + } + } + } + // else find next block + ExtAddr += blockLen; + } + + return 0; +} + +/** + * Check if EDID contains the video format. + * @param videoFormat [in] Video format to check + * @param pixelRatio [in] Pixel aspect ratio of video format to check + * @return if EDID contains the video format, return 1; Otherwise, return 0. + */ +static int CheckResolution(const enum VideoFormat videoFormat, + const enum PixelAspectRatio pixelRatio) +{ + int i, vic; + + // read EDID + if (!EDIDRead()) + return 0; + + // check ET(Established Timings) for 640x480p@60Hz + if (videoFormat == v640x480p_60Hz // if it's 640x480p@60Hz + && (gEdidData[EDID_ET_POS] & EDID_ET_640x480p_VAL)) // it support + return 1; + + // check STI(Standard Timing Identification) + // do not need + + // check DTD(Detailed Timing Description) of EDID block(0th) + if (IsContainVideoDTD(0,videoFormat)) + return 1; + + // check EDID Extension + vic = (pixelRatio == HDMI_PIXEL_RATIO_16_9) ? + aVideoParams[videoFormat].VIC16_9 : aVideoParams[videoFormat].VIC; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) // if it's timing block + if (IsContainVIC(i, vic) || IsContainVideoDTD(i, videoFormat)) + return 1; + } + + return 0; +} + +/** + * Check if EDID supports the color depth. + * @param depth [in] Color depth + * @param space [in] Color space + * @return If EDID supports the color depth, return 1; Otherwise, return 0. + */ +static int CheckColorDepth(const enum ColorDepth depth,const enum ColorSpace space) +{ + int i; + unsigned int StartAddr; + + // if color depth == 24 bit, no need to check + if (depth == HDMI_CD_24) + return 1; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && ((StartAddr = GetVSDBOffset(i)) > 0)) { // check block + int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + if (blockLength >= EDID_DC_POS) { + // get supported DC value + int deepColor = gEdidData[StartAddr + EDID_DC_POS] & EDID_DC_MASK; + DPRINTF("EDID deepColor = %x\n",deepColor); + // check supported DeepColor + // if YCBCR444 + if (space == HDMI_CS_YCBCR444) { + if ( !(deepColor & EDID_DC_YCBCR_VAL)) + return 0; + } + + // check colorDepth + switch (depth) { + case HDMI_CD_36: + deepColor &= EDID_DC_36_VAL; + break; + case HDMI_CD_30: + deepColor &= EDID_DC_30_VAL; + break; + default : + deepColor = 0; + } + if (deepColor) + return 1; + else + return 0; + } + } + } + + return 0; +} + +/** + * Check if EDID supports the color space. + * @param space [in] Color space + * @return If EDID supports the color space, return 1; Otherwise, return 0. + */ +static int CheckColorSpace(const enum ColorSpace space) +{ + int i; + + // RGB is default + if (space == HDMI_CS_RGB) + return 1; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // read Color Space + int CS = gEdidData[i*SIZEOFEDIDBLOCK + EDID_COLOR_SPACE_POS]; + + if ((space == HDMI_CS_YCBCR444 && (CS & EDID_YCBCR444_CS_MASK)) || // YCBCR444 + (space == HDMI_CS_YCBCR422 && (CS & EDID_YCBCR422_CS_MASK))) // YCBCR422 + return 1; + } + } + return 0; +} + +/** + * Check if EDID supports the colorimetry. + * @param color [in] Colorimetry + * @return If EDID supports the colorimetry, return 1; Otherwise, return 0. + */ +static int CheckColorimetry(const enum HDMIColorimetry color) +{ + int i; + + // do not need to parse if not extended colorimetry + if (color == HDMI_COLORIMETRY_NO_DATA || + color == HDMI_COLORIMETRY_ITU601 || + color == HDMI_COLORIMETRY_ITU709) + return 1; + + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // check address + unsigned int ExtAddr = i*SIZEOFEDIDBLOCK + EDID_DATA_BLOCK_START_POS; + unsigned int EndAddr = i*SIZEOFEDIDBLOCK + gEdidData[i*SIZEOFEDIDBLOCK + EDID_DETAILED_TIMING_OFFSET_POS]; + unsigned int tag,blockLen; + + while (ExtAddr < EndAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is colorimetry block + if (tag == EDID_EXTENDED_TAG_VAL && // extended tag + gEdidData[ExtAddr+1] == EDID_EXTENDED_COLORIMETRY_VAL && // colorimetry block + (blockLen-1) == EDID_EXTENDED_COLORIMETRY_BLOCK_LEN) { // check length + // get supported DC value + int colorimetry = (gEdidData[ExtAddr + 2]); + int metadata = (gEdidData[ExtAddr + 3]); + + DPRINTF("EDID extened colorimetry = %x\n",colorimetry); + DPRINTF("EDID gamut metadata profile = %x\n",metadata); + + // check colorDepth + switch (color) { + case HDMI_COLORIMETRY_EXTENDED_xvYCC601: + if (colorimetry & EDID_XVYCC601_MASK && metadata) + return 1; + break; + case HDMI_COLORIMETRY_EXTENDED_xvYCC709: + if (colorimetry & EDID_XVYCC709_MASK && metadata) + return 1; + break; + default: + break; + } + return 0; + } + // else find next block + ExtAddr += blockLen; + } + } + } + + return 0; +} + +/** + * Get Max TMDS clock that HDMI Rx can receive. + * @return If available, return MaxTMDS clock; Otherwise, return 0. + */ +static unsigned int GetMaxTMDS(void) +{ + int i; + unsigned int StartAddr; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && ((StartAddr = GetVSDBOffset(i)) > 0)) { // check block + int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + if (blockLength >= EDID_MAX_TMDS_POS) { + // get supported DC value + return gEdidData[StartAddr + EDID_MAX_TMDS_POS]; + } + } + } + + return 0; +} + +/** + * Save first 16 VIC of EDID + */ +static void SaveVIC(void) +{ + int extension; + int vic_count = 0; + for (extension = 1; extension <= gExtensions && vic_count < NUM_OF_VIC_FOR_3D; extension++) { + unsigned int StartAddr = extension*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is short video description + if (tag == EDID_SHORT_VID_DEC_TAG_VAL) { + // if so, check SVD + unsigned int edid_index; + for (edid_index = 1; edid_index < blockLen && vic_count < NUM_OF_VIC_FOR_3D; edid_index++) { + DPRINTF("EDIDVIC = %d\r\n", gEdidData[ExtAddr+edid_index] & EDID_SVD_VIC_MASK); + + // check VIC with SVDB + aVIC[vic_count++] = (gEdidData[ExtAddr+edid_index] & EDID_SVD_VIC_MASK); + } + } + // else find next block + ExtAddr += blockLen; + } + } +} + +/** + * Check if Rx supports requested 3D format. + * @param pVideo [in] HDMI Video Parameter + * @return If Rx supports requested 3D format, return 1; Otherwise, return 0. + */ +static int EDID3DFormatSupport(const struct HDMIVideoParameter * const pVideo) +{ + int edid_index; + unsigned int StartAddr; + unsigned int vic; + vic = (pVideo->pixelAspectRatio == HDMI_PIXEL_RATIO_16_9) ? + aVideoParams[pVideo->resolution].VIC16_9 : aVideoParams[pVideo->resolution].VIC; + + // if format == 2D, no need to check + if (pVideo->hdmi_3d_format == HDMI_2D_VIDEO_FORMAT) + return 1; + + // check EDID data is valid or not + if (!EDIDRead()) + return 0; + + // save first 16 VIC to check + SaveVIC(); + + // find VSDB + for (edid_index = 1; edid_index <= gExtensions; edid_index++) { + if (IsTimingExtension(edid_index) // if it's timing block + && ((StartAddr = GetVSDBOffset(edid_index)) > 0)) { // check block + unsigned int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + unsigned int VSDBHdmiVideoPre = 0; + unsigned int VSDB3DPresent = 0; + unsigned int VSDB3DMultiPresent = 0; + unsigned int HDMIVICLen; + unsigned int HDMI3DLen; + int Hdmi3DStructure = 0; + unsigned int Hdmi3DMask = 0xFFFF; + unsigned int latency_offset = 0; + + DPRINTF("VSDB Block length[0x%x] = 0x%x\r\n",StartAddr,blockLength); + + // get HDMI Video Present value + if (blockLength >= EDID_HDMI_EXT_POS) { + VSDBHdmiVideoPre = gEdidData[StartAddr + EDID_HDMI_EXT_POS] + & EDID_HDMI_VIDEO_PRESENT_MASK; + DPRINTF("EDID HDMI Video Present = 0x%x\n",VSDBHdmiVideoPre); + } else { // data related to 3D format is not available + return 0; + } + + // check if latency field is available + latency_offset = (gEdidData[StartAddr + EDID_HDMI_EXT_POS] + & EDID_HDMI_LATENCY_MASK) >> EDID_HDMI_LATENCY_POS; + if (latency_offset == 0) + latency_offset = 4; + else if (latency_offset == 3) + latency_offset = 0; + else + latency_offset = 2; + + StartAddr -= latency_offset; + + // HDMI_VIC_LEN + HDMIVICLen = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS] + & EDID_HDMI_VSDB_VIC_LEN_MASK) >> EDID_HDMI_VSDB_VIC_LEN_BIT; + + if (pVideo->hdmi_3d_format == HDMI_VIC_FORMAT) { + if (HDMIVICLen) { + for (edid_index = 0; edid_index < (int)HDMIVICLen; edid_index++) { + if (vic == gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + edid_index]) + return 1; + } + return 0; + } else { + return 0; + } + } + + // HDMI_3D_LEN + HDMI3DLen = gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS] + & EDID_HDMI_VSDB_3D_LEN_MASK; + + DPRINTF("HDMI VIC LENGTH[%x] = %x\r\n", + StartAddr + EDID_HDMI_EXT_LENGTH_POS, HDMIVICLen); + DPRINTF("HDMI 3D LENGTH[%x] = %x\r\n", + StartAddr + EDID_HDMI_EXT_LENGTH_POS, HDMI3DLen); + + // check 3D_Present bit + if (blockLength >= (EDID_HDMI_3D_PRESENT_POS - latency_offset)) { + VSDB3DPresent = gEdidData[StartAddr + EDID_HDMI_3D_PRESENT_POS] + & EDID_HDMI_3D_PRESENT_MASK; + VSDB3DMultiPresent = gEdidData[StartAddr + EDID_HDMI_3D_PRESENT_POS] + & EDID_HDMI_3D_MULTI_PRESENT_MASK; + } + + if (VSDB3DPresent) { + DPRINTF("VSDB 3D Present!!!\r\n"); + // check with 3D madatory format + if (CheckResolution(pVideo->resolution, pVideo->pixelAspectRatio)) { + int size = sizeof(edid_3d)/sizeof(struct edid_3d_mandatory); + for (edid_index = 0; edid_index < size; edid_index++) { + if (edid_3d[edid_index].resolution == pVideo->resolution && + edid_3d[edid_index].hdmi_3d_format == pVideo->hdmi_3d_format ) + return 1; + } + } + } + + // check 3D_Multi_Present bit + if (VSDB3DMultiPresent) { + DPRINTF("VSDB 3D Multi Present!!! = 0x%02x\r\n",VSDB3DMultiPresent); + // 3D Structure only + if (VSDB3DMultiPresent == EDID_3D_STRUCTURE_ONLY_EXIST) { + // 3D Structure All + Hdmi3DStructure = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 1] << 8); + Hdmi3DStructure |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 2]; + DPRINTF("VSDB 3D Structure!!! = [0x%02x]\r\n",Hdmi3DStructure); + } + + // 3D Structure and Mask + if (VSDB3DMultiPresent == EDID_3D_STRUCTURE_MASK_EXIST) { + // 3D Structure All + Hdmi3DStructure = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 1] << 8); + Hdmi3DStructure |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 2]; + // 3D Structure Mask + Hdmi3DMask |= (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 3] << 8); + Hdmi3DMask |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 4]; + DPRINTF("VSDB 3D Structure!!! = [0x%02x]\r\n",Hdmi3DStructure); + DPRINTF("VSDB 3D Mask!!! = [0x%02x]\r\n",Hdmi3DMask); + DPRINTF("Current 3D Video format!!! = [%d]\r\n",pVideo->hdmi_3d_format); + DPRINTF("Current 3D Video format!!! = [0x%02x]\r\n",1<hdmi_3d_format); + } + + // check 3D Structure and Mask + if (Hdmi3DStructure & (1<hdmi_3d_format)) { + DPRINTF("VSDB 3D Structure Contains Current Video Structure!!!\r\n"); + // check first 16 EDID + for (edid_index = 0; edid_index < NUM_OF_VIC_FOR_3D; edid_index++) { + DPRINTF("VIC = %d, EDID Vic = %d!!!\r\n",vic,aVIC[edid_index]); + if (Hdmi3DMask & (1<= (EDID_HDMI_EXT_LENGTH_POS - latency_offset)) { + unsigned int HDMI3DExtLen = HDMI3DLen - (VSDB3DMultiPresent>>EDID_HDMI_3D_MULTI_PRESENT_BIT)*2; + unsigned int VICOrder; + + // check if there is 3D extra data ? + //TODO: check 3D_Detail in case of SSH + if (HDMI3DExtLen) { + // check HDMI 3D Extra Data + for (edid_index = 0; edid_index < (int)(HDMI3DExtLen / 2); edid_index++) { + VICOrder = gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + + (VSDB3DMultiPresent>>EDID_HDMI_3D_MULTI_PRESENT_BIT) * 2 + edid_index * 2] + & EDID_HDMI_2D_VIC_ORDER_MASK; + VICOrder = (1<>EDID_HDMI_3D_MULTI_PRESENT_BIT) * 2 + edid_index * 2] + & EDID_HDMI_3D_STRUCTURE_MASK; + Hdmi3DStructure = (1<hdmi_3d_format && vic == aVIC[VICOrder]) + return 1; + } + } + } + } + } + + return 0; +} + +/** + * Initialize EDID library. This will intialize DDC library. + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDOpen(void) +{ + // init DDC + return DDCOpen(); +} + +/** + * Finalize EDID library. This will finalize DDC library. + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDClose(void) +{ + // reset EDID + EDIDReset(); + + // close EDDC + return DDCClose(); +} + +/** + * Read EDID data of Rx. + * @return If success, return 1; Otherwise, return 0; + */ +int EDIDRead(void) +{ + int block,dataPtr; + unsigned char temp[SIZEOFEDIDBLOCK]; + + // if already read?? + if (EDIDValid()) + return 1; + + // read EDID Extension Number + // read EDID + if (!ReadEDIDBlock(0,temp)) + return 0; + + // get extension + gExtensions = temp[EDID_EXTENSION_NUMBER_POS]; + + // prepare buffer + gEdidData = (unsigned char*)malloc((gExtensions+1)*SIZEOFEDIDBLOCK); + if (!gEdidData) + return 0; + + // copy EDID Block 0 + memcpy(gEdidData,temp,SIZEOFEDIDBLOCK); + + // read EDID Extension + for (block = 1,dataPtr = SIZEOFEDIDBLOCK; block <= gExtensions; block++,dataPtr+=SIZEOFEDIDBLOCK) { + // read extension 1~gExtensions + if (!ReadEDIDBlock(block, gEdidData+dataPtr)) { + // reset buffer + EDIDReset(); + return 0; + } + } + + // check if extension is more than 1, and first extension block is not block map. + if (gExtensions > 1 && gEdidData[SIZEOFEDIDBLOCK] != EDID_BLOCK_MAP_EXT_TAG_VAL) { + // reset buffer + DPRINTF("EDID has more than 1 extension but, first extension block is not block map\n"); + EDIDReset(); + return 0; + } + + return 1; +} + +/** + * Reset stored EDID data. + */ +void EDIDReset(void) +{ + if (gEdidData) { + free(gEdidData); + gEdidData = NULL; + DPRINTF("\t\t\t\tEDID is reset!!!\n"); + } +} + +/** + * Get CEC physical address. + * @param outAddr [out] CEC physical address. LSB 2 bytes is available. [0:0:AB:CD] + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDGetCECPhysicalAddress(int* const outAddr) +{ + int i; + unsigned int StartAddr; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && (StartAddr = GetVSDBOffset(i)) > 0) { // check block + // get supported DC value + // int tempDC1 = (int)(gEdidData[tempAddr+EDID_DC_POS]); + int phyAddr = gEdidData[StartAddr + EDID_CEC_PHYICAL_ADDR] << 8; + phyAddr |= gEdidData[StartAddr + EDID_CEC_PHYICAL_ADDR+1]; + + DPRINTF("phyAddr = %x\n",phyAddr); + + *outAddr = phyAddr; + + return 1; + } + } + + return 0; +} + +/** + * Check if Rx supports HDMI/DVI mode or not. + * @param video [in] HDMI or DVI mode to check + * @return If Rx supports requested mode, return 1; Otherwise, return 0. + */ +int EDIDHDMIModeSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check hdmi mode + if (video->mode == HDMI) { + if (!CheckHDMIMode()) { + DPRINTF("HDMI mode Not Supported\n"); + return 0; + } + } + return 1; +} + +/** + * Check if Rx supports requested video resoultion or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDVideoResolutionSupport(struct HDMIVideoParameter * const video) +{ + unsigned int TMDSClock; + unsigned int MaxTMDS = 0; + + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // get max tmds + MaxTMDS = GetMaxTMDS()*5; + + // Check MAX TMDS + TMDSClock = aVideoParams[video->resolution].PixelClock/100; + if (video->colorDepth == HDMI_CD_36) + TMDSClock *= 1.5; + else if (video->colorDepth == HDMI_CD_30) + TMDSClock *=1.25; + + DPRINTF("MAX TMDS = %d, Current TMDS = %d\n",MaxTMDS, TMDSClock); + if (MaxTMDS != 0 && MaxTMDS < TMDSClock) { + DPRINTF("Pixel clock is beyond Maximun TMDS in EDID\n"); + return 0; + } + + // check resolution + if (!CheckResolution(video->resolution,video->pixelAspectRatio)) { + DPRINTF("Video Resolution Not Supported\n"); + return 0; + } + + // check 3D format + if (!EDID3DFormatSupport(video)) { + DPRINTF("3D Format Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested color depth or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorDepthSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check resolution + if (!CheckColorDepth(video->colorDepth,video->colorSpace)) { + DPRINTF("Color Depth Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested color space or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorSpaceSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + // check color space + if (!CheckColorSpace(video->colorSpace)) { + DPRINTF("Color Space Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested colorimetry or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorimetrySupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check colorimetry + if (!CheckColorimetry(video->colorimetry)) { + DPRINTF("Colorimetry Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested audio parameters or not. + * @param audio [in] Audio parameters to check + * @return If Rx supports audio parameters, return 1; Otherwise, return 0. + */ +int EDIDAudioModeSupport(struct HDMIAudioParameter * const audio) +{ + int i; + + // read EDID + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check EDID Extension + // find timing block + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // find Short Audio Description + unsigned int StartAddr = i*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + DPRINTF("tag = %d\n",tag); + DPRINTF("blockLen = %d\n",blockLen-1); + + // check if it is short video description + if (tag == EDID_SHORT_AUD_DEC_TAG_VAL) { + // if so, check SAD + unsigned int j, channelNum; + int audioFormat,sampleFreq,wordLen; + for (j = 1; j < blockLen; j += 3) { + audioFormat = gEdidData[ExtAddr+j] & EDID_SAD_CODE_MASK; + channelNum = gEdidData[ExtAddr+j] & EDID_SAD_CHANNEL_MASK; + sampleFreq = gEdidData[ExtAddr+j+1]; + wordLen = gEdidData[ExtAddr+j+2]; + + DPRINTF("request = %d, EDIDAudioFormatCode = %d\n",(audio->formatCode)<<3, audioFormat); + DPRINTF("request = %d, EDIDChannelNumber= %d\n",(audio->channelNum)-1, channelNum); + DPRINTF("request = %d, EDIDSampleFreq= %d\n",1<<(audio->sampleFreq), sampleFreq); + DPRINTF("request = %d, EDIDWordLeng= %d\n",1<<(audio->wordLength), wordLen); + + // check parameter + // check audioFormat + if (audioFormat & ( (audio->formatCode) << 3) && // format code + channelNum >= ( (audio->channelNum) -1) && // channel number + (sampleFreq & (1<<(audio->sampleFreq)))) { // sample frequency + if (audioFormat == LPCM_FORMAT) { // check wordLen + int ret = 0; + switch (audio->wordLength) { + case WORD_16: + case WORD_17: + case WORD_18: + case WORD_19: + case WORD_20: + ret = wordLen & (1<<1); + break; + case WORD_21: + case WORD_22: + case WORD_23: + case WORD_24: + ret = wordLen & (1<<2); + break; + } + return ret; + } + return 1; // if not LPCM + } + } + } + // else find next block + ExtAddr += blockLen; + } + } + } + + return 0; +} diff --git a/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.h b/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.h new file mode 100644 index 0000000..dfd3096 --- /dev/null +++ b/exynos4/hal/libhdmi/libsForhdmi/libedid/libedid.h @@ -0,0 +1,42 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBEDID_H_ +#define _LIBEDID_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "video.h" +#include "audio.h" + +int EDIDOpen(void); +int EDIDRead(void); +void EDIDReset(void); +int EDIDHDMIModeSupport(struct HDMIVideoParameter *video); +int EDIDVideoResolutionSupport(struct HDMIVideoParameter *video); +int EDIDColorDepthSupport(struct HDMIVideoParameter *video); +int EDIDColorSpaceSupport(struct HDMIVideoParameter *video); +int EDIDColorimetrySupport(struct HDMIVideoParameter *video); +int EDIDAudioModeSupport(struct HDMIAudioParameter *audio); +int EDIDGetCECPhysicalAddress(int* outAddr); +int EDIDClose(void); + +#ifdef __cplusplus +} +#endif +#endif /* _LIBEDID_H_ */ diff --git a/exynos4/hal/libhwcomposer/Android.mk b/exynos4/hal/libhwcomposer/Android.mk new file mode 100644 index 0000000..902a72f --- /dev/null +++ b/exynos4/hal/libhwcomposer/Android.mk @@ -0,0 +1,88 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation, not prelinked and stored in +# hw/..so + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL \ + libGLESv1_CM + +ifeq ($(BOARD_USE_V4L2_ION),true) +LOCAL_SHARED_LIBRARIES += libion +endif + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := SecHWCLog.cpp SecHWCUtils.cpp SecHWC.cpp + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libfimg + +ifeq ($(TARGET_SOC),exynos4210) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4x12) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12 +endif + +ifeq ($(BOARD_USES_HDMI),true) +LOCAL_C_INCLUDES += \ + $(TARGET_HAL_PATH)/libhwcomposer \ + $(TARGET_HAL_PATH)/include \ + $(TARGET_HAL_PATH)/libhdmi/libhdmiservice + +LOCAL_SHARED_LIBRARIES += libhdmiclient libTVOut + +LOCAL_CFLAGS += -DBOARD_USES_HDMI +LOCAL_CFLAGS += -DBOARD_HDMI_STD=$(BOARD_HDMI_STD) +LOCAL_CFLAGS += -DVIDEO_DUAL_DISPLAY + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +ifeq ($(BOARD_HDMI_STD), STD_NTSC_M) +LOCAL_CFLAGS += -DSTD_NTSC_M +endif + +ifeq ($(BOARD_HDMI_STD),STD_480P) +LOCAL_CFLAGS += -DSTD_480P +endif + +ifeq ($(BOARD_HDMI_STD),STD_720P) +LOCAL_CFLAGS += -DSTD_720P +endif + +ifeq ($(BOARD_HDMI_STD),STD_1080P) +LOCAL_CFLAGS += -DSTD_1080P +endif +endif + +ifeq ($(BOARD_USE_V4L2),true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2 +endif + +ifeq ($(BOARD_USE_V4L2_ION),true) +LOCAL_CFLAGS += -DBOARD_USE_V4L2_ION +endif + +LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libhwcomposer/SecHWC.cpp b/exynos4/hal/libhwcomposer/SecHWC.cpp new file mode 100644 index 0000000..d2f3ecc --- /dev/null +++ b/exynos4/hal/libhwcomposer/SecHWC.cpp @@ -0,0 +1,957 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#include +#include + +#include + +#include "SecHWCUtils.h" + +#include "gralloc_priv.h" +#ifdef HWC_HWOVERLAY +#include +#endif +#if defined(BOARD_USES_HDMI) +#include "SecHdmiClient.h" +#include "SecTVOutService.h" + +#include "SecHdmi.h" + +//#define CHECK_EGL_FPS +#ifdef CHECK_EGL_FPS +extern void check_fps(); +#endif + +static int lcd_width, lcd_height; +static int prev_usage = 0; + +#define CHECK_TIME_DEBUG 0 +#define SUPPORT_AUTO_UI_ROTATE +#endif +int testRenderNum =0; + +static int hwc_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device); + +static struct hw_module_methods_t hwc_module_methods = { + open: hwc_device_open +}; + +hwc_module_t HAL_MODULE_INFO_SYM = { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: HWC_HARDWARE_MODULE_ID, + name: "Samsung S5PC21X hwcomposer module", + author: "SAMSUNG", + methods: &hwc_module_methods, + } +}; + +/*****************************************************************************/ + +static void dump_layer(hwc_layer_t const* l) { + LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, " + "{%d,%d,%d,%d}, {%d,%d,%d,%d}", + l->compositionType, l->flags, l->handle, l->transform, l->blending, + l->sourceCrop.left, + l->sourceCrop.top, + l->sourceCrop.right, + l->sourceCrop.bottom, + l->displayFrame.left, + l->displayFrame.top, + l->displayFrame.right, + l->displayFrame.bottom); +} + +void calculate_rect(struct hwc_win_info_t *win, hwc_layer_t *cur, + sec_rect *rect) +{ + rect->x = cur->displayFrame.left; + rect->y = cur->displayFrame.top; + rect->w = cur->displayFrame.right - cur->displayFrame.left; + rect->h = cur->displayFrame.bottom - cur->displayFrame.top; + + if (rect->x < 0) { + if (rect->w + rect->x > win->lcd_info.xres) + rect->w = win->lcd_info.xres; + else + rect->w = rect->w + rect->x; + rect->x = 0; + } else { + if (rect->w + rect->x > win->lcd_info.xres) + rect->w = win->lcd_info.xres - rect->x; + } + if (rect->y < 0) { + if (rect->h + rect->y > win->lcd_info.yres) + rect->h = win->lcd_info.yres; + else + rect->h = rect->h + rect->y; + rect->y = 0; + } else { + if (rect->h + rect->y > win->lcd_info.yres) + rect->h = win->lcd_info.yres - rect->y; + } +} + +static int set_src_dst_img_rect(hwc_layer_t *cur, + struct hwc_win_info_t *win, + struct sec_img *src_img, + struct sec_img *dst_img, + struct sec_rect *src_rect, + struct sec_rect *dst_rect, + int win_idx) +{ + private_handle_t *prev_handle = (private_handle_t *)(cur->handle); + sec_rect rect; + + /* 1. Set src_img from prev_handle */ + src_img->f_w = prev_handle->width; + src_img->f_h = prev_handle->height; + src_img->w = prev_handle->width; + src_img->h = prev_handle->height; + src_img->format = prev_handle->format; + src_img->base = (uint32_t)prev_handle->base; + src_img->offset = prev_handle->offset; + src_img->mem_id = prev_handle->fd; + src_img->paddr = prev_handle->paddr; + src_img->usage = prev_handle->usage; + src_img->uoffset = prev_handle->uoffset; + src_img->voffset = prev_handle->voffset; + + src_img->mem_type = HWC_VIRT_MEM_TYPE; + + switch (src_img->format) { + case HAL_PIXEL_FORMAT_YV12: /* To support video editor */ + case HAL_PIXEL_FORMAT_YCbCr_420_P: /* To support SW codec */ + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + src_img->f_w = (src_img->f_w + 15) & ~15; + src_img->f_h = (src_img->f_h + 1) & ~1; + break; + default: + src_img->f_w = src_img->w; + src_img->f_h = src_img->h; + break; + } + + /* 2. Set dst_img from window(lcd) */ + calculate_rect(win, cur, &rect); + dst_img->f_w = win->lcd_info.xres; + dst_img->f_h = win->lcd_info.yres; + dst_img->w = rect.w; + dst_img->h = rect.h; + + switch (win->lcd_info.bits_per_pixel) { + case 32: + dst_img->format = HAL_PIXEL_FORMAT_RGBX_8888; + break; + default: + dst_img->format = HAL_PIXEL_FORMAT_RGB_565; + break; + } + + dst_img->base = win->addr[win->buf_index]; + dst_img->offset = 0; + dst_img->mem_id = 0; + dst_img->mem_type = HWC_PHYS_MEM_TYPE; + + /* 3. Set src_rect(crop rect) */ + if (cur->displayFrame.left < 0) { + src_rect->x = + (0 - cur->displayFrame.left) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + if (cur->displayFrame.right + 1 > win->lcd_info.xres) { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x - + (cur->displayFrame.right - win->lcd_info.xres) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + } else { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x; + } + } else { + src_rect->x = cur->sourceCrop.left; + if (cur->displayFrame.right + 1 > win->lcd_info.xres) { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x - + (cur->displayFrame.right - win->lcd_info.xres) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + } else { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1); + } + } + if (cur->displayFrame.top < 0) { + src_rect->y = + (0 - cur->displayFrame.top) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y - + (cur->displayFrame.bottom - win->lcd_info.yres) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + } else { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y; + } + } else { + src_rect->y = cur->sourceCrop.top; + if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y - + (cur->displayFrame.bottom - win->lcd_info.yres) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + } else { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1); + } + } + + SEC_HWC_Log(HWC_LOG_DEBUG, + "crop information()::" + "sourceCrop left(%d),top(%d),right(%d),bottom(%d)," + "src_rect x(%d),y(%d),w(%d),h(%d)," + "prev_handle w(%d),h(%d)", + cur->sourceCrop.left, + cur->sourceCrop.top, + cur->sourceCrop.right, + cur->sourceCrop.bottom, + src_rect->x, src_rect->y, src_rect->w, src_rect->h, + prev_handle->width, prev_handle->height); + + src_rect->x = SEC_MAX(src_rect->x, 0); + src_rect->y = SEC_MAX(src_rect->y, 0); + src_rect->w = SEC_MAX(src_rect->w, 0); + src_rect->w = SEC_MIN(src_rect->w, prev_handle->width); + src_rect->h = SEC_MAX(src_rect->h, 0); + src_rect->h = SEC_MIN(src_rect->h, prev_handle->height); + + /* 4. Set dst_rect(fb or lcd) + * fimc dst image will be stored from left top corner + */ + dst_rect->x = 0; + dst_rect->y = 0; + dst_rect->w = win->rect_info.w; + dst_rect->h = win->rect_info.h; + + /* Summery */ + SEC_HWC_Log(HWC_LOG_DEBUG, + "set_src_dst_img_rect()::" + "SRC w(%d),h(%d),f_w(%d),f_h(%d),fmt(0x%x)," + "base(0x%x),offset(%d),paddr(0x%X),mem_id(%d),mem_type(%d)=>\r\n" + " DST w(%d),h(%d),f(0x%x),base(0x%x)," + "offset(%d),mem_id(%d),mem_type(%d)," + "rot(%d),win_idx(%d)" + " SRC_RECT x(%d),y(%d),w(%d),h(%d)=>" + "DST_RECT x(%d),y(%d),w(%d),h(%d)", + src_img->w, src_img->h, src_img->f_w, src_img->f_h, src_img->format, + src_img->base, src_img->offset, src_img->paddr, src_img->mem_id, src_img->mem_type, + dst_img->w, dst_img->h, dst_img->format, dst_img->base, + dst_img->offset, dst_img->mem_id, dst_img->mem_type, + cur->transform, win_idx, + src_rect->x, src_rect->y, src_rect->w, src_rect->h, + dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h); + + return 0; +} + +static int get_hwc_compos_decision(hwc_layer_t* cur, int iter, int win_cnt) +{ + if(cur->flags & HWC_SKIP_LAYER || !cur->handle) { + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::is_skip_layer %d cur->handle %x ", + __func__, cur->flags & HWC_SKIP_LAYER, cur->handle); + + return HWC_FRAMEBUFFER; + } + + private_handle_t *prev_handle = (private_handle_t *)(cur->handle); + int compositionType = HWC_FRAMEBUFFER; + + if (iter == 0) { + /* check here....if we have any resolution constraints */ + if (((cur->sourceCrop.right - cur->sourceCrop.left + 1) < 16) || + ((cur->sourceCrop.bottom - cur->sourceCrop.top + 1) < 8)) + return compositionType; + + if ((cur->transform == HAL_TRANSFORM_ROT_90) || + (cur->transform == HAL_TRANSFORM_ROT_270)) { + if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 4) || + ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 8)) + return compositionType; + } else if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 8) || + ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 4)) { + return compositionType; + } + + switch (prev_handle->format) { + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + compositionType = HWC_OVERLAY; + break; + case HAL_PIXEL_FORMAT_YV12: /* YCrCb_420_P */ + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + if ((prev_handle->usage & GRALLOC_USAGE_HWC_HWOVERLAY) && + (cur->blending == HWC_BLENDING_NONE)) + compositionType = HWC_OVERLAY; + else + compositionType = HWC_FRAMEBUFFER; + break; + default: + compositionType = HWC_FRAMEBUFFER; + break; + } + } + +#ifdef SUB_TITLES_HWC + else if ((win_cnt > 0) && + (prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP)) { + switch (prev_handle->format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + compositionType = HWC_OVERLAY; + break; + default: + compositionType = HWC_FRAMEBUFFER; + break; + } + + SEC_HWC_Log(HWC_LOG_DEBUG, "2nd iter###%s:: compositionType %d bpp %d" + " format %x src[%d %d %d %d] dst[%d %d %d %d] srcImg[%d %d]", + __func__, compositionType, prev_handle->bpp, + prev_handle->format, + cur->sourceCrop.left, cur->sourceCrop.right, + cur->sourceCrop.top, cur->sourceCrop.bottom, + cur->displayFrame.left, cur->displayFrame.right, + cur->displayFrame.top, cur->displayFrame.bottom, + prev_handle->width, prev_handle->height); + } +#endif + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s::compositionType(%d)=>0:FB,1:OVERLAY \r\n" + " format(0x%x),magic(0x%x),flags(%d),size(%d),offset(%d)" + "b_addr(0x%x),usage(%d),w(%d),h(%d),bpp(%d)", + "get_hwc_compos_decision()", compositionType, + prev_handle->format, prev_handle->magic, prev_handle->flags, + prev_handle->size, prev_handle->offset, prev_handle->base, + prev_handle->usage, prev_handle->width, prev_handle->height, + prev_handle->bpp); + + return compositionType; +} + +static void reset_win_rect_info(hwc_win_info_t *win) +{ + win->rect_info.x = 0; + win->rect_info.y = 0; + win->rect_info.w = 0; + win->rect_info.h = 0; + return; +} + + +static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_t *cur, + int win_idx, int layer_idx) +{ + struct hwc_win_info_t *win; + sec_rect rect; + int ret = 0; + + if (NUM_OF_WIN <= win_idx) + return -1; + + win = &ctx->win[win_idx]; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: left(%d),top(%d),right(%d),bottom(%d),transform(%d)" + "lcd_info.xres(%d),lcd_info.yres(%d)", + "++assign_overlay_window()", + cur->displayFrame.left, cur->displayFrame.top, + cur->displayFrame.right, cur->displayFrame.bottom, cur->transform, + win->lcd_info.xres, win->lcd_info.yres); + + calculate_rect(win, cur, &rect); + + if ((rect.x != win->rect_info.x) || (rect.y != win->rect_info.y) || + (rect.w != win->rect_info.w) || (rect.h != win->rect_info.h)){ + win->rect_info.x = rect.x; + win->rect_info.y = rect.y; + win->rect_info.w = rect.w; + win->rect_info.h = rect.h; + //turnoff the window and set the window position with new conf... + if (window_set_pos(win) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s", + __func__, strerror(errno)); + ret = -1; + } + ctx->layer_prev_buf[win_idx] = 0; + } + + win->layer_index = layer_idx; + win->status = HWC_WIN_RESERVED; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: win_x %d win_y %d win_w %d win_h %d lay_idx %d win_idx %d\n", + "--assign_overlay_window()", + win->rect_info.x, win->rect_info.y, win->rect_info.w, + win->rect_info.h, win->layer_index, win_idx ); + + return 0; +} + +static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) +{ + struct hwc_context_t* ctx = (struct hwc_context_t*)dev; + int overlay_win_cnt = 0; + int compositionType = 0; + int ret; + + //if geometry is not changed, there is no need to do any work here + if (!list || (!(list->flags & HWC_GEOMETRY_CHANGED))) + return 0; + + //all the windows are free here.... + for (int i = 0 ; i < NUM_OF_WIN; i++) { + ctx->win[i].status = HWC_WIN_FREE; + ctx->win[i].buf_index = 0; + } + + ctx->num_of_hwc_layer = 0; + ctx->num_of_fb_layer = 0; + ctx->num_2d_blit_layer = 0; + + for (int i = 0; i < list->numHwLayers ; i++) { + hwc_layer_t* cur = &list->hwLayers[i]; + + if (overlay_win_cnt < NUM_OF_WIN) { + compositionType = get_hwc_compos_decision(cur, 0, overlay_win_cnt); + + if (compositionType == HWC_FRAMEBUFFER) { + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + } else { + ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i); + if (ret != 0) { + LOGE("assign_overlay_window fail, change to frambuffer"); + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + continue; + } + + cur->compositionType = HWC_OVERLAY; + cur->hints = HWC_HINT_CLEAR_FB; + overlay_win_cnt++; + ctx->num_of_hwc_layer++; + } + } else { + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + } + } + +#ifdef SUB_TITLES_HWC + for (int i = 0; i < list->numHwLayers ; i++) { + if (overlay_win_cnt < NUM_OF_WIN) { + hwc_layer_t* cur = &list->hwLayers[i]; + if (get_hwc_compos_decision(cur, 1, overlay_win_cnt) == HWC_OVERLAY) { + ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i); + if (ret == 0) { + cur->compositionType = HWC_OVERLAY; + cur->hints = HWC_HINT_CLEAR_FB; + overlay_win_cnt++; + ctx->num_of_hwc_layer++; + ctx->num_of_fb_layer--; + ctx->num_2d_blit_layer = 1; + } + } + } + else + break; + } +#endif + +#if defined(BOARD_USES_HDMI) + android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance(); + mHdmiClient->setHdmiHwcLayer(ctx->num_of_hwc_layer); +#endif + + if (list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer)) + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: numHwLayers %d num_of_fb_layer %d num_of_hwc_layer %d ", + __func__, list->numHwLayers, ctx->num_of_fb_layer, + ctx->num_of_hwc_layer); + + if (overlay_win_cnt < NUM_OF_WIN) { + //turn off the free windows + for (int i = overlay_win_cnt; i < NUM_OF_WIN; i++) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + } + } + + return 0; +} + +static int hwc_set(hwc_composer_device_t *dev, + hwc_display_t dpy, + hwc_surface_t sur, + hwc_layer_list_t* list) +{ + struct hwc_context_t *ctx = (struct hwc_context_t *)dev; + int skipped_window_mask = 0; + hwc_layer_t* cur; + struct hwc_win_info_t *win; + int ret; + int pmem_phyaddr; + static int egl_check; + int egl_run = 0; + struct sec_img src_img; + struct sec_img dst_img; + struct sec_rect src_work_rect; + struct sec_rect dst_work_rect; + + memset(&src_img, 0, sizeof(src_img)); + memset(&dst_img, 0, sizeof(dst_img)); + memset(&src_work_rect, 0, sizeof(src_work_rect)); + memset(&dst_work_rect, 0, sizeof(dst_work_rect)); + +#if defined(BOARD_USES_HDMI) + int skip_hdmi_rendering = 0; + int rotVal = 0; +#endif + + if (!list) { + //turn off the all windows + for (int i = 0; i < NUM_OF_WIN; i++) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + ctx->win[i].status = HWC_WIN_FREE; + } + ctx->num_of_hwc_layer = 0; + + if (sur == NULL && dpy == NULL) + return HWC_EGL_ERROR; + } + + if(ctx->num_of_hwc_layer > NUM_OF_WIN) + ctx->num_of_hwc_layer = NUM_OF_WIN; + + //compose hardware layers here + for (int i = 0; i < ctx->num_of_hwc_layer - ctx->num_2d_blit_layer; i++) { + win = &ctx->win[i]; + if (win->status == HWC_WIN_RESERVED) { + cur = &list->hwLayers[win->layer_index]; + + if (cur->compositionType == HWC_OVERLAY) { + if (ctx->layer_prev_buf[i] == (uint32_t)cur->handle) { + /* + * In android platform, all the graphic buffer are at least + * double buffered (2 or more) this buffer is already rendered. + * It is the redundant src buffer for FIMC rendering. + */ + LOGD("SKIP FIMC rendering for Layer%d", win->layer_index); +#if defined(BOARD_USES_HDMI) + skip_hdmi_rendering = 1; +#endif + continue; + } + ctx->layer_prev_buf[i] = (uint32_t)cur->handle; + // initialize the src & dist context for fimc + set_src_dst_img_rect(cur, win, &src_img, &dst_img, + &src_work_rect, &dst_work_rect, i); + + ret = runFimc(ctx, + &src_img, &src_work_rect, + &dst_img, &dst_work_rect, + cur->transform); + + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::runFimc fail : ret=%d\n", + __func__, ret); + skipped_window_mask |= (1 << i); + continue; + } + + window_pan_display(win); + + win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF; + if (win->power_state == 0) + window_show(win); + } else { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s:: error : layer %d compositionType should have been" + " HWC_OVERLAY ", __func__, win->layer_index); + skipped_window_mask |= (1 << i); + continue; + } + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s:: error : window status should have " + "been HWC_WIN_RESERVED by now... ", __func__); + skipped_window_mask |= (1 << i); + continue; + } + } + +#ifdef SUB_TITLES_HWC + if (ctx->num_2d_blit_layer) { + g2d_rect srcRect; + g2d_rect dstRect; + + win = &ctx->win[ctx->num_of_hwc_layer - 1]; + cur = &list->hwLayers[win->layer_index]; + set_src_dst_g2d_rect(cur, win, &srcRect, &dstRect); + ret = runG2d(ctx, &srcRect, &dstRect, + cur->transform); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::runG2d fail : ret=%d\n", + __func__, ret); + skipped_window_mask |= (1 << (ctx->num_of_hwc_layer - 1)); + goto g2d_error; + } + + window_pan_display(win); + + win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF; + if (win->power_state == 0) + window_show(win); + } + +g2d_error: +#endif + + if (skipped_window_mask) { + //turn off the free windows + for (int i = 0; i < NUM_OF_WIN; i++) { + if (skipped_window_mask & (1 << i)) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + } + } + } + + if (0 < ctx->num_of_fb_layer) { +#ifdef CHECK_EGL_FPS + check_fps(); +#endif +#ifdef HWC_HWOVERLAY + unsigned char pixels[4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); +#endif + egl_check = 1; + egl_run = 1; + } else { + if (egl_check == 1) { + egl_check = 0; + egl_run = 1; + } + } + + if (egl_run == 1) { + EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur); + if (!sucess) + return HWC_EGL_ERROR; + } + +#if defined(BOARD_USES_HDMI) + android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance(); + + if (skip_hdmi_rendering == 1) + return 0; + + if (list == NULL) { + // Don't display unnecessary image + mHdmiClient->setHdmiEnable(0); + return 0; + } else { + mHdmiClient->setHdmiEnable(1); + } + +#ifdef SUPPORT_AUTO_UI_ROTATE + cur = &list->hwLayers[0]; + + if (cur->transform == HAL_TRANSFORM_ROT_90 || cur->transform == HAL_TRANSFORM_ROT_270) + mHdmiClient->setHdmiRotate(270, ctx->num_of_hwc_layer); + else + mHdmiClient->setHdmiRotate(0, ctx->num_of_hwc_layer); +#endif + + // To support S3D video playback (automatic TV mode change to 3D mode) + if (ctx->num_of_hwc_layer == 1) { + if (src_img.usage != prev_usage) + mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60 + + if ((src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_LR) || + (src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_RL)) + mHdmiClient->setHdmiResolution(7209601); // V4L2_STD_TVOUT_720P_60_SBS_HALF + else if ((src_img.usage & GRALLOC_USAGE_PRIVATE_TB_LR) || + (src_img.usage & GRALLOC_USAGE_PRIVATE_TB_RL)) + mHdmiClient->setHdmiResolution(1080924); // V4L2_STD_TVOUT_1080P_24_TB + + prev_usage = src_img.usage; + } else { + if ((prev_usage & GRALLOC_USAGE_PRIVATE_SBS_LR) || + (prev_usage & GRALLOC_USAGE_PRIVATE_SBS_RL) || + (prev_usage & GRALLOC_USAGE_PRIVATE_TB_LR) || + (prev_usage & GRALLOC_USAGE_PRIVATE_TB_RL)) + mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60 + + prev_usage = 0; + } + + if (ctx->num_of_hwc_layer == 1) { + if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)|| + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP)) { + ADDRS * addr = (ADDRS *)(src_img.base); + + mHdmiClient->blit2Hdmi(src_img.w, src_img.h, + src_img.format, + (unsigned int)addr->addr_y, (unsigned int)addr->addr_cbcr, (unsigned int)addr->addr_cbcr, + 0, 0, + android::SecHdmiClient::HDMI_MODE_VIDEO, + ctx->num_of_hwc_layer); + } else if ((src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_SP) || + (src_img.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) || + (src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_P) || + (src_img.format == HAL_PIXEL_FORMAT_YV12)) { + mHdmiClient->blit2Hdmi(src_img.w, src_img.h, + src_img.format, + (unsigned int)ctx->fimc.params.src.buf_addr_phy_rgb_y, + (unsigned int)ctx->fimc.params.src.buf_addr_phy_cb, + (unsigned int)ctx->fimc.params.src.buf_addr_phy_cr, + 0, 0, + android::SecHdmiClient::HDMI_MODE_VIDEO, + ctx->num_of_hwc_layer); + } else { + LOGE("%s: Unsupported format = %d", __func__, src_img.format); + } + } +#endif + return 0; +} + +static int hwc_device_close(struct hw_device_t *dev) +{ + struct hwc_context_t* ctx = (struct hwc_context_t*)dev; + int ret = 0; + int i; + if (ctx) { + if (destroyFimc(&ctx->fimc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc fail", __func__); + ret = -1; + } +#ifdef SUB_TITLES_HWC + if (destroyG2d(&ctx->g2d) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__); + ret = -1; + } +#endif + if (destroyMem(&ctx->s3c_mem) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem fail", __func__); + ret = -1; + } + +#ifdef USE_HW_PMEM + if (destroyPmem(&ctx->sec_pmem) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem fail", __func__); + ret = -1; + } +#endif + for (i = 0; i < NUM_OF_WIN; i++) { + if (window_close(&ctx->win[i]) < 0) + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__); + } + + free(ctx); + } + return ret; +} + +static int hwc_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device) +{ + int status = 0; + struct hwc_win_info_t *win; + + if (strcmp(name, HWC_HARDWARE_COMPOSER)) + return -EINVAL; + + struct hwc_context_t *dev; + dev = (hwc_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = hwc_device_close; + + dev->device.prepare = hwc_prepare; + dev->device.set = hwc_set; + + *device = &dev->device.common; + + //initializing + memset(&(dev->fimc), 0, sizeof(s5p_fimc_t)); + memset(&(dev->s3c_mem), 0, sizeof(struct s3c_mem_t)); +#ifdef USE_HW_PMEM + memset(&(dev->sec_pmem), 0, sizeof(sec_pmem_t)); +#endif + /* open WIN0 & WIN1 here */ + for (int i = 0; i < NUM_OF_WIN; i++) { + if (window_open(&(dev->win[i]), i) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s:: Failed to open window %d device ", __func__, i); + status = -EINVAL; + goto err; + } + } + + if (window_get_global_lcd_info(dev->win[0].fd, &dev->lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::window_get_global_lcd_info is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + +#if defined(BOARD_USES_HDMI) + lcd_width = dev->lcd_info.xres; + lcd_height = dev->lcd_info.yres; +#endif + + /* initialize the window context */ + for (int i = 0; i < NUM_OF_WIN; i++) { + win = &dev->win[i]; + memcpy(&win->lcd_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo)); + memcpy(&win->var_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo)); + + win->rect_info.x = 0; + win->rect_info.y = 0; + win->rect_info.w = win->var_info.xres; + win->rect_info.h = win->var_info.yres; + + if (window_set_pos(win) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + + if (window_get_info(win, i) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_get_info is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + + } + +#ifdef USE_HW_PMEM + if (createPmem(&dev->sec_pmem, PMEM_SIZE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::initPmem(%d) fail", __func__, PMEM_SIZE); + } +#endif + + if (createMem(&dev->s3c_mem, 0, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::createMem() fail (size=0)", __func__); + status = -EINVAL; + goto err; + } + + //create PP + if (createFimc(&dev->fimc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::creatFimc() fail", __func__); + status = -EINVAL; + goto err; + } + +#ifdef SUB_TITLES_HWC + if (createG2d(&dev->g2d) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::createG2d() fail", __func__); + status = -EINVAL; + goto err; + } +#endif + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: hwc_device_open: SUCCESS", __func__); + + return 0; + +err: + if (destroyFimc(&dev->fimc) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc() fail", __func__); +#ifdef SUB_TITLES_HWC + if (destroyG2d(&dev->g2d) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__); +#endif + if (destroyMem(&dev->s3c_mem) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem() fail", __func__); + +#ifdef USE_HW_PMEM + if (destroyPmem(&dev->sec_pmem) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem() fail", __func__); +#endif + + for (int i = 0; i < NUM_OF_WIN; i++) { + if (window_close(&dev->win[i]) < 0) + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__); + } + + return status; +} diff --git a/exynos4/hal/libhwcomposer/SecHWCLog.cpp b/exynos4/hal/libhwcomposer/SecHWCLog.cpp new file mode 100644 index 0000000..6ad4283 --- /dev/null +++ b/exynos4/hal/libhwcomposer/SecHWCLog.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#include + +#include "SecHWCUtils.h" + +void _SEC_HWC_Log(HWC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) +{ + va_list argptr; + + va_start(argptr, msg); + + switch (logLevel) { + case HWC_LOG_DEBUG: + __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); + break; + case HWC_LOG_WARNING: + __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); + break; + case HWC_LOG_ERROR: + __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr); + break; + default: + __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr); + } + + va_end(argptr); +} diff --git a/exynos4/hal/libhwcomposer/SecHWCUtils.cpp b/exynos4/hal/libhwcomposer/SecHWCUtils.cpp new file mode 100644 index 0000000..5214e40 --- /dev/null +++ b/exynos4/hal/libhwcomposer/SecHWCUtils.cpp @@ -0,0 +1,2077 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Revision History: + * - 2011/03/11 : Rama, Meka(v.meka@samsung.com) + * Initial version + * + * - 2011/12/07 : Jeonghee, Kim(jhhhh.kim@samsung.com) + * Add V4L2_PIX_FMT_YUV420M V4L2_PIX_FMT_NV12M + * + */ + +#include "SecHWCUtils.h" + +#ifdef BOARD_USE_V4L2_ION +#define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE +#define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE +#else +#define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT +#define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE +#endif + +#define EXYNOS4_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) + +//#define CHECK_FPS +#ifdef CHECK_FPS +#include +#include +#define CHK_FRAME_CNT 30 + +void check_fps() +{ + static struct timeval tick, tick_old; + static int total = 0; + static int cnt = 0; + int FPS; + cnt++; + gettimeofday(&tick, NULL); + if (cnt > 10) { + if (tick.tv_sec > tick_old.tv_sec) + total += ((tick.tv_usec/1000) + (tick.tv_sec - tick_old.tv_sec)*1000 - (tick_old.tv_usec/1000)); + else + total += ((tick.tv_usec - tick_old.tv_usec)/1000); + + memcpy(&tick_old, &tick, sizeof(timeval)); + if (cnt == (10 + CHK_FRAME_CNT)) { + FPS = 1000*CHK_FRAME_CNT/total; + LOGE("[FPS]:%d\n", FPS); + total = 0; + cnt = 10; + } + } else { + memcpy(&tick_old, &tick, sizeof(timeval)); + total = 0; + } +} +#endif + +struct yuv_fmt_list yuv_list[] = { + { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 2 }, + { "V4L2_PIX_FMT_NV12T", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12T, 12, 2 }, + { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 2 }, + { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 }, + { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 }, + { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 }, +#ifdef BOARD_USE_V4L2_ION + { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 }, + { "V4L2_PIX_FMT_NV12M", "YUV420/2P", V4L2_PIX_FMT_NV12M, 12, 2 }, +#endif + { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 }, + { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 }, + { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 }, + { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 }, + { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 }, + { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 }, + { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 }, + { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 }, + { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 }, +}; + +int window_open(struct hwc_win_info_t *win, int id) +{ + int fd = 0; + char name[64]; + int vsync = 1; + int real_id = id; + + char const * const device_template = "/dev/graphics/fb%u"; + // window & FB maping + // fb0 -> win-id : 2 + // fb1 -> win-id : 3 + // fb2 -> win-id : 4 + // fb3 -> win-id : 0 + // fb4 -> win_id : 1 + // it is pre assumed that ...win0 or win1 is used here.. + + switch (id) { + case 0: +#ifdef BOARD_USE_V4L2_ION + real_id = 2; +#else + real_id = 3; +#endif + break; + case 1: +#ifdef BOARD_USE_V4L2_ION + real_id = 1; +#else + real_id = 4; +#endif + break; + default: + SEC_HWC_Log(HWC_LOG_ERROR, "%s::id(%d) is weird", __func__, id); + goto error; +} + +// 0/10 +// snprintf(name, 64, device_template, id + 3); +// 5/10 +// snprintf(name, 64, device_template, id + 0); +// 0/10 +// snprintf(name, 64, device_template, id + 1); + snprintf(name, 64, device_template, real_id); + + win->fd = open(name, O_RDWR); + if (win->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Failed to open window device (%s) : %s", + __func__, strerror(errno), name); + goto error; + } + +#ifdef ENABLE_FIMD_VSYNC + if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__); + goto error; + } +#endif + + return 0; + +error: + if (0 < win->fd) + close(win->fd); + win->fd = 0; + + return -1; +} + +int window_close(struct hwc_win_info_t *win) +{ + int ret = 0; + + if (0 < win->fd) { + +#ifdef BOARD_USE_V4L2_ION + ion_unmap((void *)win->addr[0], ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE)); + ion_free(win->ion_fd); +#endif + +#ifdef ENABLE_FIMD_VSYNC + int vsync = 0; + if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__); +#endif + ret = close(win->fd); + } + win->fd = 0; + + return ret; +} + +int window_set_pos(struct hwc_win_info_t *win) +{ + struct s3cfb_user_window window; + + //before changing the screen configuration...powerdown the window + if (window_hide(win) != 0) + return -1; + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: x(%d), y(%d)", + __func__, win->rect_info.x, win->rect_info.y); + + win->var_info.xres_virtual = (win->lcd_info.xres + 15) & ~ 15; + win->var_info.yres_virtual = win->lcd_info.yres * NUM_OF_WIN_BUF; + win->var_info.xres = win->rect_info.w; + win->var_info.yres = win->rect_info.h; + + win->var_info.activate &= ~FB_ACTIVATE_MASK; + win->var_info.activate |= FB_ACTIVATE_FORCE; + + if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPUT_VSCREENINFO(%d, %d) fail", + __func__, win->rect_info.w, win->rect_info.h); + return -1; + } + + window.x = win->rect_info.x; + window.y = win->rect_info.y; + + if (ioctl(win->fd, S3CFB_WIN_POSITION, &window) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_WIN_POSITION(%d, %d) fail", + __func__, window.x, window.y); + return -1; + } + + return 0; +} + +int window_get_info(struct hwc_win_info_t *win, int win_num) +{ + int temp_size = 0; + + if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_FSCREENINFO failed : %s", + strerror(errno)); + goto error; + } + + win->size = win->fix_info.line_length * win->var_info.yres; + +#ifdef BOARD_USE_V4L2_ION + struct s3c_fb_user_ion_client ion_handle; + void *ion_start_addr; + + if (ioctl(win->fd, S3CFB_GET_ION_USER_HANDLE, &ion_handle) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Get fb ion client is failed\n"); + return -1; + } + + win->ion_fd = ion_handle.fd; + ion_start_addr = ion_map(win->ion_fd, ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE), 0); +#endif + + for (int j = 0; j < NUM_OF_WIN_BUF; j++) { + temp_size = win->size * j; +#ifdef BOARD_USE_V4L2_ION + win->addr[j] = (uint32_t)ion_start_addr + temp_size; +#else + win->addr[j] = win->fix_info.smem_start + temp_size; +#endif + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::win-%d add[%d] %x ", + __func__, win_num, j, win->addr[j]); + } + return 0; + +error: + win->fix_info.smem_start = 0; + + return -1; +} + +int window_pan_display(struct hwc_win_info_t *win) +{ + struct fb_var_screeninfo *lcd_info = &(win->lcd_info); + +#ifdef ENABLE_FIMD_VSYNC +#ifdef BOARD_USE_V4L2_ION + int fimd_num = 0; + if (ioctl(win->fd, FBIO_WAITFORVSYNC, &fimd_num) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIO_WAITFORVSYNC fail(%s)", + __func__, strerror(errno)); +#else + if (ioctl(win->fd, FBIO_WAITFORVSYNC, 0) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIO_WAITFORVSYNC fail(%s)", + __func__, strerror(errno)); +#endif +#endif + + lcd_info->yoffset = lcd_info->yres * win->buf_index; + + if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)", + __func__, + lcd_info->yres, + win->buf_index, lcd_info->yres_virtual, + strerror(errno)); + return -1; + } + return 0; +} + +int window_show(struct hwc_win_info_t *win) +{ + if (win->power_state == 0) { + if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)", + __func__, win->fd, strerror(errno)); + return -1; + } + win->power_state = 1; + } + return 0; +} + +int window_hide(struct hwc_win_info_t *win) +{ + if (win->power_state == 1) { + if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)", + __func__, win->fd, strerror(errno)); + return -1; + } + win->power_state = 0; + } + return 0; +} + +int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info) +{ + if (ioctl(fd, FBIOGET_VSCREENINFO, lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_VSCREENINFO failed : %s", + strerror(errno)); + return -1; + } + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: Default LCD x(%d),y(%d)", + __func__, lcd_info->xres, lcd_info->yres); + return 0; +} + +int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src) +{ + struct v4l2_format fmt; + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + struct v4l2_requestbuffers req; + +#ifdef BOARD_USE_V4L2_ION + /* You MUST initialize structure for v4l2 */ + memset(&fmt, 0, sizeof(fmt)); + memset(&cropcap, 0, sizeof(cropcap)); + memset(&crop, 0, sizeof(crop)); + memset(&req, 0, sizeof(req)); + + /* To set size & format for source image (DMA-INPUT) */ + fmt.fmt.pix_mp.num_planes = src->planes; + fmt.fmt.pix_mp.width = src->full_width; + fmt.fmt.pix_mp.height = src->full_height; + fmt.fmt.pix_mp.pixelformat = src->color_space; + fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; +#else + fmt.fmt.pix.width = src->full_width; + fmt.fmt.pix.height = src->full_height; + fmt.fmt.pix.pixelformat = src->color_space; + fmt.fmt.pix.field = V4L2_FIELD_NONE; +#endif + fmt.type = V4L2_BUF_TYPE_OUTPUT; + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::VIDIOC_S_FMT failed : errno=%d (%s)" + " : fd=%d\n", __func__, errno, strerror(errno), fd); + return -1; + } + + /* crop input size */ + crop.type = V4L2_BUF_TYPE_OUTPUT; + crop.c.width = src->width; + crop.c.height = src->height; +#ifdef BOARD_USE_V4L2_ION + crop.c.left = src->start_x; + crop.c.top = src->start_y; +#else + if (0x50 <= hw_ver) { + crop.c.left = src->start_x; + crop.c.top = src->start_y; + } else { + crop.c.left = 0; + crop.c.top = 0; + } + +#endif + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP :" + "crop.c.left : (%d), crop.c.top : (%d), crop.c.width : (%d), crop.c.height : (%d)", + __func__, crop.c.left, crop.c.top, crop.c.width, crop.c.height); + return -1; + } + + /* input buffer type */ + req.count = 1; + req.memory = V4L2_MEMORY_USERPTR; + req.type = V4L2_BUF_TYPE_OUTPUT; + + if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_set_dst(int fd, s5p_fimc_img_info *dst, + int rotation, int hflip, int vflip, unsigned int addr) +{ + struct v4l2_format sFormat; + struct v4l2_control vc; + struct v4l2_framebuffer fbuf; +#ifdef BOARD_USE_V4L2_ION + struct v4l2_crop crop; + struct v4l2_requestbuffers req; +#endif + int ret; + +#ifdef BOARD_USE_V4L2_ION + /* You MUST initialize structure for v4l2 */ + memset(&sFormat, 0, sizeof(sFormat)); + memset(&vc, 0, sizeof(vc)); + memset(&fbuf, 0, sizeof(fbuf)); + memset(&crop, 0, sizeof(crop)); + memset(&req, 0, sizeof(req)); +#endif + + /* set rotation configuration */ +#ifdef BOARD_USE_V4L2_ION + vc.id = V4L2_CID_ROTATE; +#else + vc.id = V4L2_CID_ROTATION; +#endif + vc.value = rotation; + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - rotation (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + + vc.id = V4L2_CID_HFLIP; + vc.value = hflip; + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - hflip (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + + vc.id = V4L2_CID_VFLIP; + vc.value = vflip; + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - vflip (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + +#ifdef BOARD_USE_V4L2_ION + /* set destination */ + sFormat.type = V4L2_BUF_TYPE_CAPTURE; + sFormat.fmt.pix_mp.width = dst->full_width; + sFormat.fmt.pix_mp.height = dst->full_height; + sFormat.fmt.pix_mp.pixelformat = dst->color_space; + sFormat.fmt.pix_mp.num_planes = dst->planes; + sFormat.fmt.pix.field = V4L2_FIELD_ANY; + + ret = ioctl(fd, VIDIOC_S_FMT, &sFormat); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FMT (%d)", __func__, ret); + return -1; + } + + /* set destination window */ + crop.type = V4L2_BUF_TYPE_CAPTURE; + crop.c.left = dst->start_x; + crop.c.top = dst->start_y; + crop.c.width = dst->width; + crop.c.height = dst->height; + + ret = ioctl(fd, VIDIOC_S_CROP, &crop); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP (%d)", __func__, ret); + return -1; + } + + /* input buffer type */ + req.count = 1; + req.type = V4L2_BUF_TYPE_CAPTURE; + req.memory = V4L2_MEMORY_USERPTR; + + ret = ioctl (fd, VIDIOC_REQBUFS, &req); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS (%d)", __func__, ret); + return -1; + } +#else + /* set size, format & address for destination image (DMA-OUTPUT) */ + ret = ioctl(fd, VIDIOC_G_FBUF, &fbuf); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_FBUF (%d)", __func__, ret); + return -1; + } + + fbuf.base = (void *)addr; + fbuf.fmt.width = dst->full_width; + fbuf.fmt.height = dst->full_height; + fbuf.fmt.pixelformat = dst->color_space; + + ret = ioctl(fd, VIDIOC_S_FBUF, &fbuf); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FBUF (%d)", __func__, ret); + return -1; + } + + /* set destination window */ + sFormat.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + sFormat.fmt.win.w.left = dst->start_x; + sFormat.fmt.win.w.top = dst->start_y; + sFormat.fmt.win.w.width = dst->width; + sFormat.fmt.win.w.height = dst->height; + + ret = ioctl(fd, VIDIOC_S_FMT, &sFormat); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FMT (%d)", __func__, ret); + return -1; + } +#endif + + return 0; +} + +int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type) +{ + if (-1 == ioctl(fd, VIDIOC_STREAMON, &type)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMON\n"); + return -1; + } + + return 0; +} + +int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type, int index) +{ +#ifdef BOARD_USE_V4L2_ION + struct v4l2_plane plane[3]; + int i; +#endif + struct v4l2_buffer buf; + int ret; + +#ifdef BOARD_USE_V4L2_ION + buf.length = fimc_buf->planes; +#else + buf.length = 0; + buf.m.userptr = (unsigned long)fimc_buf; +#endif + buf.memory = V4L2_MEMORY_USERPTR; + buf.index = index; + buf.type = type; + +#ifdef BOARD_USE_V4L2_ION + if (buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + for (i = 0; i < buf.length; i++) { + plane[i].m.userptr = fimc_buf->base[i]; + plane[i].length = fimc_buf->size[i]; + } + } + buf.m.planes = plane; +#endif + + ret = ioctl(fd, VIDIOC_QBUF, &buf); + if (0 > ret) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_QBUF : (%d)", ret); + return -1; + } + + return 0; +} + +int fimc_v4l2_dequeue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type) +{ + struct v4l2_buffer buf; +#ifdef BOARD_USE_V4L2_ION + struct v4l2_plane plane[3]; +#endif + +#ifdef BOARD_USE_V4L2_ION + buf.m.planes = plane; + buf.length = fimc_buf->planes; +#endif + buf.memory = V4L2_MEMORY_USERPTR; + buf.type = type; + + if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_DQBUF\n"); + return -1; + } + + return buf.index; +} + +int fimc_v4l2_stream_off(int fd, enum v4l2_buf_type type) +{ + if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMOFF\n"); + return -1; + } + + return 0; +} + +int fimc_v4l2_clr_buf(int fd, enum v4l2_buf_type type) +{ + struct v4l2_requestbuffers req; + + req.count = 0; + req.memory = V4L2_MEMORY_USERPTR; + req.type = type; + + if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_REQBUFS"); + } + + return 0; +} + +int fimc_v4l2_S_ctrl(int fd) +{ + struct v4l2_control vc; + + vc.id = V4L2_CID_CACHEABLE; + vc.value = 1; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_S_CTRL"); + return -1; + } + + return 0; +} + +int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_src_buf, struct fimc_buf *fimc_dst_buf) +{ +#ifdef CHECK_FPS + check_fps(); +#endif + +#ifdef BOARD_USE_V4L2_ION + if (fimc_v4l2_queue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_queue()"); + return -1; + } + + if (fimc_v4l2_queue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_queue()"); + return -2; + } + + if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_on()"); + return -3; + } + + if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_on()"); + return -4; + } +#else + if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_on()"); + return -5; + } + + if (fimc_v4l2_queue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_queue()"); + goto STREAM_OFF; + } +#endif + if (fimc_v4l2_dequeue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_dequeue()"); + return -6; + } +#ifdef BOARD_USE_V4L2_ION + if (fimc_v4l2_dequeue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_dequeue()"); + return -7; + } +#endif +STREAM_OFF: + if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_off()"); + return -8; + } +#ifdef BOARD_USE_V4L2_ION + if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_off()"); + return -9; + } +#endif + if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_clr_buf()"); + return -10; + } +#ifdef BOARD_USE_V4L2_ION + if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_CAPTURE)< 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_clr_buf()"); + return -11; + } +#endif + return 0; +} + +static int memcpy_rect(void *dst, void *src, int fullW, int fullH, int realW, int realH, int format) +{ + unsigned char *srcCb, *srcCr; + unsigned char *dstCb, *dstCr; + unsigned char *srcY, *dstY; + int srcCbOffset, srcCrOffset; + int dstCbOffset, dstFrameOffset, dstCrOffset; + int cbFullW, cbRealW, cbFullH, cbRealH; + int ySrcFW, ySrcFH, ySrcRW, ySrcRH; + int planes; + int i; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "++memcpy_rect()::" + "dst(0x%x),src(0x%x),f.w(%d),f.h(%d),r.w(%d),r.h(%d),format(0x%x)", + (unsigned int)dst, (unsigned int)src, fullW, fullH, realW, realH, format); + +// Set dst Y, Cb, Cr address for FIMC + { + cbFullW = fullW >> 1; + cbRealW = realW >> 1; + cbFullH = fullH >> 1; + cbRealH = realH >> 1; + dstFrameOffset = fullW * fullH; + dstCrOffset = cbFullW * cbFullH; + dstY = (unsigned char *)dst; + dstCb = (unsigned char *)dst + dstFrameOffset; + dstCr = (unsigned char *)dstCb + dstCrOffset; + } + +// Get src Y, Cb, Cr address for source buffer. +// Each address is aligned by 16's multiple for GPU both width and height. + { + ySrcFW = fullW; + ySrcFH = fullH; + ySrcRW = realW; + ySrcRH = realH; + srcCbOffset = EXYNOS4_ALIGN(ySrcRW,16)* EXYNOS4_ALIGN(ySrcRH,16); + srcCrOffset = EXYNOS4_ALIGN(cbRealW,16)* EXYNOS4_ALIGN(cbRealH,16); + srcY = (unsigned char *)src; + srcCb = (unsigned char *)src + srcCbOffset; + srcCr = (unsigned char *)srcCb + srcCrOffset; + } + SEC_HWC_Log(HWC_LOG_DEBUG, + "--memcpy_rect()::\n" + "dstY(0x%x),dstCb(0x%x),dstCr(0x%x) \n" + "srcY(0x%x),srcCb(0x%x),srcCr(0x%x) \n" + "cbRealW(%d),cbRealH(%d)", + (unsigned int)dstY,(unsigned int)dstCb,(unsigned int)dstCr, + (unsigned int)srcY,(unsigned int)srcCb,(unsigned int)srcCr, + cbRealW, cbRealH); + + if (format == HAL_PIXEL_FORMAT_YV12) { //YV12(Y,Cr,Cv) + planes = 3; +//This is code for VE, deleted temporory by SSONG 2011.09.22 +// This will be enabled later. +/* + //as defined in hardware.h, cb & cr full_width should be aligned to 16. ALIGN(y_stride/2, 16). + ////Alignment is hard coded to 16. + ////for example...check frameworks/media/libvideoeditor/lvpp/VideoEditorTools.cpp file for UV stride cal + cbSrcFW = (cbSrcFW + 15) & (~15); + srcCbOffset = ySrcFW * fullH; + srcCrOffset = srcCbOffset + ((cbSrcFW * fullH) >> 1); + srcY = (unsigned char *)src; + srcCb = (unsigned char *)src + srcCbOffset; + srcCr = (unsigned char *)src + srcCrOffset; +*/ + } else if ((format == HAL_PIXEL_FORMAT_YCbCr_420_P)) { + planes = 3; + } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { + planes = 2; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "use default memcpy instead of memcpy_rect"); + return -1; + } +//#define CHECK_PERF +#ifdef CHECK_PERF + struct timeval start, end; + gettimeofday(&start, NULL); +#endif + for (i = 0; i < realH; i++) + memcpy(dstY + fullW * i, srcY + ySrcFW * i, ySrcRW); + if (planes == 2) { + for (i = 0; i < cbRealH; i++) + memcpy(dstCb + ySrcFW * i, srcCb + ySrcFW * i, ySrcRW); + } else if (planes == 3) { + for (i = 0; i < cbRealH; i++) + memcpy(dstCb + cbFullW * i, srcCb + cbFullW * i, cbRealW); + for (i = 0; i < cbRealH; i++) + memcpy(dstCr + cbFullW * i, srcCr + cbFullW * i, cbRealW); + } +#ifdef CHECK_PERF + gettimeofday(&end, NULL); + SEC_HWC_Log(HWC_LOG_ERROR, "[COPY]=%d,",(end.tv_sec - start.tv_sec)*1000+(end.tv_usec - start.tv_usec)/1000); +#endif + + return 0; +} + +/*****************************************************************************/ +static int get_src_phys_addr(struct hwc_context_t *ctx, + sec_img *src_img, sec_rect *src_rect) +{ + s5p_fimc_t *fimc = &ctx->fimc; + struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[0]; + struct s3c_mem_dma_param s3c_mem_dma; +#ifdef USE_HW_PMEM + sec_pmem_alloc_t *pm_alloc = &ctx->sec_pmem.sec_pmem_alloc[0]; +#endif + + unsigned int src_virt_addr = 0; + unsigned int src_phys_addr = 0; + unsigned int src_frame_size = 0; + + struct pmem_region region; + ADDRS * addr; + + // error check routine + if (0 == src_img->base && !(src_img->usage & GRALLOC_USAGE_HW_FIMC1)) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s invalid src image base\n", __func__); + return 0; + } + + switch (src_img->mem_type) { + case HWC_PHYS_MEM_TYPE: + src_phys_addr = src_img->base + src_img->offset; + break; + + case HWC_VIRT_MEM_TYPE: + case HWC_UNKNOWN_MEM_TYPE: + switch (src_img->format) { + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + addr = (ADDRS *)(src_img->base); + fimc->params.src.buf_addr_phy_rgb_y = addr->addr_y; + fimc->params.src.buf_addr_phy_cb = addr->addr_cbcr; + + src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y; + if (0 == src_phys_addr) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s address error " + "(format=CUSTOM_YCbCr/YCrCb_420_SP Y-addr=0x%x " + "CbCr-Addr=0x%x)", + __func__, fimc->params.src.buf_addr_phy_rgb_y, + fimc->params.src.buf_addr_phy_cb); + return 0; + } + break; + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + addr = (ADDRS *)(src_img->base + src_img->offset); + fimc->params.src.buf_addr_phy_rgb_y = addr->addr_y; + src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y; + if (0 == src_phys_addr) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s address error " + "(format=CUSTOM_YCbCr/CbYCrY_422_I Y-addr=0x%x)", + __func__, fimc->params.src.buf_addr_phy_rgb_y); + return 0; + } + break; + default: +#ifdef BOARD_USE_V4L2_ION + fimc->params.src.buf_addr_phy_rgb_y = src_img->base; + fimc->params.src.buf_addr_phy_cb = src_img->base + src_img->uoffset; + fimc->params.src.buf_addr_phy_cr = src_img->base + src_img->uoffset + src_img->voffset; + src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y; + break; +#endif + if (src_img->usage & GRALLOC_USAGE_HW_FIMC1) { + fimc->params.src.buf_addr_phy_rgb_y = src_img->paddr; + fimc->params.src.buf_addr_phy_cb = src_img->paddr + src_img->uoffset; + fimc->params.src.buf_addr_phy_cr = src_img->paddr + src_img->uoffset + src_img->voffset; + src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y; + break; + } + // copy + src_frame_size = FRAME_SIZE(src_img->format, src_img->w, src_img->h); + if (src_frame_size == 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FRAME_SIZE fail", __func__); + return 0; + } + +#ifdef USE_HW_PMEM + if (0 <= checkPmem(&ctx->sec_pmem, 0, src_frame_size)) { + src_virt_addr = pm_alloc->virt_addr; + src_phys_addr = pm_alloc->phys_addr; + pm_alloc->size = src_frame_size; + } else +#endif + if (0 <= checkMem(&ctx->s3c_mem, 0, src_frame_size)) { + src_virt_addr = ptr_mem_alloc->vir_addr; + src_phys_addr = ptr_mem_alloc->phy_addr; + ptr_mem_alloc->size = src_frame_size; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::check_mem fail", __func__); + return 0; + } + if ((src_img->format == HAL_PIXEL_FORMAT_YCbCr_420_P) || + (src_img->format == HAL_PIXEL_FORMAT_YV12) || + (src_img->format == HAL_PIXEL_FORMAT_YCbCr_420_SP) || + (src_img->format == HAL_PIXEL_FORMAT_YCrCb_420_SP)) { + if (memcpy_rect((void *)src_virt_addr, (void*)((unsigned int)src_img->base), + src_img->f_w, src_img->f_h, src_rect->w, src_rect->h, src_img->format) != 0) + return 0; + } else { + memcpy((void *)src_virt_addr, (void*)((unsigned int)src_img->base), src_frame_size); + } + +#ifdef USE_HW_PMEM + if (pm_alloc->size == src_frame_size) { + region.offset = 0; + region.len = src_frame_size; + if (ioctl(ctx->sec_pmem.pmem_master_fd, PMEM_CACHE_FLUSH, ®ion) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::pmem cache flush fail ", __func__); + } +#endif + break; + } + } + + return src_phys_addr; +} + +static int get_dst_phys_addr(struct hwc_context_t *ctx, sec_img *dst_img, + sec_rect *dst_rect, int *dst_memcpy_flag) +{ + unsigned int dst_phys_addr = 0; + + if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base) + dst_phys_addr = dst_img->base; + else + dst_phys_addr = dst_img->base; + + return dst_phys_addr; +} + +static inline int rotateValueHAL2PP(unsigned char transform) +{ + int rotate_flag = transform & 0x7; + + switch (rotate_flag) { + case HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_ROT_180: return 180; + case HAL_TRANSFORM_ROT_270: return 270; + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_FLIP_H: return 0; + case HAL_TRANSFORM_FLIP_V: return 0; + } + return 0; +} + +static inline int hflipValueHAL2PP(unsigned char transform) +{ + int flip_flag = transform & 0x7; + switch (flip_flag) { + case HAL_TRANSFORM_FLIP_H: + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: + return 1; + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_180: + case HAL_TRANSFORM_ROT_270: + case HAL_TRANSFORM_FLIP_V: + break; + } + return 0; +} + +static inline int vflipValueHAL2PP(unsigned char transform) +{ + int flip_flag = transform & 0x7; + switch (flip_flag) { + case HAL_TRANSFORM_FLIP_V: + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: + return 1; + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_180: + case HAL_TRANSFORM_ROT_270: + case HAL_TRANSFORM_FLIP_H: + break; + } + return 0; +} + +static inline int multipleOf2(int number) +{ + if (number % 2 == 1) + return (number - 1); + else + return number; +} + +static inline int multipleOf4(int number) +{ + int remain_number = number % 4; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int multipleOf8(int number) +{ + int remain_number = number % 8; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int multipleOf16(int number) +{ + int remain_number = number % 16; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int widthOfPP(unsigned int ver, int pp_color_format, int number) +{ +#ifdef BOARD_USE_V4L2_ION + if (1) { +#else + if (0x50 <= ver) { +#endif + switch (pp_color_format) { + /* 422 1/2/3 plane */ + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_YUV422P: + + /* 420 2/3 plane */ + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + return multipleOf2(number); + + default : + return number; + } + } else { + switch (pp_color_format) { + case V4L2_PIX_FMT_RGB565: + return multipleOf8(number); + + case V4L2_PIX_FMT_RGB32: + return multipleOf4(number); + + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + return multipleOf4(number); + + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + return multipleOf8(number); + + case V4L2_PIX_FMT_YUV422P: + return multipleOf16(number); + + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + return multipleOf8(number); + + case V4L2_PIX_FMT_YUV420: + return multipleOf16(number); + + default : + return number; + } + } + return number; +} + +static inline int heightOfPP(int pp_color_format, int number) +{ + switch (pp_color_format) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + return multipleOf2(number); + + default : + return number; + break; + } + return number; +} + +static unsigned int get_yuv_bpp(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].bpp; +} + +static unsigned int get_yuv_planes(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].planes; +} + +static int runcFimcCore(struct hwc_context_t *ctx, + unsigned int src_phys_addr, sec_img *src_img, sec_rect *src_rect, + uint32_t src_color_space, + unsigned int dst_phys_addr, sec_img *dst_img, sec_rect *dst_rect, + uint32_t dst_color_space, int transform) +{ + s5p_fimc_t * fimc = &ctx->fimc; + s5p_fimc_params_t * params = &(fimc->params); + + struct fimc_buf fimc_src_buf; + int src_bpp, src_planes; + +#ifdef BOARD_USE_V4L2_ION + struct fimc_buf fimc_dst_buf; + int dst_bpp, dst_planes; + unsigned int src_frame_size = 0; + unsigned int dst_frame_size = 0; +#endif + unsigned int frame_size = 0; + + bool src_cbcr_order = true; + int rotate_value = rotateValueHAL2PP(transform); + int hflip = hflipValueHAL2PP(transform); + int vflip = vflipValueHAL2PP(transform); + + /* 1. param(fimc config)->src information + * - src_img,src_rect => s_fw,s_fh,s_w,s_h,s_x,s_y + */ + params->src.full_width = src_img->f_w; + params->src.full_height = src_img->f_h; + params->src.width = src_rect->w; + params->src.height = src_rect->h; + params->src.start_x = src_rect->x; + params->src.start_y = src_rect->y; + params->src.color_space = src_color_space; + params->src.buf_addr_phy_rgb_y = src_phys_addr; + +#ifdef BOARD_USE_V4L2_ION + params->dst.full_width = dst_img->f_w; + params->dst.full_height = dst_img->f_h; + params->dst.width = widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w); + params->dst.height = heightOfPP(dst_color_space, dst_rect->h); + params->dst.start_x = dst_rect->x; + params->dst.start_y = dst_rect->y; + params->dst.color_space = dst_color_space; + params->dst.buf_addr_phy_rgb_y = dst_phys_addr; +#endif + + /* check src minimum */ + if (src_rect->w < 16 || src_rect->h < 8) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s src size is not supported by fimc : f_w=%d f_h=%d " + "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__, + params->src.full_width, params->src.full_height, + params->src.start_x, params->src.start_y, + params->src.width, params->src.height, + src_rect->w, src_rect->h, + params->src.color_space); + return -1; + } + +#ifdef BOARD_USE_V4L2_ION +#else + /* 2. param(fimc config)->dst information + * - dst_img,dst_rect,rot => d_fw,d_fh,d_w,d_h,d_x,d_y + */ + switch (rotate_value) { + case 0: + params->dst.full_width = dst_img->f_w; + params->dst.full_height = dst_img->f_h; + + params->dst.start_x = dst_rect->x; + params->dst.start_y = dst_rect->y; + + params->dst.width = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w); + params->dst.height = heightOfPP(dst_color_space, dst_rect->h); + break; + case 90: + params->dst.full_width = dst_img->f_h; + params->dst.full_height = dst_img->f_w; + + params->dst.start_x = dst_rect->y; + params->dst.start_y = dst_img->f_w - (dst_rect->x + dst_rect->w); + + params->dst.width = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h); + params->dst.height = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w); + + if (0x50 > fimc->hw_ver) + params->dst.start_y += (dst_rect->w - params->dst.height); + break; + case 180: + params->dst.full_width = dst_img->f_w; + params->dst.full_height = dst_img->f_h; + + params->dst.start_x = dst_img->f_w - (dst_rect->x + dst_rect->w); + params->dst.start_y = dst_img->f_h - (dst_rect->y + dst_rect->h); + + params->dst.width = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w); + params->dst.height = heightOfPP(dst_color_space, dst_rect->h); + break; + case 270: + params->dst.full_width = dst_img->f_h; + params->dst.full_height = dst_img->f_w; + + params->dst.start_x = dst_img->f_h - (dst_rect->y + dst_rect->h); + params->dst.start_y = dst_rect->x; + + params->dst.width = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h); + params->dst.height = + widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w); + + if (0x50 > fimc->hw_ver) + params->dst.start_y += (dst_rect->w - params->dst.height); + break; + } + params->dst.color_space = dst_color_space; +#endif + + SEC_HWC_Log(HWC_LOG_DEBUG, + "runcFimcCore()::" + "SRC f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)=>" + "DST f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)", + params->src.full_width, params->src.full_height, + params->src.start_x, params->src.start_y, + params->src.width, params->src.height, + params->dst.full_width, params->dst.full_height, + params->dst.start_x, params->dst.start_y, + params->dst.width, params->dst.height); + + /* check dst minimum */ + if (dst_rect->w < 8 || dst_rect->h < 4) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s dst size is not supported by fimc : f_w=%d f_h=%d " + "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__, + params->dst.full_width, params->dst.full_height, + params->dst.start_x, params->dst.start_y, + params->dst.width, params->dst.height, + dst_rect->w, dst_rect->h, params->dst.color_space); + return -1; + } + /* check scaling limit + * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT + */ + if (((src_rect->w > dst_rect->w) && + ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) || + ((dst_rect->w > src_rect->w) && + ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s over scaling limit : src.w=%d dst.w=%d (limit=%d)", + __func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT); + return -1; + } + + /* 3. Set configuration related to destination (DMA-OUT) + * - set input format & size + * - crop input size + * - set input buffer + * - set buffer type (V4L2_MEMORY_USERPTR) + */ +#ifdef BOARD_USE_V4L2_ION + switch (dst_img->format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_BGRA_8888: + dst_planes = 1; + dst_bpp = 32; + break; + + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + dst_planes = 1; + dst_bpp = 16; + break; + } + + dst_frame_size = params->dst.width * params->dst.height ; + params->dst.planes = dst_planes; + + if (dst_planes == 1) { + fimc_dst_buf.base[0] = params->dst.buf_addr_phy_rgb_y; + if (dst_bpp == 32) + fimc_dst_buf.size[0] = dst_frame_size * 4; + else if (dst_bpp == 16) + fimc_dst_buf.size[0] = dst_frame_size * 2; + } +#endif + + if (fimc_v4l2_set_dst(fimc->dev_fd, ¶ms->dst, rotate_value, hflip, vflip, dst_phys_addr) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_dst is failed\n"); + return -1; + } + + /* 4. Set configuration related to source (DMA-INPUT) + * - set input format & size + * - crop input size + * - set input buffer + * - set buffer type (V4L2_MEMORY_USERPTR) + */ +#ifndef BOARD_USE_V4L2_ION + if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, ¶ms->src) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_src is failed\n"); + return -1; + } +#endif + + /* 5. Set input dma address (Y/RGB, Cb, Cr) + * - zero copy : mfc, camera + * - memcpy to pmem : SW dec(420P), video editor(YV12) + */ + switch (src_img->format) { + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + /* for video contents zero copy case */ + fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y; + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_YV12: + default: + if (src_img->format == HAL_PIXEL_FORMAT_YV12) + src_cbcr_order = false; + +#ifdef BOARD_USE_V4L2_ION + fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y; + if (src_cbcr_order == true) { + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[2] = params->src.buf_addr_phy_cr; + } else { + fimc_src_buf.base[1] = params->src.buf_addr_phy_cr; + fimc_src_buf.base[2] = params->src.buf_addr_phy_cb; + } + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore - Y=0x%X, U=0x%X, V=0x%X\n", + fimc_src_buf.base[0], fimc_src_buf.base[1],fimc_src_buf.base[2]); + src_frame_size = params->src.full_width * params->src.full_height; + fimc_src_buf.size[0] = src_frame_size; + fimc_src_buf.size[1] = src_frame_size >> 2; + fimc_src_buf.size[2] = src_frame_size >> 2; + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore - Y_length=%d, U_length=%d, V_length=%d\n", + fimc_src_buf.size[0], fimc_src_buf.size[1],fimc_src_buf.size[2]); + src_planes = get_yuv_planes(src_color_space); + + break; +#endif + + if (src_img->usage & GRALLOC_USAGE_HW_FIMC1) { + fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y; + if (src_cbcr_order == true) { + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[2] = params->src.buf_addr_phy_cr; + } + else { + fimc_src_buf.base[2] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[1] = params->src.buf_addr_phy_cr; + } + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore - Y=0x%X, U=0x%X, V=0x%X\n", + fimc_src_buf.base[0], fimc_src_buf.base[1],fimc_src_buf.base[2]); + break; + } + + /* set source Y image */ + fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y; + /* set source Cb,Cr images for 2 or 3 planes */ + src_bpp = get_yuv_bpp(src_color_space); + src_planes = get_yuv_planes(src_color_space); + if (2 == src_planes) { /* 2 planes */ + frame_size = params->src.full_width * params->src.full_height; + params->src.buf_addr_phy_cb = + params->src.buf_addr_phy_rgb_y + frame_size; + /* CbCr */ + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + } else if (3 == src_planes) { /* 3 planes */ + frame_size = params->src.full_width * params->src.full_height; + params->src.buf_addr_phy_cb = + params->src.buf_addr_phy_rgb_y + frame_size; + if (12 == src_bpp) + params->src.buf_addr_phy_cr = + params->src.buf_addr_phy_cb + (frame_size >> 2); + else + params->src.buf_addr_phy_cr = + params->src.buf_addr_phy_cb + (frame_size >> 1); + /* Cb, Cr */ + if (src_cbcr_order == true) { + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[2] = params->src.buf_addr_phy_cr; + } + else { + fimc_src_buf.base[2] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[1] = params->src.buf_addr_phy_cr; + } + } + break; + } + + /* 6. Run FIMC + * - stream on => queue => dequeue => stream off => clear buf + */ +#ifdef BOARD_USE_V4L2_ION + int ret = 0; + params->src.planes = src_planes; + + if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, ¶ms->src) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_src is failed\n"); + return -1; + } + + fimc_src_buf.planes = src_planes; + fimc_dst_buf.planes = dst_planes; + + ret = fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf, &fimc_dst_buf); + + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR,"fimc_handle_oneshot = %d\n",ret); + if (ret == -2) { + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT); + } else if (ret == -3) { + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT); + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_CAPTURE); + } + return ret; + } +#else + if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf, NULL) < 0) { + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT); + return -1; + } +#endif + + return 0; +} + +#ifdef SUB_TITLES_HWC +int createG2d(sec_g2d_t *g2d) +{ + g2d->dev_fd = open(SEC_G2D_DEV_NAME, O_RDWR); + + if (g2d->dev_fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::G2d open error (%d)", __func__, errno); + goto err; + } + + return 0; +err: + if (0 < g2d->dev_fd) + close(g2d->dev_fd); + g2d->dev_fd =0; + + return -1; +} + +int destroyG2d(sec_g2d_t *g2d) +{ + // close + if (0 < g2d->dev_fd) + close(g2d->dev_fd); + g2d->dev_fd = 0; + + return 0; +} +#endif + +int createFimc(s5p_fimc_t *fimc) +{ + struct v4l2_capability cap; + struct v4l2_format fmt; + struct v4l2_control vc; + + // open device file + if (fimc->dev_fd <= 0) + fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR); + + if (fimc->dev_fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Post processor open error (%d)", + __func__, errno); + goto err; + } + + // check capability + if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "VIDIOC_QUERYCAP failed"); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + SEC_HWC_Log(HWC_LOG_ERROR, "%d has no streaming support", fimc->dev_fd); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + SEC_HWC_Log(HWC_LOG_ERROR, "%d is no video output", fimc->dev_fd); + goto err; + } + + /* + * malloc fimc_outinfo structure + */ + fmt.type = V4L2_BUF_TYPE_OUTPUT; + if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_FMT", __func__); + goto err; + } + +#ifdef BOARD_USE_V4L2_ION +#else + vc.id = V4L2_CID_FIMC_VERSION; + vc.value = 0; + + if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_CTRL", __func__); + goto err; + } + fimc->hw_ver = vc.value; +#endif + + return 0; + +err: + if (0 < fimc->dev_fd) + close(fimc->dev_fd); + fimc->dev_fd =0; + + return -1; +} + +int destroyFimc(s5p_fimc_t *fimc) +{ + if (fimc->out_buf.virt_addr != NULL) { + fimc->out_buf.virt_addr = NULL; + fimc->out_buf.length = 0; + } + + // close + if (0 < fimc->dev_fd) + close(fimc->dev_fd); + fimc->dev_fd = 0; + + return 0; +} + +int runFimc(struct hwc_context_t *ctx, + struct sec_img *src_img, struct sec_rect *src_rect, + struct sec_img *dst_img, struct sec_rect *dst_rect, + uint32_t transform) +{ + s5p_fimc_t * fimc = &ctx->fimc; + + unsigned int src_phys_addr = 0; + unsigned int dst_phys_addr = 0; + int rotate_value = 0; + int flag_force_memcpy = 0; + int32_t src_color_space; + int32_t dst_color_space; + + /* 1. source address and size */ + src_phys_addr = get_src_phys_addr(ctx, src_img, src_rect); + if (0 == src_phys_addr) + return -1; + + /* 2. destination address and size */ + dst_phys_addr = get_dst_phys_addr(ctx, dst_img, dst_rect, &flag_force_memcpy); + if (0 == dst_phys_addr) + return -2; + + /* 3. check whether fimc supports the src format */ + src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); + if (0 > src_color_space) + return -3; + dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); + if (0 > dst_color_space) + return -4; + + /* 4. FIMC: src_rect of src_img => dst_rect of dst_img */ + if (runcFimcCore(ctx, src_phys_addr, src_img, src_rect, + (uint32_t)src_color_space, dst_phys_addr, dst_img, dst_rect, + (uint32_t)dst_color_space, transform) < 0) + return -5; + + if (flag_force_memcpy == 1) { +#ifdef USE_HW_PMEM + if (0 != ctx->sec_pmem.sec_pmem_alloc[1].size) { + struct s3c_mem_dma_param s3c_mem_dma; + + s3c_mem_dma.src_addr = + (unsigned long)(ctx->sec_pmem.sec_pmem_alloc[1].virt_addr); + s3c_mem_dma.size = ctx->sec_pmem.sec_pmem_alloc[1].size; + + ioctl(ctx->s3c_mem.fd, S3C_MEM_CACHE_INVAL, &s3c_mem_dma); + + memcpy((void*)((unsigned int)dst_img->base), + (void *)(ctx->sec_pmem.sec_pmem_alloc[1].virt_addr), + ctx->sec_pmem.sec_pmem_alloc[1].size); + } else +#endif + { + struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[1]; + struct s3c_mem_dma_param s3c_mem_dma; + + s3c_mem_dma.src_addr = (unsigned long)ptr_mem_alloc->vir_addr; + s3c_mem_dma.size = ptr_mem_alloc->size; + + ioctl(ctx->s3c_mem.fd, S3C_MEM_CACHE_INVAL, &s3c_mem_dma); + + memcpy((void*)((unsigned int)dst_img->base), + (void *)ptr_mem_alloc->vir_addr, ptr_mem_alloc->size); + } + } + + return 0; +} + +#ifdef SUB_TITLES_HWC +static int get_g2d_src_phys_addr(struct hwc_context_t *ctx, g2d_rect *src_rect) +{ + sec_g2d_t *g2d = &ctx->g2d; + struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[0]; +#ifdef USE_HW_PMEM + sec_pmem_alloc_t *pm_alloc = &ctx->sec_pmem.sec_pmem_alloc[0]; +#endif + + unsigned int src_virt_addr = 0; + unsigned int src_phys_addr = 0; + unsigned int src_frame_size = 0; + + struct pmem_region region; + + // error check routine + if (0 == src_rect->virt_addr) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s invalid src address\n", __func__); + return 0; + } + + src_frame_size = FRAME_SIZE(src_rect->color_format, + src_rect->full_w, src_rect->full_h); + if (src_frame_size == 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FRAME_SIZE fail", __func__); + return 0; + } + +#ifdef USE_HW_PMEM + if (0 <= checkPmem(&ctx->sec_pmem, 0, src_frame_size)) { + src_virt_addr = pm_alloc->virt_addr; + src_phys_addr = pm_alloc->phys_addr; + pm_alloc->size = src_frame_size; + } else +#endif + if (0 <= checkMem(&ctx->s3c_mem, 0, src_frame_size)) { + src_virt_addr = ptr_mem_alloc->vir_addr; + src_phys_addr = ptr_mem_alloc->phy_addr; + ptr_mem_alloc->size = src_frame_size; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::check_mem fail", __func__); + return 0; + } + memcpy((void *)src_virt_addr, (void*)((unsigned int)src_rect->virt_addr), src_frame_size); + + return src_phys_addr; +} + +int get_HAL_2_G2D_FORMAT(int format) +{ + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: return G2D_ABGR_8888; + case HAL_PIXEL_FORMAT_RGBX_8888: return G2D_XBGR_8888; + case HAL_PIXEL_FORMAT_BGRA_8888: return G2D_ARGB_8888; + case HAL_PIXEL_FORMAT_RGB_888: return G2D_PACKED_BGR_888; + case HAL_PIXEL_FORMAT_RGB_565: return G2D_RGB_565; + case HAL_PIXEL_FORMAT_RGBA_5551: return G2D_RGBA_5551; + case HAL_PIXEL_FORMAT_RGBA_4444: return G2D_RGBA_4444; + default: + return -1; + } +} + +static inline int rotateValueHAL2G2D(unsigned char transform) +{ + int rotate_flag = transform & 0x7; + + switch (rotate_flag) { + case HAL_TRANSFORM_ROT_90: return G2D_ROT_90; + case HAL_TRANSFORM_ROT_180: return G2D_ROT_180; + case HAL_TRANSFORM_ROT_270: return G2D_ROT_270; + default: + return G2D_ROT_0; + } +} + +int runG2d(struct hwc_context_t *ctx, g2d_rect *src_rect, g2d_rect *dst_rect, + uint32_t transform) +{ + sec_g2d_t * g2d = &ctx->g2d; + g2d_flag flag = {G2D_ROT_0, G2D_ALPHA_BLENDING_OPAQUE, 0, 0, 0, 0, 0, 0}; + int rotate_value = 0; + + // 1 : source address and size + src_rect->phys_addr = get_g2d_src_phys_addr(ctx, src_rect); + if (0 == src_rect->phys_addr) + return -1; + + // 2 : destination address and size + if (0 == dst_rect->phys_addr) + return -2; + + // check whether g2d supports the src format + src_rect->color_format = get_HAL_2_G2D_FORMAT(src_rect->color_format); + if (0 > src_rect->color_format) + return -3; + + dst_rect->color_format = get_HAL_2_G2D_FORMAT(dst_rect->color_format); + if (0 > dst_rect->color_format) + return -4; + + flag.rotate_val = rotateValueHAL2G2D(transform); + + // scale and rotate and alpha with FIMG + if(stretchSecFimg(src_rect, dst_rect, &flag) < 0) + return -5; + + return 0; +} +#endif + +int createMem(struct s3c_mem_t *mem, unsigned int index, unsigned int size) +{ + struct s3c_mem_alloc *ptr_mem_alloc; + struct s3c_mem_alloc mem_alloc_info; + + if (index >= NUM_OF_MEM_OBJ) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalid index (%d >= %d)", + __func__, index, NUM_OF_MEM_OBJ); + goto err; + } + + ptr_mem_alloc = &mem->mem_alloc[index]; + + if (mem->fd <= 0) { + mem->fd = open(S3C_MEM_DEV_NAME, O_RDWR); + if (mem->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::open(%s) fail(%s)", + __func__, S3C_MEM_DEV_NAME, strerror(errno)); + goto err; + } + } + + // kcoolsw : what the hell of this line?? + if (0 == size) + return 0; + + mem_alloc_info.size = size; + + if (ioctl(mem->fd, S3C_MEM_CACHEABLE_ALLOC, &mem_alloc_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_ALLOC(size : %d) fail", + __func__, mem_alloc_info.size); + goto err; + } + + ptr_mem_alloc->phy_addr = mem_alloc_info.phy_addr; + ptr_mem_alloc->vir_addr = mem_alloc_info.vir_addr; + ptr_mem_alloc->size = mem_alloc_info.size; + + return 0; + +err: + if (0 < mem->fd) + close(mem->fd); + mem->fd = 0; + + return 0; +} + +int destroyMem(struct s3c_mem_t *mem) +{ + int i; + struct s3c_mem_alloc *ptr_mem_alloc; + + if (mem->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalied fd(%d) fail", __func__, mem->fd); + return -1; + } + + for (i = 0; i < NUM_OF_MEM_OBJ; i++) { + ptr_mem_alloc = &mem->mem_alloc[i]; + + if (0 != ptr_mem_alloc->vir_addr) { + if (ioctl(mem->fd, S3C_MEM_FREE, ptr_mem_alloc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_FREE fail", __func__); + return -1; + } + + ptr_mem_alloc->phy_addr = 0; + ptr_mem_alloc->vir_addr = 0; + ptr_mem_alloc->size = 0; + } + } + + close(mem->fd); + mem->fd = 0; + + return 0; +} + +int checkMem(struct s3c_mem_t *mem, unsigned int index, unsigned int size) +{ + int ret; + struct s3c_mem_alloc *ptr_mem_alloc; + struct s3c_mem_alloc mem_alloc_info; + + if (index >= NUM_OF_MEM_OBJ) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalid index (%d >= %d)", __func__, + index, NUM_OF_MEM_OBJ); + return -1; + } + + if (mem->fd <= 0) { + ret = createMem(mem, index, size); + return ret; + } + + ptr_mem_alloc = &mem->mem_alloc[index]; + + if (ptr_mem_alloc->size < (int)size) { + if (0 < ptr_mem_alloc->size) { + // free allocated mem + if (ioctl(mem->fd, S3C_MEM_FREE, ptr_mem_alloc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_FREE fail", __func__); + return -1; + } + } + + // allocate mem with requested size + mem_alloc_info.size = size; + if (ioctl(mem->fd, S3C_MEM_CACHEABLE_ALLOC, &mem_alloc_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_ALLOC(size : %d) fail", + __func__, mem_alloc_info.size); + return -1; + } + + ptr_mem_alloc->phy_addr = mem_alloc_info.phy_addr; + ptr_mem_alloc->vir_addr = mem_alloc_info.vir_addr; + ptr_mem_alloc->size = mem_alloc_info.size; + } + + return 0; +} + +#ifdef USE_HW_PMEM +int createPmem(sec_pmem_t *pm, unsigned int buf_size) +{ + int master_fd, err = 0, i; + void *base; + unsigned int phys_base; + size_t size, sub_size[NUM_OF_MEM_OBJ]; + struct pmem_region region; + + master_fd = open(PMEM_DEVICE_DEV_NAME, O_RDWR, 0); + if (master_fd < 0) { + pm->pmem_master_fd = -1; + if (EACCES == errno) { + return 0; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::open(%s) fail(%s)", + __func__, PMEM_DEVICE_DEV_NAME, strerror(errno)); + return -errno; + } + } + + if (ioctl(master_fd, PMEM_GET_TOTAL_SIZE, ®ion) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "PMEM_GET_TOTAL_SIZE failed, default mode"); + size = 8<<20; // 8 MiB + } else { + size = region.len; + } + + base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0); + if (base == MAP_FAILED) { + SEC_HWC_Log(HWC_LOG_ERROR, "[%s] mmap failed : %d (%s)", __func__, + errno, strerror(errno)); + base = 0; + close(master_fd); + master_fd = -1; + return -errno; + } + + if (ioctl(master_fd, PMEM_GET_PHYS, ®ion) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "PMEM_GET_PHYS failed, limp mode"); + region.offset = 0; + } + + pm->pmem_master_fd = master_fd; + pm->pmem_master_base = base; + pm->pmem_total_size = size; + //pm->pmem_master_phys_base = region.offset; + phys_base = region.offset; + + // sec_pmem_alloc[0] for temporary buffer for source + sub_size[0] = buf_size; + sub_size[0] = roundUpToPageSize(sub_size[0]); + + for (i = 0; i < NUM_OF_MEM_OBJ; i++) { + sec_pmem_alloc_t *pm_alloc = &(pm->sec_pmem_alloc[i]); + int fd, ret; + int offset = i ? sub_size[i-1] : 0; + struct pmem_region sub = { offset, sub_size[i] }; + + // create the "sub-heap" + if (0 > (fd = open(PMEM_DEVICE_DEV_NAME, O_RDWR, 0))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] open failed (%dL) : %d (%s)", + __func__, i, __LINE__, errno, strerror(errno)); + return -errno; + } + + // connect to it + if (0 != (ret = ioctl(fd, PMEM_CONNECT, pm->pmem_master_fd))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_CONNECT) failed : %d (%s)", + __func__, i, errno, strerror(errno)); + close(fd); + return -errno; + } + + // make it available to the client process + if (0 != (ret = ioctl(fd, PMEM_MAP, &sub))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_MAP) failed : %d (%s)", + __func__, i, errno, strerror(errno)); + close(fd); + return -errno; + } + + pm_alloc->fd = fd; + pm_alloc->total_size = sub_size[i]; + pm_alloc->offset = offset; + pm_alloc->virt_addr = (unsigned int)base + (unsigned int)offset; + pm_alloc->phys_addr = (unsigned int)phys_base + (unsigned int)offset; + +#if defined (PMEM_DEBUG) + SEC_HWC_Log(HWC_LOG_DEBUG, "[%s] pm_alloc[%d] fd=%d total_size=%d " + "offset=0x%x virt_addr=0x%x phys_addr=0x%x", + __func__, i, pm_alloc->fd, pm_alloc->total_size, + pm_alloc->offset, pm_alloc->virt_addr, pm_alloc->phys_addr); +#endif + } + + return err; +} + +int destroyPmem(sec_pmem_t *pm) +{ + int i, err; + + for (i=0; isec_pmem_alloc[i]); + + if (0 <= pm_alloc->fd) { + struct pmem_region sub = { pm_alloc->offset, pm_alloc->total_size }; + + if (0 > (err = ioctl(pm_alloc->fd, PMEM_UNMAP, &sub))) + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_UNMAP) failed : %d (%s)", + __func__, i, errno, strerror(errno)); +#if defined (PMEM_DEBUG) + else + SEC_HWC_Log(HWC_LOG_DEBUG, + "[%s] pm_alloc[%d] unmap fd=%d total_size=%d offset=0x%x", + __func__, i, pm_alloc->fd, pm_alloc->total_size, + pm_alloc->offset); +#endif + close(pm_alloc->fd); + + pm_alloc->fd = -1; + pm_alloc->total_size = 0; + pm_alloc->offset = 0; + pm_alloc->virt_addr = 0; + pm_alloc->phys_addr = 0; + } + } + + if (0 <= pm->pmem_master_fd) { + munmap(pm->pmem_master_base, pm->pmem_total_size); + close(pm->pmem_master_fd); + pm->pmem_master_fd = -1; + } + + pm->pmem_master_base = 0; + pm->pmem_total_size = 0; + + return 0; +} + +int checkPmem(sec_pmem_t *pm, unsigned int index, unsigned int requested_size) +{ + sec_pmem_alloc_t *pm_alloc = &(pm->sec_pmem_alloc[index]); + + if (0 < pm_alloc->virt_addr && + requested_size <= (unsigned int)(pm_alloc->total_size)) + return 0; + + pm_alloc->size = 0; + return -1; +} + +#endif diff --git a/exynos4/hal/libhwcomposer/SecHWCUtils.h b/exynos4/hal/libhwcomposer/SecHWCUtils.h new file mode 100644 index 0000000..005b694 --- /dev/null +++ b/exynos4/hal/libhwcomposer/SecHWCUtils.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie, Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#ifndef ANDROID_SEC_HWC_UTILS_H_ +#define ANDROID_SEC_HWC_UTILS_H_ + +#include +#include +#include + +#include +#include +#include + +#ifdef BOARD_USE_V4L2_ION +#include +#include "s5p_fimc_v4l2.h" +#include "sec_utils_v4l2.h" +#else +#include +#include "s5p_fimc.h" +#include "sec_utils.h" +#endif + +#include +#include +#include +#include + +#include "linux/fb.h" + +#include "s3c_lcd.h" +#include "s3c_mem.h" +#include "sec_format.h" + +//#define HWC_DEBUG +#if defined(BOARD_USES_FIMGAPI) +#include "sec_g2d.h" +//#define SUB_TITLES_HWC +#endif + +#define NUM_OF_WIN (2) +#define NUM_OF_WIN_BUF (2) +#define NUM_OF_MEM_OBJ (1) + +#if (NUM_OF_WIN_BUF < 2) + #define ENABLE_FIMD_VSYNC +#endif + +#define MAX_RESIZING_RATIO_LIMIT (63) + +#ifdef SAMSUNG_EXYNOS4x12 +#ifdef BOARD_USE_V4L2_ION +#define PP_DEVICE_DEV_NAME "/dev/video4" +#else +#define PP_DEVICE_DEV_NAME "/dev/video3" +#endif +#endif + +#ifdef SAMSUNG_EXYNOS4210 +#define PP_DEVICE_DEV_NAME "/dev/video1" +#endif + +#define S3C_MEM_DEV_NAME "/dev/s3c-mem" +#define PMEM_DEVICE_DEV_NAME "/dev/pmem_gpu1" + +#ifdef BOARD_USE_V4L2_ION +#undef USE_HW_PMEM +#else +#define USE_HW_PMEM +#endif + +#define PMEM_SIZE (1920 * 1280 * 2) + +struct sec_rect { + int32_t x; + int32_t y; + int32_t w; + int32_t h; +}; + +struct sec_img { + uint32_t f_w; + uint32_t f_h; + uint32_t w; + uint32_t h; + uint32_t format; + uint32_t base; + uint32_t offset; + uint32_t paddr; + uint32_t uoffset; + uint32_t voffset; + int usage; + int mem_id; + int mem_type; +}; + +inline int SEC_MIN(int x, int y) +{ + return ((x < y) ? x : y); +} + +inline int SEC_MAX(int x, int y) +{ + return ((x > y) ? x : y); +} + +struct s3c_mem_t { + int fd; + struct s3c_mem_alloc mem_alloc[NUM_OF_MEM_OBJ]; +}; + +#ifdef USE_HW_PMEM +typedef struct __sec_pmem_alloc { + int fd; + int total_size; + int offset; + int size; + unsigned int virt_addr; + unsigned int phys_addr; +} sec_pmem_alloc_t; + +typedef struct __sec_pmem { + int pmem_master_fd; + void *pmem_master_base; + int pmem_total_size; + sec_pmem_alloc_t sec_pmem_alloc[NUM_OF_MEM_OBJ]; +} sec_pmem_t; + +inline size_t roundUpToPageSize(size_t x) +{ + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} +#endif + +struct hwc_win_info_t { + int fd; + int size; + sec_rect rect_info; + uint32_t addr[NUM_OF_WIN_BUF]; + int buf_index; + + int power_state; + int blending; + int layer_index; + int status; + int vsync; +#ifdef BOARD_USE_V4L2_ION + int ion_fd; +#endif + + struct fb_fix_screeninfo fix_info; + struct fb_var_screeninfo var_info; + struct fb_var_screeninfo lcd_info; +}; + +enum { + HWC_WIN_FREE = 0, + HWC_WIN_RESERVED, +}; + +enum { + HWC_UNKNOWN_MEM_TYPE = 0, + HWC_PHYS_MEM_TYPE, + HWC_VIRT_MEM_TYPE, +}; + +struct hwc_context_t { + hwc_composer_device_t device; + + /* our private state goes below here */ + struct hwc_win_info_t win[NUM_OF_WIN]; + struct fb_var_screeninfo lcd_info; + s5p_fimc_t fimc; +#ifdef SUB_TITLES_HWC + sec_g2d_t g2d; +#endif + struct s3c_mem_t s3c_mem; +#ifdef USE_HW_PMEM + sec_pmem_t sec_pmem; +#endif + int num_of_fb_layer; + int num_of_hwc_layer; + int num_2d_blit_layer; + uint32_t layer_prev_buf[NUM_OF_WIN]; +}; + +typedef enum _LOG_LEVEL { + HWC_LOG_DEBUG, + HWC_LOG_WARNING, + HWC_LOG_ERROR, +} HWC_LOG_LEVEL; + +#define SEC_HWC_LOG_TAG "SECHWC_LOG" + +#ifdef HWC_DEBUG +#define SEC_HWC_Log(a, ...) ((void)_SEC_HWC_Log(a, SEC_HWC_LOG_TAG, __VA_ARGS__)) +#else +#define SEC_HWC_Log(a, ...) \ + do { \ + if (a == HWC_LOG_ERROR) \ + ((void)_SEC_HWC_Log(a, SEC_HWC_LOG_TAG, __VA_ARGS__)); \ + } while (0) +#endif + +extern void _SEC_HWC_Log(HWC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); + +/* copied from gralloc module ..*/ +typedef struct { + native_handle_t base; + + /* These fields can be sent cross process. They are also valid + * to duplicate within the same process. + * + * A table is stored within psPrivateData on gralloc_module_t (this + * is obviously per-process) which maps stamps to a mapped + * PVRSRV_CLIENT_MEM_INFO in that process. Each map entry has a lock + * count associated with it, satisfying the requirements of the + * Android API. This also prevents us from leaking maps/allocations. + * + * This table has entries inserted either by alloc() + * (alloc_device_t) or map() (gralloc_module_t). Entries are removed + * by free() (alloc_device_t) and unmap() (gralloc_module_t). + * + * As a special case for framebuffer_device_t, framebuffer_open() + * will add and framebuffer_close() will remove from this table. + */ + +#define IMG_NATIVE_HANDLE_NUMFDS 1 + /* The `fd' field is used to "export" a meminfo to another process. + * Therefore, it is allocated by alloc_device_t, and consumed by + * gralloc_module_t. The framebuffer_device_t does not need a handle, + * and the special value IMG_FRAMEBUFFER_FD is used instead. + */ + int fd; + +#if 1 + int format; + int magic; + int flags; + int size; + int offset; + int base_addr; +#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(uint64_t) / sizeof(int)) + 4 + 6) +#else +#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(IMG_UINT64) / sizeof(int)) + 4) +#endif + /* A KERNEL unique identifier for any exported kernel meminfo. Each + * exported kernel meminfo will have a unique stamp, but note that in + * userspace, several meminfos across multiple processes could have + * the same stamp. As the native_handle can be dup(2)'d, there could be + * multiple handles with the same stamp but different file descriptors. + */ + uint64_t ui64Stamp; + + /* We could live without this, but it lets us perform some additional + * validation on the client side. Normally, we'd have no visibility + * of the allocated usage, just the lock usage. + */ + int usage; + + /* In order to do efficient cache flushes we need the buffer dimensions + * and format. These are available on the android_native_buffer_t, + * but the platform doesn't pass them down to the graphics HAL. + * + * TODO: Ideally the platform would be modified to not require this. + */ + int width; + int height; + int bpp; +} +__attribute__((aligned(sizeof(int)),packed)) sec_native_handle_t; + +int window_open (struct hwc_win_info_t *win, int id); +int window_close (struct hwc_win_info_t *win); +int window_set_pos (struct hwc_win_info_t *win); +int window_get_info (struct hwc_win_info_t *win, int win_num); +int window_pan_display(struct hwc_win_info_t *win); +int window_show (struct hwc_win_info_t *win); +int window_hide (struct hwc_win_info_t *win); +int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info); + +int createFimc (s5p_fimc_t *fimc); +int destroyFimc(s5p_fimc_t *fimc); +int runFimc(struct hwc_context_t *ctx, + struct sec_img *src_img, struct sec_rect *src_rect, + struct sec_img *dst_img, struct sec_rect *dst_rect, + uint32_t transform); + +#ifdef SUB_TITLES_HWC +int runG2d(struct hwc_context_t *ctx, + g2d_rect *src_rect, g2d_rect *dst_rect, + uint32_t transform); + +int destroyG2d(sec_g2d_t *g2d); +int createG2d(sec_g2d_t *g2d); +#endif + +int createMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size); +int destroyMem(struct s3c_mem_t *mem); +int checkMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size); + +#ifdef USE_HW_PMEM +int createPmem (sec_pmem_t *pm, unsigned int size); +int destroyPmem(sec_pmem_t *pm); +int checkPmem (sec_pmem_t *pm, unsigned int index, unsigned int size); +#endif + +#endif /* ANDROID_SEC_HWC_UTILS_H_*/ diff --git a/exynos4/hal/libhwconverter/Android.mk b/exynos4/hal/libhwconverter/Android.mk index ecda03b..c1ded53 100644 --- a/exynos4/hal/libhwconverter/Android.mk +++ b/exynos4/hal/libhwconverter/Android.mk @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) + LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) @@ -21,10 +23,13 @@ LOCAL_SHARED_LIBRARIES := liblog libutils libcutils libfimc LOCAL_SRC_FILES := HardwareConverter.cpp LOCAL_C_INCLUDES := \ - $(TOP)/$(BOARD_HAL_PATH)/include \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/sec_omx/include/khronos \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/sec_omx/include/sec + $(LOCAL_PATH)/../include \ + $(TOP)/$(TARGET_HAL_PATH)/include \ + $(TOP)/$(TARGET_OMX_PATH)/include/khronos \ + $(TOP)/$(TARGET_OMX_PATH)/include/sec LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libhwconverter include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos4/hal/libhwconverter/HardwareConverter.cpp b/exynos4/hal/libhwconverter/HardwareConverter.cpp index 3a66767..9ff6e55 100644 --- a/exynos4/hal/libhwconverter/HardwareConverter.cpp +++ b/exynos4/hal/libhwconverter/HardwareConverter.cpp @@ -15,7 +15,6 @@ */ #include - #include "SEC_OMX_Def.h" #include "SecFimc.h" #include "HardwareConverter.h" @@ -25,7 +24,7 @@ HardwareConverter::HardwareConverter() SecFimc* handle_fimc = new SecFimc(); mSecFimc = (void *)handle_fimc; - if (handle_fimc->create(SecFimc::DEV_2, SecFimc::MODE_MULTI_BUF, 1) == false) + if (handle_fimc->create(SecFimc::DEV_0, SecFimc::MODE_MULTI_BUF, 1) == false) bHWconvert_flag = 0; else bHWconvert_flag = 1; diff --git a/exynos4/hal/libhwjpeg/Android.mk b/exynos4/hal/libhwjpeg/Android.mk new file mode 100644 index 0000000..21a99fb --- /dev/null +++ b/exynos4/hal/libhwjpeg/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES:= \ + jpeg_hal_unit.c \ + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + +LOCAL_STATIC_LIBRARIES := \ + +LOCAL_MODULE:= libhwjpeg + +LOCAL_MODULE_TAGS := eng + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libhwjpeg/jpeg_hal_unit.c b/exynos4/hal/libhwjpeg/jpeg_hal_unit.c new file mode 100644 index 0000000..a0b4224 --- /dev/null +++ b/exynos4/hal/libhwjpeg/jpeg_hal_unit.c @@ -0,0 +1,572 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "libhwjpeg" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "jpeg_hal.h" + +#ifdef JPEG_PERF_MEAS +unsigned long measure_time(struct timeval *start, struct timeval *stop) +{ + unsigned long sec, usec, time; + + sec = stop->tv_sec - start->tv_sec; + + if (stop->tv_usec >= start->tv_usec) { + usec = stop->tv_usec - start->tv_usec; + } else { + usec = stop->tv_usec + 1000000 - start->tv_usec; + sec--; + } + + time = (sec * 1000000) + usec; + + return time; +} +#endif + +static int jpeg_v4l2_querycap(int fd) +{ + struct v4l2_capability cap; + int ret = 0; + + ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) + LOGE("[%s]: does not support streaming", __func__); + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) + LOGE("[%s]: does not support output", __func__); + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) + LOGE("[%s]: does not support capture", __func__); + + return ret; +} + +static int jpeg_v4l2_s_jpegcomp(int fd, int quality) +{ + struct v4l2_jpegcompression arg; + int ret = 0; + + arg.quality = quality; + + ret = ioctl(fd, VIDIOC_S_JPEGCOMP, &arg); + + return ret; +} + +static int jpeg_v4l2_s_fmt(int fd, enum v4l2_buf_type type, struct jpeg_config *config) +{ + struct v4l2_format fmt; + int ret = 0; + + fmt.type = type; + fmt.fmt.pix_mp.width = config->width; + fmt.fmt.pix_mp.height = config->height; + fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; + fmt.fmt.pix_mp.num_planes = config->num_planes; + + if (config->mode == JPEG_ENCODE) + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: /* fall through */ + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (config->mode == JPEG_ENCODE) { + fmt.fmt.pix_mp.pixelformat = config->pix.enc_fmt.in_fmt; + } else { + fmt.fmt.pix_mp.pixelformat = config->pix.dec_fmt.in_fmt; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = config->sizeJpeg; + } + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (config->mode == JPEG_ENCODE) { + fmt.fmt.pix_mp.pixelformat = config->pix.enc_fmt.out_fmt; + } else { + fmt.fmt.pix_mp.pixelformat = config->pix.dec_fmt.out_fmt; + fmt.fmt.pix_mp.width = config->scaled_width; + fmt.fmt.pix_mp.height = config->scaled_height; + } + break; + default: + LOGE("[%s]: invalid v4l2 buf type", __func__); + return -1; + } + + ret = ioctl(fd, VIDIOC_S_FMT, &fmt); + + return ret; +} + +static int jpeg_v4l2_g_fmt(int fd, enum v4l2_buf_type type, struct jpeg_config *config) +{ + struct v4l2_format fmt; + int ret = 0; + + fmt.type = type; + ret = ioctl(fd, VIDIOC_G_FMT, &fmt); + if (ret < 0) + return -1; + + config->width = fmt.fmt.pix_mp.width; + config->height = fmt.fmt.pix_mp.height; + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: /* fall through */ + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (config->mode == JPEG_ENCODE) + config->pix.enc_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; + else + config->pix.dec_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (config->mode == JPEG_ENCODE) + config->pix.enc_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; + else + config->pix.dec_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; + break; + default: + LOGE("[%s]: invalid v4l2 buf type", __func__); + return -1; + } + + return ret; +} + +int jpeghal_getconfig(int fd, struct jpeg_config *config) +{ + int ret = 0; + + ret = jpeg_v4l2_g_fmt(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, config); + if (ret < 0) { + LOGE("[%s]: input G_FMT failed", __func__); + return -1; + } + + ret = jpeg_v4l2_g_fmt(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, config); + if (ret < 0) + LOGE("[%s]: output G_FMT failed", __func__); + + return ret; +} + +static int jpeg_v4l2_reqbufs(int fd, int buf_cnt, struct jpeg_buf *buf) +{ + struct v4l2_requestbuffers req; + int ret = 0; + + memset(&req, 0, sizeof(req)); + + req.type = buf->buf_type; + req.memory = buf->memory; + + req.count = buf_cnt; + + ret = ioctl(fd, VIDIOC_REQBUFS, &req); + + return ret; +} + +static int jpeg_v4l2_querybuf(int fd, struct jpeg_buf *buf) +{ + struct v4l2_buffer v4l2_buf; + struct v4l2_plane plane[JPEG_MAX_PLANE_CNT]; + int i; + int ret = 0; + + memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane)); + + v4l2_buf.index = 0; + v4l2_buf.type = buf->buf_type; + v4l2_buf.memory = buf->memory; + v4l2_buf.length = buf->num_planes; + v4l2_buf.m.planes = plane; + + ret = ioctl(fd, VIDIOC_QUERYBUF, &v4l2_buf); + if (ret < 0) { + LOGE("[%s:%d]: VIDIOC_QUERYBUF failed", __func__, ret); + return ret; + } + + for (i= 0; i < buf->num_planes; i++) { + buf->length[i] = v4l2_buf.m.planes[i].length; + buf->start[i] = (char *) mmap(0, buf->length[i], + PROT_READ | PROT_WRITE, MAP_SHARED, fd, + v4l2_buf.m.planes[i].m.mem_offset); + + //LOGI("[%s]: buf.start[%d] = %p, length = %d", __func__, 0, buf->start[0], buf->length[0]); + if (buf->start[0] == MAP_FAILED) { + LOGE("[%s]: mmap failed", __func__); + return -1; + } + } + + return ret; +} + +static int jpeg_v4l2_qbuf(int fd, struct jpeg_buf *buf) +{ + struct v4l2_buffer v4l2_buf; + struct v4l2_plane plane[JPEG_MAX_PLANE_CNT]; + int i; + int ret = 0; + + memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer)); + memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane)); + + v4l2_buf.index = 0; + v4l2_buf.type = buf->buf_type; + v4l2_buf.memory = buf->memory; + v4l2_buf.length = buf->num_planes; + v4l2_buf.m.planes = plane; + + if (buf->memory == V4L2_MEMORY_USERPTR) { + for (i = 0; i < buf->num_planes; i++) { + v4l2_buf.m.planes[i].m.userptr = (unsigned long)buf->start[i]; + v4l2_buf.m.planes[i].length = buf->length[i]; + } + } + + ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buf); + if (ret < 0) { + LOGE("[%s:%d] QBUF failed", __func__, ret); + return -1; + } + + return ret; +} + +static int jpeg_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory) +{ + struct v4l2_buffer buf; + int ret = 0; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + buf.type = type; + buf.memory = memory; + + ret = ioctl(fd, VIDIOC_DQBUF, &buf); + if (ret < 0) { + LOGE("[%s:%d] DQBUF failed", __func__, ret); + return -1; + } + + return ret; +} + +static int jpeg_v4l2_streamon(int fd, enum v4l2_buf_type type) +{ + int ret = 0; + + ret = ioctl(fd, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOGE("[%s:%d] STREAMON failed", __func__, ret); + return -1; + } + + return ret; +} + +static int jpeg_v4l2_streamoff(int fd, enum v4l2_buf_type type) +{ + int ret = 0; + + ret = ioctl(fd, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOGE("[%s:%d] STREAMOFF failed", __func__, ret); + return -1; + } + + return ret; +} + +int jpeghal_dec_init() +{ + int fd; + int ret = 0; + + fd = open(JPEG_DEC_NODE, O_RDWR, 0); + + if (fd < 0) { + LOGE("[%s]: JPEG dec open failed", __func__); + return -1; + } + + ret = jpeg_v4l2_querycap(fd); + if (ret < 0) { + LOGE("[%s]: QUERYCAP failed", __func__); + return -1; + } + + return fd; +} + +int jpeghal_enc_init() +{ + int fd; + int ret = 0; + + fd = open(JPEG_ENC_NODE, O_RDWR, 0); + if (fd < 0) { + LOGE("[%s]: JPEG enc open failed", __func__); + return -1; + } + + ret = jpeg_v4l2_querycap(fd); + if (ret < 0) { + LOGE("[%s]: QUERYCAP failed", __func__); + return -1; + } + + return fd; +} + +int jpeghal_dec_setconfig(int fd, struct jpeg_config *config) +{ + int ret = 0; + + config->mode = JPEG_DECODE; + + ret = jpeg_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, config); + if (ret < 0) { + LOGE("[%s]: decoder input S_FMT failed", __func__); + return -1; + } + + ret = jpeg_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, config); + if (ret < 0) { + LOGE("[%s]: decoder output S_FMT failed", __func__); + return -1; + } + + return ret; +} + +int jpeghal_dec_getconfig(int fd, struct jpeg_config *config) +{ + int ret = 0; + + jpeghal_getconfig(fd, config); + + return ret; +} + +int jpeghal_enc_setconfig(int fd, struct jpeg_config *config) +{ + int ret = 0; + + ret = jpeg_v4l2_s_jpegcomp(fd, config->enc_qual); + if (ret < 0) { + LOGE("[%s]: S_JPEGCOMP failed", __func__); + return -1; + } + + config->mode = JPEG_ENCODE; + + ret = jpeg_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, config); + if (ret < 0) { + LOGE("[%s]: encoder input S_FMT failed", __func__); + return -1; + } + + ret = jpeg_v4l2_s_fmt(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, config); + if (ret < 0) { + LOGE("[%s]: encoder output S_FMT failed", __func__); + return -1; + } + + return ret; +} + +int jpeghal_enc_getconfig(int fd, struct jpeg_config *config) +{ + int ret = 0; + + jpeghal_getconfig(fd, config); + + return ret; +} + +int jpeghal_set_inbuf(int fd, struct jpeg_buf *buf) +{ + int ret = 0; + + buf->buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + ret = jpeg_v4l2_reqbufs(fd, 1, buf); + if (ret < 0) { + LOGE("[%s:%d]: Input REQBUFS failed", __func__, ret); + return -1; + } + + if (buf->memory == V4L2_MEMORY_MMAP) { + ret = jpeg_v4l2_querybuf(fd, buf); + if (ret < 0) { + LOGE("[%s:%d]: Input QUERYBUF failed", __func__, ret); + return -1; + } + } + + return ret; +} + +int jpeghal_set_outbuf(int fd, struct jpeg_buf *buf) +{ + int ret = 0; + + buf->buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = jpeg_v4l2_reqbufs(fd, 1, buf); + if (ret < 0) { + LOGE("[%s:%d]: Output REQBUFS failed", __func__, ret); + return -1; + } + + if (buf->memory == V4L2_MEMORY_MMAP) { + ret = jpeg_v4l2_querybuf(fd, buf); + if (ret < 0) { + LOGE("[%s:%d]: Output QUERYBUF failed", __func__, ret); + return -1; + } + } + + return ret; +} + +static int jpeg_exe(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf) +{ + int ret = 0; + + ret = jpeg_v4l2_qbuf(fd, in_buf); + if (ret < 0) { + LOGE("[%s:%d]: Input QBUF failed", __func__, ret); + return -1; + } + + ret = jpeg_v4l2_qbuf(fd, out_buf); + if (ret < 0) { + LOGE("[%s:%d]: Output QBUF failed", __func__, ret); + return -1; + } + + ret = jpeg_v4l2_streamon(fd, in_buf->buf_type); + ret = jpeg_v4l2_streamon(fd, out_buf->buf_type); + + ret = jpeg_v4l2_dqbuf(fd, in_buf->buf_type, in_buf->memory); + ret = jpeg_v4l2_dqbuf(fd, out_buf->buf_type, out_buf->memory); + + return ret; +} + +int jpeghal_dec_exe(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf) +{ + int ret = 0; + + ret = jpeg_exe(fd, in_buf, out_buf); + if (ret < 0) + LOGE("[%s]: JPEG decoding is failed", __func__); + + return ret; +} + +int jpeghal_enc_exe(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf) +{ + int ret = 0; + + ret = jpeg_exe(fd, in_buf, out_buf); + if (ret < 0) + LOGE("[%s]: JPEG Encoding is failed", __func__); + + return ret; +} + +int jpeghal_deinit(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf) +{ + int ret = 0; + + jpeg_v4l2_streamoff(fd, in_buf->buf_type); + jpeg_v4l2_streamoff(fd, out_buf->buf_type); + + if (in_buf->memory == V4L2_MEMORY_MMAP) + munmap((char *)(in_buf->start[0]), in_buf->length[0]); + + if (out_buf->memory == V4L2_MEMORY_MMAP) + munmap((char *)(out_buf->start[0]), out_buf->length[0]); + + jpeg_v4l2_reqbufs(fd, 0, in_buf); + + jpeg_v4l2_reqbufs(fd, 0, out_buf); + + ret = close(fd); + + return ret; +} + +int jpeghal_s_ctrl(int fd, int cid, int value) +{ + struct v4l2_control vc; + int ret = 0; + + vc.id = cid; + vc.value = value; + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret != 0) { + LOGE("[%s] ioctl : cid(%d), value(%d)\n", __func__, cid, value); + return -1; + } + + return ret; +} + +int jpeghal_g_ctrl(int fd, int id) +{ + struct v4l2_control ctrl; + int ret = 0; + + ctrl.id = id; + + ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); + if (ret < 0) { + LOGE("[%s] ioctl : cid(%d)\n", __func__, ctrl.id); + return -1; + } + + return ctrl.value; +} diff --git a/exynos4/hal/liblights/Android.mk b/exynos4/hal/liblights/Android.mk deleted file mode 100644 index 995bd02..0000000 --- a/exynos4/hal/liblights/Android.mk +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (C) 2011 The Android Open Source Project -# Copyright (C) 2011 The CyanogenMod Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) -# HAL module implemenation, not prelinked and stored in -# hw/..so -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := lights.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw - -LOCAL_SHARED_LIBRARIES := liblog - -LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM) - -LOCAL_MODULE_TAGS := optional - -include $(BUILD_SHARED_LIBRARY) - diff --git a/exynos4/hal/liblights/NOTICE b/exynos4/hal/liblights/NOTICE deleted file mode 100644 index f921593..0000000 --- a/exynos4/hal/liblights/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/exynos4/hal/liblights/lights.c b/exynos4/hal/liblights/lights.c deleted file mode 100644 index 7cbe9d4..0000000 --- a/exynos4/hal/liblights/lights.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * Copyright (C) 2011 The CyanogenMod Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#define LOG_TAG "lights" -#define LOG_NDEBUG 0 - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/******************************************************************************/ - -static pthread_once_t g_init = PTHREAD_ONCE_INIT; -static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; -static int g_enable_touchlight = -1; - -#ifdef EXYNOS4210_TABLET -char const*const PANEL_FILE - = "/sys/class/backlight/backlight/brightness"; -#else -char const*const PANEL_FILE - = "/sys/class/backlight/panel/brightness"; - -char const*const BUTTON_POWER - = "/sys/class/sec/sec_touchkey/enable_disable"; - -char const*const BUTTON_FILE - = "/sys/class/sec/sec_touchkey/brightness"; -#endif - -void init_globals(void) -{ - // init the mutex - pthread_mutex_init(&g_lock, NULL); -} - -void -load_settings() -{ - FILE* fp = fopen("/data/.disable_touchlight", "r"); - if (!fp) { - g_enable_touchlight = 1; - } else { - g_enable_touchlight = (int)(fgetc(fp)); - if (g_enable_touchlight == '1') - g_enable_touchlight = 1; - else - g_enable_touchlight = 0; - - fclose(fp); - } -} - -static int -write_int(char const* path, int value) -{ - int fd; - static int already_warned = 0; - - fd = open(path, O_RDWR); - if (fd >= 0) { - char buffer[20]; - int bytes = sprintf(buffer, "%d\n", value); - int amt = write(fd, buffer, bytes); - close(fd); - return amt == -1 ? -errno : 0; - } else { - if (already_warned == 0) { - LOGE("write_int failed to open %s\n", path); - already_warned = 1; - } - return -errno; - } -} - -static int -is_lit(struct light_state_t const* state) -{ - return state->color & 0x00ffffff; -} - -static int -rgb_to_brightness(struct light_state_t const* state) -{ - int color = state->color & 0x00ffffff; - return ((77*((color>>16)&0x00ff)) - + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; -} - -static int -set_light_backlight(struct light_device_t* dev, - struct light_state_t const* state) -{ - load_settings(); - - int err = 0; - int brightness = rgb_to_brightness(state); - - pthread_mutex_lock(&g_lock); - err = write_int(PANEL_FILE, brightness); - -#ifndef EXYNOS4210_TABLET - if (g_enable_touchlight == -1 || g_enable_touchlight > 0) - err = write_int(BUTTON_FILE, brightness > 0 ? 1 : 0); -#endif - - pthread_mutex_unlock(&g_lock); - - return err; -} - -static int -set_light_keyboard(struct light_device_t* dev, - struct light_state_t const* state) -{ - return 0; -} - -static int -set_light_buttons(struct light_device_t* dev, - struct light_state_t const* state) -{ -#ifdef EXYNOS4210_TABLET - return 0; -#else - - load_settings(); - - int err = 0; - - pthread_mutex_lock(&g_lock); - LOGD("set_light_button on=%d\n", g_enable_touchlight ? 1 : 0); - err = write_int(BUTTON_FILE, g_enable_touchlight ? 1 : 0); - pthread_mutex_unlock(&g_lock); - - return err; -#endif -} - -static int -set_light_battery(struct light_device_t* dev, - struct light_state_t const* state) -{ - return 0; -} - -static int -set_light_notification(struct light_device_t* dev, - struct light_state_t const* state) -{ - return 0; -} - -static int -set_light_attention(struct light_device_t* dev, - struct light_state_t const* state) -{ - return 0; -} - -static int -close_lights(struct light_device_t *dev) -{ - if (dev) { - free(dev); - } - return 0; -} - - -/******************************************************************************/ -static int open_lights(const struct hw_module_t* module, char const* name, - struct hw_device_t** device) -{ - int (*set_light)(struct light_device_t* dev, - struct light_state_t const* state); - - if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) { - set_light = set_light_backlight; - } - else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) { - set_light = set_light_keyboard; - } - else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) { - set_light = set_light_buttons; - } - else if (0 == strcmp(LIGHT_ID_BATTERY, name)) { - set_light = set_light_battery; - } - else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) { - set_light = set_light_notification; - } - else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) { - set_light = set_light_attention; - } - else { - return -EINVAL; - } - - pthread_once(&g_init, init_globals); - - struct light_device_t *dev = malloc(sizeof(struct light_device_t)); - memset(dev, 0, sizeof(*dev)); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t*)module; - dev->common.close = (int (*)(struct hw_device_t*))close_lights; - dev->set_light = set_light; - - *device = (struct hw_device_t*)dev; - return 0; -} - - -static struct hw_module_methods_t lights_module_methods = { - .open = open_lights, -}; - -const struct hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = LIGHTS_HARDWARE_MODULE_ID, - .name = "Samsung Exynos4210 Lights Module", - .author = "The CyanogenMod Project", - .methods = &lights_module_methods, -}; diff --git a/exynos4/hal/libs5pjpeg/Android.mk b/exynos4/hal/libs5pjpeg/Android.mk index e1ac187..c6d8cf6 100644 --- a/exynos4/hal/libs5pjpeg/Android.mk +++ b/exynos4/hal/libs5pjpeg/Android.mk @@ -15,9 +15,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH) \ - $(BOARD_HAL_PATH)/include \ +LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include LOCAL_SRC_FILES:= \ jpeg_api.c \ diff --git a/exynos4/hal/libsensors/AkmSensor.cpp b/exynos4/hal/libsensors/AkmSensor.cpp deleted file mode 100644 index 98a17cb..0000000 --- a/exynos4/hal/libsensors/AkmSensor.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ak8973b.h" - -#include -#include "AkmSensor.h" - -//#define LOG_NDEBUG 0 - -/*****************************************************************************/ - -int (*akm_is_sensor_enabled)(uint32_t sensor_type); -int (*akm_enable_sensor)(uint32_t sensor_type); -int (*akm_disable_sensor)(uint32_t sensor_type); -int (*akm_set_delay)(uint32_t sensor_type, uint64_t delay); - -int stub_is_sensor_enabled(uint32_t sensor_type) { - return 0; -} - -int stub_enable_disable_sensor(uint32_t sensor_type) { - return -ENODEV; -} - -int stub_set_delay(uint32_t sensor_type, uint64_t delay) { - return -ENODEV; -} - -AkmSensor::AkmSensor() -: SensorBase(NULL, NULL), - mEnabled(0), - mPendingMask(0), - mInputReader(32) -{ - /* Open the library before opening the input device. The library - * creates a uinput device. - */ - if (loadAKMLibrary() == 0) { - data_name = "compass_sensor"; - data_fd = openInput("compass_sensor"); - } - - memset(mPendingEvents, 0, sizeof(mPendingEvents)); - - mPendingEvents[Accelerometer].version = sizeof(sensors_event_t); - mPendingEvents[Accelerometer].sensor = ID_A; - mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER; - mPendingEvents[Accelerometer].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; - - mPendingEvents[MagneticField].version = sizeof(sensors_event_t); - mPendingEvents[MagneticField].sensor = ID_M; - mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; - mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH; - - mPendingEvents[Orientation ].version = sizeof(sensors_event_t); - mPendingEvents[Orientation ].sensor = ID_O; - mPendingEvents[Orientation ].type = SENSOR_TYPE_ORIENTATION; - mPendingEvents[Orientation ].orientation.status = SENSOR_STATUS_ACCURACY_HIGH; - - // read the actual value of all sensors if they're enabled already - struct input_absinfo absinfo; - short flags = 0; - - if (akm_is_sensor_enabled(SENSOR_TYPE_ACCELEROMETER)) { - mEnabled |= 1<= numSensors) - return -EINVAL; - - int newState = en ? 1 : 0; - int err = 0; - - if ((uint32_t(newState)<type; - if (type == EV_REL) { - processEvent(event->code, event->value); - mInputReader.next(); - } else if (type == EV_SYN) { - int64_t time = timevalToNano(event->time); - for (int j=0 ; count && mPendingMask && jcode); - mInputReader.next(); - } - } - return numEventReceived; -} - -void AkmSensor::processEvent(int code, int value) -{ - switch (code) { - case EVENT_TYPE_ACCEL_X: - mPendingMask |= 1< -#include -#include -#include - - -#include "sensors.h" -#include "SensorBase.h" -#include "InputEventReader.h" - -/*****************************************************************************/ - -struct input_event; - -class AkmSensor : public SensorBase { -public: - AkmSensor(); - virtual ~AkmSensor(); - - enum { - Accelerometer = 0, - MagneticField = 1, - Orientation = 2, - numSensors - }; - - virtual int setDelay(int32_t handle, int64_t ns); - virtual int enable(int32_t handle, int enabled); - virtual int readEvents(sensors_event_t* data, int count); - void processEvent(int code, int value); - -private: - int loadAKMLibrary(); - int update_delay(); - void *mLibAKM; - uint32_t mEnabled; - uint32_t mPendingMask; - InputEventCircularReader mInputReader; - sensors_event_t mPendingEvents[numSensors]; - uint64_t mDelays[numSensors]; -}; - -/*****************************************************************************/ - -#endif // ANDROID_AKM_SENSOR_H diff --git a/exynos4/hal/libsensors/Android.mk b/exynos4/hal/libsensors/Android.mk deleted file mode 100644 index 15c29a2..0000000 --- a/exynos4/hal/libsensors/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -LOCAL_PATH := $(call my-dir) - -ifneq ($(TARGET_SIMULATOR),true) - -# HAL module implemenation, not prelinked, and stored in -# hw/..so -include $(CLEAR_VARS) - -LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM) - -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw - -LOCAL_MODULE_TAGS := optional - -LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\" -LOCAL_SRC_FILES := \ - sensors.cpp \ - SensorBase.cpp \ - LightSensor.cpp \ - ProximitySensor.cpp \ - AkmSensor.cpp \ - GyroSensor.cpp \ - InputEventReader.cpp - -LOCAL_SHARED_LIBRARIES := liblog libcutils libdl -LOCAL_PRELINK_MODULE := false - -include $(BUILD_SHARED_LIBRARY) - -endif # !TARGET_SIMULATOR diff --git a/exynos4/hal/libsensors/GyroSensor.cpp b/exynos4/hal/libsensors/GyroSensor.cpp deleted file mode 100644 index ef0c01c..0000000 --- a/exynos4/hal/libsensors/GyroSensor.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "GyroSensor.h" - -#define FETCH_FULL_EVENT_BEFORE_RETURN 1 -#define IGNORE_EVENT_TIME 350000000 -/*****************************************************************************/ - -GyroSensor::GyroSensor() - : SensorBase(NULL, "gyro_sensor"), - mEnabled(0), - mInputReader(4), - mHasPendingEvent(false), - mEnabledTime(0) -{ - mPendingEvent.version = sizeof(sensors_event_t); - mPendingEvent.sensor = ID_GY; - mPendingEvent.type = SENSOR_TYPE_GYROSCOPE; - memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); - - if (data_fd) { - strcpy(input_sysfs_path, "/sys/class/input/"); - strcat(input_sysfs_path, input_name); - strcat(input_sysfs_path, "/device/"); - input_sysfs_path_len = strlen(input_sysfs_path); - enable(0, 1); - } -} - -GyroSensor::~GyroSensor() { - if (mEnabled) { - enable(0, 0); - } -} - -int GyroSensor::setInitialState() { - struct input_absinfo absinfo_x; - struct input_absinfo absinfo_y; - struct input_absinfo absinfo_z; - float value; - if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_x) && - !ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_y) && - !ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_z)) { - value = absinfo_x.value; - mPendingEvent.data[0] = value * CONVERT_GYRO_X; - value = absinfo_x.value; - mPendingEvent.data[1] = value * CONVERT_GYRO_Y; - value = absinfo_x.value; - mPendingEvent.data[2] = value * CONVERT_GYRO_Z; - mHasPendingEvent = true; - } - return 0; -} - -int GyroSensor::enable(int32_t, int en) { - int flags = en ? 1 : 0; - if (flags != mEnabled) { - int fd; - strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); - fd = open(input_sysfs_path, O_RDWR); - if (fd >= 0) { - char buf[2]; - int err; - buf[1] = 0; - if (flags) { - buf[0] = '1'; - mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME; - } else { - buf[0] = '0'; - } - err = write(fd, buf, sizeof(buf)); - close(fd); - mEnabled = flags; - setInitialState(); - return 0; - } - return -1; - } - return 0; -} - -bool GyroSensor::hasPendingEvents() const { - return mHasPendingEvent; -} - -int GyroSensor::setDelay(int32_t handle, int64_t delay_ns) -{ - int fd; - strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); - fd = open(input_sysfs_path, O_RDWR); - if (fd >= 0) { - char buf[80]; - sprintf(buf, "%lld", delay_ns); - write(fd, buf, strlen(buf)+1); - close(fd); - return 0; - } - return -1; -} - -int GyroSensor::readEvents(sensors_event_t* data, int count) -{ - if (count < 1) - return -EINVAL; - - if (mHasPendingEvent) { - mHasPendingEvent = false; - mPendingEvent.timestamp = getTimestamp(); - *data = mPendingEvent; - return mEnabled ? 1 : 0; - } - - ssize_t n = mInputReader.fill(data_fd); - if (n < 0) - return n; - - int numEventReceived = 0; - input_event const* event; - -#if FETCH_FULL_EVENT_BEFORE_RETURN -again: -#endif - while (count && mInputReader.readEvent(&event)) { - int type = event->type; - if (type == EV_REL) { - float value = event->value; - if (event->code == EVENT_TYPE_GYRO_X) { - mPendingEvent.data[0] = value * CONVERT_GYRO_X; - } else if (event->code == EVENT_TYPE_GYRO_Y) { - mPendingEvent.data[1] = value * CONVERT_GYRO_Y; - } else if (event->code == EVENT_TYPE_GYRO_Z) { - mPendingEvent.data[2] = value * CONVERT_GYRO_Z; - } - } else if (type == EV_SYN) { - mPendingEvent.timestamp = timevalToNano(event->time); - if (mEnabled) { - if (mPendingEvent.timestamp >= mEnabledTime) { - *data++ = mPendingEvent; - numEventReceived++; - } - count--; - } - } else { - LOGE("GyroSensor: unknown event (type=%d, code=%d)", - type, event->code); - } - mInputReader.next(); - } - -#if FETCH_FULL_EVENT_BEFORE_RETURN - /* if we didn't read a complete event, see if we can fill and - try again instead of returning with nothing and redoing poll. */ - if (numEventReceived == 0 && mEnabled == 1) { - n = mInputReader.fill(data_fd); - if (n) - goto again; - } -#endif - - return numEventReceived; -} - diff --git a/exynos4/hal/libsensors/GyroSensor.h b/exynos4/hal/libsensors/GyroSensor.h deleted file mode 100644 index e8997de..0000000 --- a/exynos4/hal/libsensors/GyroSensor.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_GYRO_SENSOR_H -#define ANDROID_GYRO_SENSOR_H - -#include -#include -#include -#include - -#include "sensors.h" -#include "SensorBase.h" -#include "InputEventReader.h" - -/*****************************************************************************/ - -struct input_event; - -class GyroSensor : public SensorBase { - int mEnabled; - InputEventCircularReader mInputReader; - sensors_event_t mPendingEvent; - bool mHasPendingEvent; - char input_sysfs_path[PATH_MAX]; - int input_sysfs_path_len; - int64_t mEnabledTime; - - int setInitialState(); - -public: - GyroSensor(); - virtual ~GyroSensor(); - virtual int readEvents(sensors_event_t* data, int count); - virtual bool hasPendingEvents() const; - virtual int setDelay(int32_t handle, int64_t ns); - virtual int enable(int32_t handle, int enabled); -}; - -/*****************************************************************************/ - -#endif // ANDROID_GYRO_SENSOR_H diff --git a/exynos4/hal/libsensors/InputEventReader.cpp b/exynos4/hal/libsensors/InputEventReader.cpp deleted file mode 100644 index 1014f29..0000000 --- a/exynos4/hal/libsensors/InputEventReader.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "InputEventReader.h" - -/*****************************************************************************/ - -struct input_event; - -InputEventCircularReader::InputEventCircularReader(size_t numEvents) - : mBuffer(new input_event[numEvents * 2]), - mBufferEnd(mBuffer + numEvents), - mHead(mBuffer), - mCurr(mBuffer), - mFreeSpace(numEvents) -{ -} - -InputEventCircularReader::~InputEventCircularReader() -{ - delete [] mBuffer; -} - -ssize_t InputEventCircularReader::fill(int fd) -{ - size_t numEventsRead = 0; - if (mFreeSpace) { - const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); - if (nread<0 || nread % sizeof(input_event)) { - // we got a partial event!! - return nread<0 ? -errno : -EINVAL; - } - - numEventsRead = nread / sizeof(input_event); - if (numEventsRead) { - mHead += numEventsRead; - mFreeSpace -= numEventsRead; - if (mHead > mBufferEnd) { - size_t s = mHead - mBufferEnd; - memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); - mHead = mBuffer + s; - } - } - } - - return numEventsRead; -} - -ssize_t InputEventCircularReader::readEvent(input_event const** events) -{ - *events = mCurr; - ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; - return available ? 1 : 0; -} - -void InputEventCircularReader::next() -{ - mCurr++; - mFreeSpace++; - if (mCurr >= mBufferEnd) { - mCurr = mBuffer; - } -} diff --git a/exynos4/hal/libsensors/InputEventReader.h b/exynos4/hal/libsensors/InputEventReader.h deleted file mode 100644 index 180aade..0000000 --- a/exynos4/hal/libsensors/InputEventReader.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INPUT_EVENT_READER_H -#define ANDROID_INPUT_EVENT_READER_H - -#include -#include -#include -#include - -/*****************************************************************************/ - -struct input_event; - -class InputEventCircularReader -{ - struct input_event* const mBuffer; - struct input_event* const mBufferEnd; - struct input_event* mHead; - struct input_event* mCurr; - ssize_t mFreeSpace; - -public: - InputEventCircularReader(size_t numEvents); - ~InputEventCircularReader(); - ssize_t fill(int fd); - ssize_t readEvent(input_event const** events); - void next(); -}; - -/*****************************************************************************/ - -#endif // ANDROID_INPUT_EVENT_READER_H diff --git a/exynos4/hal/libsensors/LightSensor.cpp b/exynos4/hal/libsensors/LightSensor.cpp deleted file mode 100644 index 1d4f0e4..0000000 --- a/exynos4/hal/libsensors/LightSensor.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "LightSensor.h" - -// #define LOG_NDEBUG 0 - -/*****************************************************************************/ - -LightSensor::LightSensor() - : SensorBase(NULL, "light_sensor"), - mEnabled(0), - mInputReader(4), - mHasPendingEvent(false) -{ - mPendingEvent.version = sizeof(sensors_event_t); - mPendingEvent.sensor = ID_L; - mPendingEvent.type = SENSOR_TYPE_LIGHT; - memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); - - if (data_fd) { - strcpy(input_sysfs_path, "/sys/class/input/"); - strcat(input_sysfs_path, input_name); - strcat(input_sysfs_path, "/device/"); - input_sysfs_path_len = strlen(input_sysfs_path); - enable(0, 1); - } -} - -LightSensor::~LightSensor() { - if (mEnabled) { - enable(0, 0); - } -} - -int LightSensor::setInitialState() { - struct input_absinfo absinfo; - if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_LIGHT), &absinfo)) { - // make sure to report an event immediately - mHasPendingEvent = true; - mPendingEvent.light = absinfo.value; - } - return 0; -} - -int LightSensor::setDelay(int32_t handle, int64_t ns) -{ - int fd; - strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); - fd = open(input_sysfs_path, O_RDWR); - if (fd >= 0) { - char buf[80]; - sprintf(buf, "%lld", ns); - write(fd, buf, strlen(buf)+1); - close(fd); - return 0; - } - return -1; -} - -int LightSensor::enable(int32_t handle, int en) -{ - int flags = en ? 1 : 0; - if (flags != mEnabled) { - int fd; - strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); - fd = open(input_sysfs_path, O_RDWR); - if (fd >= 0) { - char buf[2]; - int err; - buf[1] = 0; - if (flags) { - buf[0] = '1'; - } else { - buf[0] = '0'; - } - err = write(fd, buf, sizeof(buf)); - close(fd); - mEnabled = flags; - return 0; - } - return -1; - } - return 0; -} - -bool LightSensor::hasPendingEvents() const { - return mHasPendingEvent; -} - -int LightSensor::readEvents(sensors_event_t* data, int count) -{ - if (count < 1) - return -EINVAL; - - if (mHasPendingEvent) { - mHasPendingEvent = false; - mPendingEvent.timestamp = getTimestamp(); - *data = mPendingEvent; - return mEnabled ? 1 : 0; - } - - ssize_t n = mInputReader.fill(data_fd); - if (n < 0) - return n; - - int numEventReceived = 0; - input_event const* event; - - while (count && mInputReader.readEvent(&event)) { - int type = event->type; - if (type == EV_ABS) { - if (event->code == EVENT_TYPE_LIGHT) { - if (event->value != -1) { - LOGV("LightSensor: event (value=%d)", event->value); - // FIXME: not sure why we're getting -1 sometimes - mPendingEvent.light = event->value; - } - } - } else if (type == EV_SYN) { - mPendingEvent.timestamp = timevalToNano(event->time); - if (mEnabled) { - *data++ = mPendingEvent; - count--; - numEventReceived++; - } - } else { - LOGE("LightSensor: unknown event (type=%d, code=%d)", - type, event->code); - } - mInputReader.next(); - } - - return numEventReceived; -} diff --git a/exynos4/hal/libsensors/LightSensor.h b/exynos4/hal/libsensors/LightSensor.h deleted file mode 100644 index 85e65d9..0000000 --- a/exynos4/hal/libsensors/LightSensor.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_LIGHT_SENSOR_H -#define ANDROID_LIGHT_SENSOR_H - -#include -#include -#include -#include - -#include "sensors.h" -#include "SensorBase.h" -#include "InputEventReader.h" - -/*****************************************************************************/ - -struct input_event; - -class LightSensor : public SensorBase { - int mEnabled; - InputEventCircularReader mInputReader; - sensors_event_t mPendingEvent; - bool mHasPendingEvent; - char input_sysfs_path[PATH_MAX]; - int input_sysfs_path_len; - - float indexToValue(size_t index) const; - int setInitialState(); - -public: - LightSensor(); - virtual ~LightSensor(); - virtual int readEvents(sensors_event_t* data, int count); - virtual bool hasPendingEvents() const; - virtual int setDelay(int32_t handle, int64_t ns); - virtual int enable(int32_t handle, int enabled); -}; - -/*****************************************************************************/ - -#endif // ANDROID_LIGHT_SENSOR_H diff --git a/exynos4/hal/libsensors/MODULE_LICENSE_APACHE2 b/exynos4/hal/libsensors/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 diff --git a/exynos4/hal/libsensors/ProximitySensor.cpp b/exynos4/hal/libsensors/ProximitySensor.cpp deleted file mode 100644 index 46424a5..0000000 --- a/exynos4/hal/libsensors/ProximitySensor.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "ProximitySensor.h" - -/*****************************************************************************/ - -ProximitySensor::ProximitySensor() - : SensorBase(NULL, "proximity_sensor"), - mEnabled(0), - mInputReader(4), - mHasPendingEvent(false) -{ - mPendingEvent.version = sizeof(sensors_event_t); - mPendingEvent.sensor = ID_P; - mPendingEvent.type = SENSOR_TYPE_PROXIMITY; - memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); - - if (data_fd) { - strcpy(input_sysfs_path, "/sys/class/input/"); - strcat(input_sysfs_path, input_name); - strcat(input_sysfs_path, "/device/"); - input_sysfs_path_len = strlen(input_sysfs_path); - enable(0, 1); - } -} - -ProximitySensor::~ProximitySensor() { - if (mEnabled) { - enable(0, 0); - } -} - -int ProximitySensor::setInitialState() { - struct input_absinfo absinfo; - if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo)) { - // make sure to report an event immediately - mHasPendingEvent = true; - mPendingEvent.distance = indexToValue(absinfo.value); - } - return 0; -} - -int ProximitySensor::enable(int32_t, int en) { - int flags = en ? 1 : 0; - if (flags != mEnabled) { - int fd; - strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); - fd = open(input_sysfs_path, O_RDWR); - if (fd >= 0) { - char buf[2]; - buf[1] = 0; - if (flags) { - buf[0] = '1'; - } else { - buf[0] = '0'; - } - write(fd, buf, sizeof(buf)); - close(fd); - mEnabled = flags; - setInitialState(); - return 0; - } - return -1; - } - return 0; -} - -bool ProximitySensor::hasPendingEvents() const { - return mHasPendingEvent; -} - -int ProximitySensor::readEvents(sensors_event_t* data, int count) -{ - if (count < 1) - return -EINVAL; - - if (mHasPendingEvent) { - mHasPendingEvent = false; - mPendingEvent.timestamp = getTimestamp(); - *data = mPendingEvent; - return mEnabled ? 1 : 0; - } - - ssize_t n = mInputReader.fill(data_fd); - if (n < 0) - return n; - - int numEventReceived = 0; - input_event const* event; - - while (count && mInputReader.readEvent(&event)) { - int type = event->type; - if (type == EV_ABS) { - if (event->code == EVENT_TYPE_PROXIMITY) { - mPendingEvent.distance = indexToValue(event->value); - } - } else if (type == EV_SYN) { - mPendingEvent.timestamp = timevalToNano(event->time); - if (mEnabled) { - *data++ = mPendingEvent; - count--; - numEventReceived++; - } - } else { - LOGE("ProximitySensor: unknown event (type=%d, code=%d)", - type, event->code); - } - mInputReader.next(); - } - - return numEventReceived; -} - -float ProximitySensor::indexToValue(size_t index) const -{ - LOGV("ProximitySensor: Index = %zu", index); - return index * PROXIMITY_THRESHOLD_CM; -} diff --git a/exynos4/hal/libsensors/ProximitySensor.h b/exynos4/hal/libsensors/ProximitySensor.h deleted file mode 100644 index 08ea49c..0000000 --- a/exynos4/hal/libsensors/ProximitySensor.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_PROXIMITY_SENSOR_H -#define ANDROID_PROXIMITY_SENSOR_H - -#include -#include -#include -#include - -#include "sensors.h" -#include "SensorBase.h" -#include "InputEventReader.h" - -/*****************************************************************************/ - -struct input_event; - -class ProximitySensor : public SensorBase { - int mEnabled; - InputEventCircularReader mInputReader; - sensors_event_t mPendingEvent; - bool mHasPendingEvent; - char input_sysfs_path[PATH_MAX]; - int input_sysfs_path_len; - - int setInitialState(); - float indexToValue(size_t index) const; - -public: - ProximitySensor(); - virtual ~ProximitySensor(); - virtual int readEvents(sensors_event_t* data, int count); - virtual bool hasPendingEvents() const; - virtual int enable(int32_t handle, int enabled); -}; - -/*****************************************************************************/ - -#endif // ANDROID_PROXIMITY_SENSOR_H diff --git a/exynos4/hal/libsensors/SensorBase.cpp b/exynos4/hal/libsensors/SensorBase.cpp deleted file mode 100644 index d448eb2..0000000 --- a/exynos4/hal/libsensors/SensorBase.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "SensorBase.h" - -/*****************************************************************************/ - -SensorBase::SensorBase( - const char* dev_name, - const char* data_name) - : dev_name(dev_name), data_name(data_name), - dev_fd(-1), data_fd(-1) -{ - if (data_name) { - data_fd = openInput(data_name); - } -} - -SensorBase::~SensorBase() { - if (data_fd >= 0) { - close(data_fd); - } - if (dev_fd >= 0) { - close(dev_fd); - } -} - -int SensorBase::open_device() { - if (dev_fd<0 && dev_name) { - dev_fd = open(dev_name, O_RDONLY); - LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno)); - } - return 0; -} - -int SensorBase::close_device() { - if (dev_fd >= 0) { - close(dev_fd); - dev_fd = -1; - } - return 0; -} - -int SensorBase::getFd() const { - if (!data_name) { - return dev_fd; - } - return data_fd; -} - -int SensorBase::setDelay(int32_t handle, int64_t ns) { - return 0; -} - -bool SensorBase::hasPendingEvents() const { - return false; -} - -int64_t SensorBase::getTimestamp() { - struct timespec t; - t.tv_sec = t.tv_nsec = 0; - clock_gettime(CLOCK_MONOTONIC, &t); - return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; -} - -int SensorBase::openInput(const char* inputName) { - int fd = -1; - const char *dirname = "/dev/input"; - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - dir = opendir(dirname); - if(dir == NULL) - return -1; - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - while((de = readdir(dir))) { - if(de->d_name[0] == '.' && - (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) - continue; - strcpy(filename, de->d_name); - fd = open(devname, O_RDONLY); - if (fd>=0) { - char name[80]; - if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { - name[0] = '\0'; - } - if (!strcmp(name, inputName)) { - strcpy(input_name, filename); - break; - } else { - close(fd); - fd = -1; - } - } - } - closedir(dir); - LOGE_IF(fd<0, "couldn't find '%s' input device", inputName); - return fd; -} diff --git a/exynos4/hal/libsensors/SensorBase.h b/exynos4/hal/libsensors/SensorBase.h deleted file mode 100644 index bb4d055..0000000 --- a/exynos4/hal/libsensors/SensorBase.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_SENSOR_BASE_H -#define ANDROID_SENSOR_BASE_H - -#include -#include -#include -#include - - -/*****************************************************************************/ - -struct sensors_event_t; - -class SensorBase { -protected: - const char* dev_name; - const char* data_name; - char input_name[PATH_MAX]; - int dev_fd; - int data_fd; - - int openInput(const char* inputName); - static int64_t getTimestamp(); - - - static int64_t timevalToNano(timeval const& t) { - return t.tv_sec*1000000000LL + t.tv_usec*1000; - } - - int open_device(); - int close_device(); - -public: - SensorBase( - const char* dev_name, - const char* data_name); - - virtual ~SensorBase(); - - virtual int readEvents(sensors_event_t* data, int count) = 0; - virtual bool hasPendingEvents() const; - virtual int getFd() const; - virtual int setDelay(int32_t handle, int64_t ns); - virtual int enable(int32_t handle, int enabled) = 0; -}; - -/*****************************************************************************/ - -#endif // ANDROID_SENSOR_BASE_H diff --git a/exynos4/hal/libsensors/ak8973b.h b/exynos4/hal/libsensors/ak8973b.h deleted file mode 100644 index 9b7ab60..0000000 --- a/exynos4/hal/libsensors/ak8973b.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Definitions for akm8973 compass chip. - */ -#ifndef AKM8973_H -#define AKM8973_H - -#include - -#define AKM8973_I2C_NAME "ak8973b" - -#define AKMIO 0xA1 - -/* IOCTLs for AKM library */ -#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char*) -#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char*) -#define ECS_IOCTL_RESET _IO(AKMIO, 0x03) -#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x04, short) -#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[SENSOR_DATA_SIZE]) -#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12]) -#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int) -#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int) -#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, int64_t) -#define ECS_IOCTL_GET_PROJECT_NAME _IOR(AKMIO, 0x0D, char[64]) -#define ECS_IOCTL_GET_MATRIX _IOR(AKMIO, 0x0E, short [4][3][3]) - -/* IOCTLs for APPs */ -#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short) -#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short) -#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short) -#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short) -#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short) -#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short) -#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short) -#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17) -#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, int64_t) -#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY - -/* Set raw magnetic vector flag */ -#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short) - -/* Get raw magnetic vector flag */ -#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short) - -struct akm8973_platform_data { - short layouts[4][3][3]; - char project_name[64]; - int gpio_RST; - int gpio_INT; -}; - -#endif diff --git a/exynos4/hal/libsensors/sensors.cpp b/exynos4/hal/libsensors/sensors.cpp deleted file mode 100644 index 6f0bdad..0000000 --- a/exynos4/hal/libsensors/sensors.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Sensors" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "sensors.h" - -#include "LightSensor.h" -#include "ProximitySensor.h" -#include "AkmSensor.h" -#include "GyroSensor.h" - -/*****************************************************************************/ - -#define DELAY_OUT_TIME 0x7FFFFFFF - -#define LIGHT_SENSOR_POLLTIME 2000000000 - - -#define SENSORS_ACCELERATION (1<getFd(); - mPollFds[light].events = POLLIN; - mPollFds[light].revents = 0; - - mSensors[proximity] = new ProximitySensor(); - mPollFds[proximity].fd = mSensors[proximity]->getFd(); - mPollFds[proximity].events = POLLIN; - mPollFds[proximity].revents = 0; - - mSensors[akm] = new AkmSensor(); - mPollFds[akm].fd = mSensors[akm]->getFd(); - mPollFds[akm].events = POLLIN; - mPollFds[akm].revents = 0; - - mSensors[gyro] = new GyroSensor(); - mPollFds[gyro].fd = mSensors[gyro]->getFd(); - mPollFds[gyro].events = POLLIN; - mPollFds[gyro].revents = 0; - - int wakeFds[2]; - int result = pipe(wakeFds); - LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); - fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); - fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); - mWritePipeFd = wakeFds[1]; - - mPollFds[wake].fd = wakeFds[0]; - mPollFds[wake].events = POLLIN; - mPollFds[wake].revents = 0; -} - -sensors_poll_context_t::~sensors_poll_context_t() { - for (int i=0 ; ienable(handle, enabled); - if (enabled && !err) { - const char wakeMessage(WAKE_MESSAGE); - int result = write(mWritePipeFd, &wakeMessage, 1); - LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); - } - return err; -} - -int sensors_poll_context_t::setDelay(int handle, int64_t ns) { - - int index = handleToDriver(handle); - if (index < 0) return index; - return mSensors[index]->setDelay(handle, ns); -} - -int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) -{ - int nbEvents = 0; - int n = 0; - - do { - // see if we have some leftover from the last poll() - for (int i=0 ; count && ihasPendingEvents())) { - int nb = sensor->readEvents(data, count); - if (nb < count) { - // no more data for this sensor - mPollFds[i].revents = 0; - } - count -= nb; - nbEvents += nb; - data += nb; - } - } - - if (count) { - // we still have some room, so try to see if we can get - // some events immediately or just wait if we don't have - // anything to return - n = poll(mPollFds, numFds, nbEvents ? 0 : -1); - if (n<0) { - LOGE("poll() failed (%s)", strerror(errno)); - return -errno; - } - if (mPollFds[wake].revents & POLLIN) { - char msg; - int result = read(mPollFds[wake].fd, &msg, 1); - LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); - LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); - mPollFds[wake].revents = 0; - } - } - // if we have events and space, go read them - } while (n && count); - - return nbEvents; -} - -/*****************************************************************************/ - -static int poll__close(struct hw_device_t *dev) -{ - sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; - if (ctx) { - delete ctx; - } - return 0; -} - -static int poll__activate(struct sensors_poll_device_t *dev, - int handle, int enabled) { - sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; - return ctx->activate(handle, enabled); -} - -static int poll__setDelay(struct sensors_poll_device_t *dev, - int handle, int64_t ns) { - sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; - return ctx->setDelay(handle, ns); -} - -static int poll__poll(struct sensors_poll_device_t *dev, - sensors_event_t* data, int count) { - sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; - return ctx->pollEvents(data, count); -} - -/*****************************************************************************/ - -/** Open a new instance of a sensor device using name */ -static int open_sensors(const struct hw_module_t* module, const char* id, - struct hw_device_t** device) -{ - int status = -EINVAL; - sensors_poll_context_t *dev = new sensors_poll_context_t(); - - memset(&dev->device, 0, sizeof(sensors_poll_device_t)); - - dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = 0; - dev->device.common.module = const_cast(module); - dev->device.common.close = poll__close; - dev->device.activate = poll__activate; - dev->device.setDelay = poll__setDelay; - dev->device.poll = poll__poll; - - *device = &dev->device.common; - status = 0; - - return status; -} - diff --git a/exynos4/hal/libsensors/sensors.h b/exynos4/hal/libsensors/sensors.h deleted file mode 100644 index ecc6fed..0000000 --- a/exynos4/hal/libsensors/sensors.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_SENSORS_H -#define ANDROID_SENSORS_H - -#include -#include -#include -#include - -#include - -#include -#include - -__BEGIN_DECLS - -/*****************************************************************************/ - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -#define ID_A (0) -#define ID_M (1) -#define ID_O (2) -#define ID_L (3) -#define ID_P (4) -#define ID_GY (5) - -/*****************************************************************************/ - -/* - * The SENSORS Module - */ - -/* the CM3663 is a binary proximity sensor that triggers around 6 cm on - * this hardware */ -#define PROXIMITY_THRESHOLD_CM 6.0f - -/*****************************************************************************/ - -#define AKM_DEVICE_NAME "/dev/akm8975" -#define CM_DEVICE_NAME "/dev/i2c11" // FIXME Proximity -#define LS_DEVICE_NAME "/dev/i2c11" // FIXME Lig - -/* - E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) - E/Sensors ( 2656): AkmSensor: processing event (type=0, code=0) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=8) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=3) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=4) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=5) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=0) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=1) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=2) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=6) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=7) - E/Sensors ( 2656): AkmSensor: processing event (type=2, code=9) -*/ - -// for akm8975 -#define EVENT_TYPE_ACCEL_X ABS_Y //1 -#define EVENT_TYPE_ACCEL_Y ABS_X //0 -#define EVENT_TYPE_ACCEL_Z ABS_Z //2 -//#define EVENT_TYPE_ACCEL_STATUS ABS_WHEEL //8 - -#define EVENT_TYPE_YAW ABS_RX //3 -#define EVENT_TYPE_PITCH ABS_RY //4 -#define EVENT_TYPE_ROLL ABS_RZ //5 -#define EVENT_TYPE_ORIENT_STATUS ABS_WHEEL //8 - -#define EVENT_TYPE_MAGV_X ABS_RUDDER // 6 -#define EVENT_TYPE_MAGV_Y ABS_THROTTLE // 7 -#define EVENT_TYPE_MAGV_Z ABS_GAS // 9 - -#define EVENT_TYPE_TEMPERATURE ABS_THROTTLE -#define EVENT_TYPE_STEP_COUNT ABS_GAS -#define EVENT_TYPE_PROXIMITY ABS_DISTANCE -#define EVENT_TYPE_LIGHT ABS_MISC - -#define EVENT_TYPE_GYRO_X REL_RY -#define EVENT_TYPE_GYRO_Y REL_RX -#define EVENT_TYPE_GYRO_Z REL_RZ - -// 90 LSB = 1G for KR3DM -#define LSB (90.0f) -#define NUMOFACCDATA (8.0f) - -// conversion of acceleration data to SI units (m/s^2) -#define RANGE_A (2*GRAVITY_EARTH) -#define CONVERT_A (GRAVITY_EARTH / LSB / NUMOFACCDATA) -#define CONVERT_A_X (CONVERT_A) -#define CONVERT_A_Y (-CONVERT_A) -#define CONVERT_A_Z (-CONVERT_A) - -// conversion of magnetic data to uT units -#define CONVERT_M (1.0f/16.0f) -#define CONVERT_M_X (CONVERT_M) -#define CONVERT_M_Y (-CONVERT_M) -#define CONVERT_M_Z (CONVERT_M) - -/* conversion of orientation data to degree units */ -#define CONVERT_O (1.0f/64.0f) -#define CONVERT_O_A (CONVERT_O) -#define CONVERT_O_P (CONVERT_O) -#define CONVERT_O_R (-CONVERT_O) - -// conversion of gyro data to SI units (radian/sec) -#define RANGE_GYRO (2000.0f*(float)M_PI/180.0f) -#define CONVERT_GYRO ((70.0f / 1000.0f) * ((float)M_PI / 180.0f)) -#define CONVERT_GYRO_X (CONVERT_GYRO) -#define CONVERT_GYRO_Y (-CONVERT_GYRO) -#define CONVERT_GYRO_Z (CONVERT_GYRO) - -#define SENSOR_STATE_MASK (0x7FFF) - -/*****************************************************************************/ - -__END_DECLS - -#endif // ANDROID_SENSORS_H diff --git a/exynos4/hal/libswconverter/Android.mk b/exynos4/hal/libswconverter/Android.mk index ce6daf4..e52aea7 100644 --- a/exynos4/hal/libswconverter/Android.mk +++ b/exynos4/hal/libswconverter/Android.mk @@ -1,20 +1,9 @@ -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - LOCAL_PATH := $(call my-dir) + include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional + LOCAL_SRC_FILES := \ swconvertor.c \ csc_linear_to_tiled_crop_neon.s \ @@ -24,21 +13,24 @@ LOCAL_SRC_FILES := \ csc_interleave_memcpy_neon.s LOCAL_C_INCLUDES := \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/include/khronos \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/include/sec \ - $(TOP)/$(BOARD_HAL_PATH)/include \ - $(TOP)/$(BOARD_HAL_PATH)/libhwconverter + $(TOP)/$(TARGET_OMX_PATH)/include/khronos \ + $(TOP)/$(TARGET_OMX_PATH)/include/sec \ + $(TOP)/$(TARGET_HAL_PATH)/include \ + $(TOP)/$(TARGET_HAL_PATH)/libhwconverter ifeq ($(BOARD_USE_SAMSUNG_COLORFORMAT), true) LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT endif -LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libswconverter LOCAL_PRELINK_MODULE := false + +LOCAL_CFLAGS := + LOCAL_ARM_MODE := arm +LOCAL_STATIC_LIBRARIES := LOCAL_SHARED_LIBRARIES := liblog libfimc libhwconverter include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/hal/libump/Android.mk b/exynos4/hal/libump/Android.mk deleted file mode 100644 index 306b6af..0000000 --- a/exynos4/hal/libump/Android.mk +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (C) 2010 ARM Limited. All rights reserved. -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -UMP_SRCS := \ - arch_011_udd/ump_frontend.c \ - arch_011_udd/ump_ref_drv.c \ - arch_011_udd/ump_arch.c \ - os/linux/ump_uku.c \ - os/linux/ump_osu_memory.c \ - os/linux/ump_osu_locks.c - -# Shared and static library for target -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := libUMP -LOCAL_SRC_FILES := $(UMP_SRCS) - -LOCAL_C_INCLUDES:= \ - $(BOARD_HAL_PATH)/libump/ \ - $(BOARD_HAL_PATH)/libump/include \ - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_PATH := $(TARGET_OUT_STATIC_LIBRARIES)/ -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libUMP -LOCAL_MODULE_TAGS := optional -LOCAL_WHOLE_STATIC_LIBRARIES := libUMP -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/ -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/hal/libump/Makefile b/exynos4/hal/libump/Makefile deleted file mode 100644 index b936fe9..0000000 --- a/exynos4/hal/libump/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (C) 2010-2011 ARM Limited. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -UMP_DIR ?= . -UMP_LIB ?= libUMP -UDD_OS ?= android -#CROSS_COMPILE ?= arm-none-linux-gnueabi- -TARGET_CC ?= $(CROSS_COMPILE)gcc -TARGET_AR ?= $(CROSS_COMPILE)ar -CFLAGS += -I$(UMP_DIR)/include -I$(UMP_DIR)/include/ump -Wall -march=armv6 -mthumb-interwork -fno-strict-aliasing -Wno-strict-aliasing -Wno-long-long -O3 - -include ump.mak - -%.o: %.c - $(TARGET_CC) -c -o $@ $< $(CFLAGS) - -UMP_OBJS := $(UMP_SRCS:.c=.o) - -libUMP.so: $(UMP_OBJS) - arm-none-linux-gnueabi-gcc -shared -o $@ $(UMP_OBJS) $(CFLAGS) -libUMP.a: $(UMP_OBJS) - $(TARGET_AR) rcs $@ $(UMP_OBJS) - -clean: - -rm -f $(UMP_OBJS) libUMP.so libUMP.a diff --git a/exynos4/hal/libump/arch_011_udd/ump_arch.c b/exynos4/hal/libump/arch_011_udd/ump_arch.c deleted file mode 100644 index 79c3c18..0000000 --- a/exynos4/hal/libump/arch_011_udd/ump_arch.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_arch.c - * - * UMP arch layer for UMP-UDD - */ - -#include -#include "ump_arch.h" -#include - -#include -#include "../os/ump_uku.h" - -/** Pointer to an OS-Specific context that we should pass in _uku_ calls */ -void *ump_uk_ctx = NULL; - -/** Reference counting of ump_arch_open() and ump_arch_close(). */ -volatile static int ump_ref_count = 0; - -/** Lock for critical section in open/close */ -_ump_osu_lock_t * ump_lock = NULL; - -ump_result ump_arch_open(void) -{ - ump_result retval = UMP_OK; - - _ump_osu_lock_auto_init( &ump_lock, 0, 0, 0 ); - - /* Check that the lock was initialized */ - if (NULL == ump_lock) - { - UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to init lock\n")); - return UMP_ERROR; - } - - /* Attempt to obtain a lock */ - if( _UMP_OSU_ERR_OK != _ump_osu_lock_wait( ump_lock, _UMP_OSU_LOCKMODE_RW ) ) - { - UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to acquire lock\n")); - return UMP_ERROR; - } - - /* ASSERT NEEDED */ - UMP_DEBUG_ASSERT(0 <= ump_ref_count, ("UMP: Reference count invalid at _ump_base_arch_open()")); - ump_ref_count++; - - if (1 == ump_ref_count) - { - /* We are the first, open the UMP device driver */ - - if (_UMP_OSU_ERR_OK != _ump_uku_open( &ump_uk_ctx )) - { - UMP_DEBUG_PRINT(1, ("UMP: ump_arch_open() failed to open UMP device driver\n")); - retval = UMP_ERROR; - ump_ref_count--; - } - } - - /* Signal the lock so someone else can use it */ - _ump_osu_lock_signal( ump_lock, _UMP_OSU_LOCKMODE_RW ); - - return retval; -} - - - -void ump_arch_close(void) -{ - _ump_osu_lock_auto_init( &ump_lock, 0, 0, 0 ); - - /* Check that the lock was initialized */ - if(NULL == ump_lock) - { - UMP_DEBUG_PRINT(1, ("UMP: ump_arch_close() failed to init lock\n")); - return; - } - - /* Attempt to obtain a lock */ - if( _UMP_OSU_ERR_OK != _ump_osu_lock_wait( ump_lock, _UMP_OSU_LOCKMODE_RW ) ) - { - UMP_DEBUG_PRINT(1, ("UMP: ump_arch_close() failed to acquire lock\n")); - return; - } - - UMP_DEBUG_ASSERT(0 < ump_ref_count, ("UMP: ump_arch_close() called while no references exist")); - if (ump_ref_count > 0) - { - ump_ref_count--; - if (0 == ump_ref_count) - { - _ump_osu_errcode_t retval = _ump_uku_close(&ump_uk_ctx); - UMP_DEBUG_ASSERT(retval == _UMP_OSU_ERR_OK, ("UMP: Failed to close UMP interface")); - UMP_IGNORE(retval); - ump_uk_ctx = NULL; - _ump_osu_lock_signal( ump_lock, _UMP_OSU_LOCKMODE_RW ); - _ump_osu_lock_term( ump_lock ); /* Not 100% thread safe, since another thread can already be waiting for this lock in ump_arch_open() */ - ump_lock = NULL; - return; - } - } - - /* Signal the lock so someone else can use it */ - _ump_osu_lock_signal( ump_lock, _UMP_OSU_LOCKMODE_RW ); -} - - - -ump_secure_id ump_arch_allocate(unsigned long * size, ump_alloc_constraints constraints) -{ - _ump_uk_allocate_s call_arg; - - if ( NULL == size ) - { - return UMP_INVALID_SECURE_ID; - } - - call_arg.ctx = ump_uk_ctx; - call_arg.secure_id = UMP_INVALID_SECURE_ID; - call_arg.size = *size; -#ifdef UMP_DEBUG_SKIP_CODE - /** Run-time ASSERTing that _ump_uk_api_version_s and ump_alloc_constraints are - * interchangable */ - switch (constraints) - { - case UMP_REF_DRV_CONSTRAINT_NONE: - UMP_DEBUG_ASSERT( UMP_REF_DRV_UK_CONSTRAINT_NONE == constraints, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints") ); - break; - case UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR: - UMP_DEBUG_ASSERT( UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR == constraints, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints") ); - break; - default: - UMP_DEBUG_ASSERT( 1, ("ump_uk_alloc_constraints out of sync with ump_alloc_constraints: %d unrecognized", constraints) ); - break; - } -#endif - call_arg.constraints = (ump_uk_alloc_constraints)constraints; - - if ( _UMP_OSU_ERR_OK != _ump_uku_allocate(&call_arg) ) - { - return UMP_INVALID_SECURE_ID; - } - - *size = call_arg.size; - - UMP_DEBUG_PRINT(4, ("UMP: Allocated ID %u, size %ul", call_arg.secure_id, call_arg.size)); - - return call_arg.secure_id; -} - - - -unsigned long ump_arch_size_get(ump_secure_id secure_id) -{ - _ump_uk_size_get_s dd_size_call_arg; - - dd_size_call_arg.ctx = ump_uk_ctx; - dd_size_call_arg.secure_id = secure_id; - dd_size_call_arg.size = 0; - - if (_UMP_OSU_ERR_OK == _ump_uku_size_get( &dd_size_call_arg ) ) - { - return dd_size_call_arg.size; - } - - return 0; -} - - -void ump_arch_reference_release(ump_secure_id secure_id) -{ - _ump_uk_release_s dd_release_call_arg; - _ump_osu_errcode_t retval; - - dd_release_call_arg.ctx = ump_uk_ctx; - dd_release_call_arg.secure_id = secure_id; - - UMP_DEBUG_PRINT(4, ("UMP: Releasing ID %u", secure_id)); - - retval = _ump_uku_release( &dd_release_call_arg ); - UMP_DEBUG_ASSERT(retval == _UMP_OSU_ERR_OK, ("UMP: Failed to release reference to UMP memory")); - UMP_IGNORE(retval); -} - - -void* ump_arch_map(ump_secure_id secure_id, unsigned long size, ump_cache_enabled cache, unsigned long *cookie_out) -{ - _ump_uk_map_mem_s dd_map_call_arg; - - UMP_DEBUG_ASSERT_POINTER( cookie_out ); - - dd_map_call_arg.ctx = ump_uk_ctx; - dd_map_call_arg.secure_id = secure_id; - dd_map_call_arg.size = size; - dd_map_call_arg.is_cached = (u32) (UMP_CACHE_ENABLE==cache); - - if ( -1 == _ump_uku_map_mem( &dd_map_call_arg ) ) - { - UMP_DEBUG_PRINT(4, ("UMP: Mapping failed for ID %u", secure_id)); - return NULL; - } - - UMP_DEBUG_PRINT(4, ("Mapped %u at 0x%08lx", secure_id, (unsigned long)dd_map_call_arg.mapping)); - - *cookie_out = dd_map_call_arg.cookie; - return dd_map_call_arg.mapping; -} - - - -void ump_arch_unmap(void* mapping, unsigned long size, unsigned long cookie) -{ - _ump_uk_unmap_mem_s dd_unmap_call_arg; - - dd_unmap_call_arg.ctx = ump_uk_ctx; - dd_unmap_call_arg.mapping = mapping; - dd_unmap_call_arg.size = size; - dd_unmap_call_arg.cookie = cookie; - - UMP_DEBUG_PRINT(4, ("Unmapping 0x%08lx", (unsigned long)mapping)); - _ump_uku_unmap_mem( &dd_unmap_call_arg ); -} - -/** Memory synchronization - cache flushing of mapped memory */ -int ump_arch_msync(ump_secure_id secure_id, void* mapping, unsigned long cookie, void * address, unsigned long size, ump_cpu_msync_op op) -{ - _ump_uk_msync_s dd_msync_call_arg; - - dd_msync_call_arg.ctx = ump_uk_ctx; - dd_msync_call_arg.mapping = mapping; - dd_msync_call_arg.address = address; - dd_msync_call_arg.size = size; - dd_msync_call_arg.op = (ump_uk_msync_op)op; - dd_msync_call_arg.cookie = cookie; - dd_msync_call_arg.secure_id = secure_id; - dd_msync_call_arg.is_cached = 0; - - UMP_DEBUG_PRINT(4, ("Msync 0x%08lx", (unsigned long)mapping)); - _ump_uku_msynch( &dd_msync_call_arg ); - if ( 0==dd_msync_call_arg.is_cached ) - { - UMP_DEBUG_PRINT(4, ("Trying to flush uncached UMP mem ID: %d", secure_id)); - } - return dd_msync_call_arg.is_cached; -} diff --git a/exynos4/hal/libump/arch_011_udd/ump_arch.h b/exynos4/hal/libump/arch_011_udd/ump_arch.h deleted file mode 100644 index 064d7c5..0000000 --- a/exynos4/hal/libump/arch_011_udd/ump_arch.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_arch.h - * - * Header file for the arch dependent backend, which will do the communication with the UMP device driver. - */ - -#ifndef _UNIFIED_MEMORY_PROVIDER_ARCH_H_ -#define _UNIFIED_MEMORY_PROVIDER_ARCH_H_ - -#include -#include -#include "ump_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - - - -/** Open UMP interface. */ -ump_result ump_arch_open(void); - -/** Close UMP interface. */ -void ump_arch_close(void); - -/** Allocate UMP memory. */ -ump_secure_id ump_arch_allocate(unsigned long * size, ump_alloc_constraints constraints); - -/** Query size of specified UMP memory, in bytes. */ -unsigned long ump_arch_size_get(ump_secure_id secure_id); - -/** Release a reference from specified UMP memory. */ -void ump_arch_reference_release(ump_secure_id secure_id); - -/** Map specified UMP memory into CPU address space */ -void* ump_arch_map(ump_secure_id secure_id, unsigned long size, ump_cache_enabled cache, unsigned long *cookie_out); - -/** Unmap specified UMP memory from CPU adderss space */ -void ump_arch_unmap(void* mapping, unsigned long size, unsigned long cookie); - -/** Memory synchronization - cache flushing of mapped memory - * @return Is_cached: 1==True 0==NonCached */ -int ump_arch_msync(ump_secure_id secure_id, void* mapping, unsigned long cookie, void * address, unsigned long size, ump_cpu_msync_op op); - -#ifdef __cplusplus -} -#endif - -#endif /* _UNIFIED_MEMORY_PROVIDER_ARCH_H_ */ diff --git a/exynos4/hal/libump/arch_011_udd/ump_frontend.c b/exynos4/hal/libump/arch_011_udd/ump_frontend.c deleted file mode 100644 index 8c93332..0000000 --- a/exynos4/hal/libump/arch_011_udd/ump_frontend.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_frontend.c - * - * This file implements the user space API of the UMP API. - * It relies heavily on a arch backend to do the communication with the UMP device driver. - */ - -#include -#include "ump_internal.h" -#include "ump_arch.h" -#include -#include - -UMP_API_EXPORT ump_result ump_open(void) -{ - return ump_arch_open(); -} - -UMP_API_EXPORT void ump_close(void) -{ - ump_arch_close(); -} - -UMP_API_EXPORT ump_secure_id ump_secure_id_get(ump_handle memh) -{ - ump_mem * mem = (ump_mem*)memh; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low")); - - return mem->secure_id; -} - -UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id) -{ - unsigned long size; - - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != secure_id, ("Secure ID is invalid")); - - size = ump_arch_size_get(secure_id); - if (0 != size) - { - unsigned long cookie; - /* - * The UMP memory which the secure_id referes to could now be deleted and re-created - * since we don't have any references to it yet. The mapping below will however fail if - * we have supplied incorrect size, so we are safe. - */ - void * mapping = ump_arch_map(secure_id, size, UMP_CACHE_DISABLE, &cookie); - if (NULL != mapping) - { - ump_mem * mem = _ump_osu_calloc(1, sizeof(*mem)); - if (NULL != mem) - { - mem->secure_id = secure_id; - mem->mapped_mem = mapping; - mem->size = size; - mem->cookie = cookie; - mem->is_cached = 1; /* Is set to actually check in the ump_cpu_msync_now() function */ - - _ump_osu_lock_auto_init(&mem->ref_lock, 0, 0, 0); - UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n")); - mem->ref_count = 1; - - /* This is called only to set the cache settings in this handle */ - ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0); - - UMP_DEBUG_PRINT(4, ("UMP handle created for ID %u of size %lu, mapped into address 0x%08lx", mem->secure_id, mem->size, (unsigned long)mem->mapped_mem)); - - return (ump_handle)mem; - } - - ump_arch_unmap(mapping, size, cookie); - } - } - - UMP_DEBUG_PRINT(2, ("UMP handle creation failed for ID %u", secure_id)); - - return UMP_INVALID_MEMORY_HANDLE; -} - -UMP_API_EXPORT unsigned long ump_size_get(ump_handle memh) -{ - ump_mem * mem = (ump_mem*)memh; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low")); - - return mem->size; -} - -UMP_API_EXPORT void ump_read(void *dst, ump_handle srch, unsigned long offset, unsigned long length) -{ - ump_mem * src = (ump_mem*)srch; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != srch, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != src->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < src->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < src->size, ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != src->mapped_mem, ("UMP Memory is not mapped")); - UMP_DEBUG_ASSERT((src->size) >= (offset + length), ("Requested read beyond end of UMP memory")); - - _ump_osu_memcpy(dst,(char*)(src->mapped_mem) + offset, length); -} - -UMP_API_EXPORT void ump_write(ump_handle dsth, unsigned long offset, const void *src, unsigned long length) -{ - ump_mem * dst = (ump_mem*)dsth; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != dsth, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != dst->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < dst->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < dst->size, ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != dst->mapped_mem, ("UMP Memory is not mapped")); - UMP_DEBUG_ASSERT((dst->size) >= (offset + length), ("Requested write beyond end of UMP memory")); - - _ump_osu_memcpy((char*)(dst->mapped_mem) + offset, src, length); -} - - - -UMP_API_EXPORT void* ump_mapped_pointer_get(ump_handle memh) -{ - ump_mem * mem = (ump_mem*)memh; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != mem->mapped_mem, ("Error in mapping pointer (not mapped)")); - - return mem->mapped_mem; -} - - - -UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle memh) -{ - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != ((ump_mem*)memh)->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < ((ump_mem*)memh)->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < ((ump_mem*)memh)->size, ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != ((ump_mem*)memh)->mapped_mem, ("Error in mapping pointer (not mapped)")); - - /* noop, cos we map in the pointer when handle is created, and unmap it when handle is destroyed */ -} - - - -UMP_API_EXPORT void ump_reference_add(ump_handle memh) -{ - ump_mem * mem = (ump_mem*)memh; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != mem->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < mem->ref_count, ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < mem->size, ("Memory size of passed handle too low")); - - _ump_osu_lock_wait(mem->ref_lock, _UMP_OSU_LOCKMODE_RW); - mem->ref_count += 1; - _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW); -} - - - -UMP_API_EXPORT void ump_reference_release(ump_handle memh) -{ - ump_mem * mem = (ump_mem*)memh; - - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != ((ump_mem*)mem)->secure_id, ("Secure ID is inavlid")); - UMP_DEBUG_ASSERT(0 < (((ump_mem*)mem)->ref_count), ("Reference count too low")); - UMP_DEBUG_ASSERT(0 < ((ump_mem*)mem)->size, ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != ((ump_mem*)mem)->mapped_mem, ("Error in mapping pointer (not mapped)")); - - _ump_osu_lock_wait(mem->ref_lock, _UMP_OSU_LOCKMODE_RW); - mem->ref_count -= 1; - if (0 == mem->ref_count) - { - /* Remove memory mapping, which holds our only reference towards the UMP kernel space driver */ - ump_arch_unmap(mem->mapped_mem, mem->size, mem->cookie); - - _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW); - - /* Free the lock protecting the reference count */ - _ump_osu_lock_term(mem->ref_lock); - - /* Free the memory for this handle */ - _ump_osu_free(mem); - } else { - _ump_osu_lock_signal(mem->ref_lock, _UMP_OSU_LOCKMODE_RW); - } -} diff --git a/exynos4/hal/libump/arch_011_udd/ump_internal.h b/exynos4/hal/libump/arch_011_udd/ump_internal.h deleted file mode 100644 index bc1f2a9..0000000 --- a/exynos4/hal/libump/arch_011_udd/ump_internal.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_internal.c - * - * Internal definitions and debugging macros for the UMP implementation. - */ - -#ifndef _UNIFIED_MEMORY_PROVIDER_INTERNAL_H_ -#define _UNIFIED_MEMORY_PROVIDER_INTERNAL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum ump_cache_enabled -{ - UMP_CACHE_DISABLE = 0, - UMP_CACHE_ENABLE = 1 -} ump_cache_enabled; - -/** - * The actual (hidden) definition of ump_handles. - */ -typedef struct ump_mem -{ - ump_secure_id secure_id; /**< UMP device driver cookie */ - void * mapped_mem; /**< Mapped memory; all read and write use this */ - unsigned long size; /**< Size of allocated memory */ - _ump_osu_lock_t* ref_lock; /**< Lock protection ref_count */ - int ref_count; /**< The reference count of the ump_handle in userspace. It is used for finding out - when to free the memory used by this userspace handle. It is NOT the same as the - real ump_mem reference count in the devicedriver which do reference counting - for the memory that this handle reveals. */ - unsigned long cookie; /**< cookie for use in arch_unmap calls */ - ump_cache_enabled is_cached; -} ump_mem; - -#ifdef __cplusplus -} -#endif - - - -#endif /* _UNIFIED_MEMORY_PROVIDER_INTERNAL_H_ */ diff --git a/exynos4/hal/libump/arch_011_udd/ump_ref_drv.c b/exynos4/hal/libump/arch_011_udd/ump_ref_drv.c deleted file mode 100644 index cf3b9eb..0000000 --- a/exynos4/hal/libump/arch_011_udd/ump_ref_drv.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_ref_drv.c - * - * Implementation of the user space API extensions provided by the reference implementation. - */ - -#include -#include -#include "ump_internal.h" -#include "ump_arch.h" -#include -#include - -/* Allocate a buffer which can be used directly by hardware, 4kb aligned */ -static ump_handle ump_ref_drv_allocate_internal(unsigned long size, ump_alloc_constraints constraints, ump_cache_enabled cache); - - - -/* Allocate a buffer which can be used directly by hardware, 4kb aligned */ -ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints constraints) -{ - ump_cache_enabled cache= UMP_CACHE_DISABLE; - if ( 0!=(constraints&UMP_REF_DRV_CONSTRAINT_USE_CACHE) ) - { - cache = UMP_CACHE_ENABLE; - } - return ump_ref_drv_allocate_internal(size, constraints, cache); -} - -UMP_API_EXPORT int ump_cpu_msync_now(ump_handle memh, ump_cpu_msync_op op, void* address, int size) -{ - ump_mem * mem = (ump_mem*)memh; - UMP_DEBUG_ASSERT(UMP_INVALID_MEMORY_HANDLE != memh, ("Handle is invalid")); - - /* If the op is readout, we do the readout from DD. - Else we skip flushing if the userspace handle says that it is uncached */ - if ((UMP_MSYNC_READOUT_CACHE_ENABLED!=op) && (0 == mem->is_cached) ) return 0; - - UMP_DEBUG_ASSERT(0 < (((ump_mem*)mem)->ref_count), ("Reference count too low")); - UMP_DEBUG_ASSERT((size>=0) && (size <= ((ump_mem*)mem)->size), ("Memory size of passed handle too low")); - UMP_DEBUG_ASSERT(NULL != ((ump_mem*)mem)->mapped_mem, ("Error in mapping pointer (not mapped)")); - - if (size > mem->size) size = mem->size; - - mem->is_cached = ump_arch_msync(mem->secure_id, mem->mapped_mem, mem->cookie, address, size, op); - return mem->is_cached ; -} - -/* Allocate a buffer which can be used directly by hardware, 4kb aligned */ -static ump_handle ump_ref_drv_allocate_internal(unsigned long size, ump_alloc_constraints constraints, ump_cache_enabled cache) -{ - ump_secure_id secure_id; - unsigned long allocated_size = size; - - UMP_DEBUG_PRINT(4, ("Allocating UMP memory of size %lu", size)); - - secure_id = ump_arch_allocate(&allocated_size, constraints); - if (secure_id != UMP_INVALID_SECURE_ID) - { - unsigned long cookie; - void * mapping; - - mapping = ump_arch_map(secure_id, allocated_size, cache, &cookie); - if (NULL != mapping) - { - /* - * PS: By now we have actually increased the ref count in the device driver by 2, - * one for the allocation iteself, and one for the mapping. - */ - ump_mem * mem; - mem = _ump_osu_calloc(1, sizeof(*mem)); - if (NULL != mem) - { - mem->secure_id = secure_id; - mem->mapped_mem = mapping; - mem->size = allocated_size; - mem->cookie = cookie; - mem->is_cached = 1; /* Default to ON, is disabled later if not */ - - _ump_osu_lock_auto_init(&mem->ref_lock, 0, 0, 0); - UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n")); - mem->ref_count = 1; - - /* - * ump_arch_allocate() gave us a kernel space reference, and the same did ump_arch_map() - * We release the one from ump_arch_allocate(), and rely solely on the one from the ump_arch_map() - * That is, ump_arch_unmap() should now do the final release towards the UMP kernel space driver. - */ - ump_arch_reference_release(secure_id); - - /* This is called only to set the cache settings in this handle */ - ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0); - - UMP_DEBUG_PRINT(4, ("UMP handle created for ID %u of size %lu, mapped into address 0x%08lx", mem->secure_id, mem->size, (unsigned long)mem->mapped_mem)); - - return (ump_handle)mem; - } - - ump_arch_unmap(mapping, allocated_size, cookie); /* Unmap the memory */ - ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */ - } - - ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */ - } - - UMP_DEBUG_PRINT(4, ("Allocation of UMP memory failed")); - return UMP_INVALID_MEMORY_HANDLE; -} diff --git a/exynos4/hal/libump/include/ump/ump.h b/exynos4/hal/libump/include/ump/ump.h deleted file mode 100644 index 2829113..0000000 --- a/exynos4/hal/libump/include/ump/ump.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump.h - * - * This file contains the user space part of the UMP API. - */ - -#ifndef _UNIFIED_MEMORY_PROVIDER_H_ -#define _UNIFIED_MEMORY_PROVIDER_H_ - - -/** @defgroup ump_user_space_api UMP User Space API - * @{ */ - - -#include "ump_platform.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * External representation of a UMP handle in user space. - */ -typedef void * ump_handle; - -/** - * Typedef for a secure ID, a system wide identificator for UMP memory buffers. - */ -typedef unsigned int ump_secure_id; - -/** - * Value to indicate an invalid UMP memory handle. - */ -#define UMP_INVALID_MEMORY_HANDLE ((ump_handle)0) - -/** - * Value to indicate an invalid secure Id. - */ -#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) - -/** - * UMP error codes for user space. - */ -typedef enum -{ - UMP_OK = 0, /**< indicates success */ - UMP_ERROR, /**< indicates failure */ -} ump_result; - - -/** - * Opens and initializes the UMP library. - * - * This function must be called at least once before calling any other UMP API functions. - * Each open is reference counted and must be matched with a call to @ref ump_close "ump_close". - * - * @see ump_close - * - * @return UMP_OK indicates success, UMP_ERROR indicates failure. - */ -UMP_API_EXPORT ump_result ump_open(void); - - -/** - * Terminate the UMP library. - * - * This must be called once for every successful @ref ump_open "ump_open". The UMP library is - * terminated when, and only when, the last open reference to the UMP interface is closed. - * - * @see ump_open - */ -UMP_API_EXPORT void ump_close(void); - - -/** - * Retrieves the secure ID for the specified UMP memory. - * - * This identificator is unique across the entire system, and uniquely identifies - * the specified UMP memory. This identificator can later be used through the - * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" or - * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" - * functions in order to access this UMP memory, for instance from another process. - * - * @note There is a kernel space equivalent function called @ref ump_dd_secure_id_get "ump_dd_secure_id_get" - * - * @see ump_handle_create_from_secure_id - * @see ump_dd_handle_create_from_secure_id - * @see ump_dd_secure_id_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the secure ID for the specified UMP memory. - */ -UMP_API_EXPORT ump_secure_id ump_secure_id_get(ump_handle mem); - - -/** - * Retrieves a handle to allocated UMP memory. - * - * The usage of UMP memory is reference counted, so this will increment the reference - * count by one for the specified UMP memory. - * Use @ref ump_reference_release "ump_reference_release" when there is no longer any - * use for the retrieved handle. - * - * @note There is a kernel space equivalent function called @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" - * - * @see ump_reference_release - * @see ump_dd_handle_create_from_secure_id - * - * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. - * - * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. - */ -UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id); - - -/** - * Retrieves the actual size of the specified UMP memory. - * - * The size is reported in bytes, and is typically page aligned. - * - * @note There is a kernel space equivalent function called @ref ump_dd_size_get "ump_dd_size_get" - * - * @see ump_dd_size_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the allocated size of the specified UMP memory, in bytes. - */ -UMP_API_EXPORT unsigned long ump_size_get(ump_handle mem); - - -/** - * Read from specified UMP memory. - * - * Another way of reading from (and writing to) UMP memory is to use the - * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve - * a CPU mapped pointer to the memory. - * - * @see ump_mapped_pointer_get - * - * @param dst Destination buffer. - * @param src Handle to UMP memory to read from. - * @param offset Where to start reading, given in bytes. - * @param length How much to read, given in bytes. - */ -UMP_API_EXPORT void ump_read(void * dst, ump_handle src, unsigned long offset, unsigned long length); - - -/** - * Write to specified UMP memory. - * - * Another way of writing to (and reading from) UMP memory is to use the - * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve - * a CPU mapped pointer to the memory. - * - * @see ump_mapped_pointer_get - * - * @param dst Handle to UMP memory to write to. - * @param offset Where to start writing, given in bytes. - * @param src Buffer to read from. - * @param length How much to write, given in bytes. - */ -UMP_API_EXPORT void ump_write(ump_handle dst, unsigned long offset, const void * src, unsigned long length); - - -/** - * Retrieves a memory mapped pointer to the specified UMP memory. - * - * This function retrieves a memory mapped pointer to the specified UMP memory, - * that can be used by the CPU. Every successful call to - * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" is reference counted, - * and must therefor be followed by a call to - * @ref ump_mapped_pointer_release "ump_mapped_pointer_release " when the - * memory mapping is no longer needed. - * - * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required. - * - * @see ump_mapped_pointer_release - * - * @param mem Handle to UMP memory. - * - * @return NULL indicates failure, otherwise a CPU mapped pointer is returned. - */ -UMP_API_EXPORT void * ump_mapped_pointer_get(ump_handle mem); - - -/** - * Releases a previously mapped pointer to the specified UMP memory. - * - * The CPU mapping of the specified UMP memory memory is reference counted, - * so every call to @ref ump_mapped_pointer_get "ump_mapped_pointer_get" must - * be matched with a call to this function when the mapping is no longer needed. - * - * The CPU mapping is not removed before all references to the mapping is released. - * - * @note Systems without a MMU must still implement this function, even though no unmapping should be needed. - * - * @param mem Handle to UMP memory. - */ -UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle mem); - - -/** - * Adds an extra reference to the specified UMP memory. - * - * This function adds an extra reference to the specified UMP memory. This function should - * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle - * variable. The function @ref ump_reference_release "ump_reference_release" must then be used - * to release each copy of the UMP memory handle. - * - * @note You are not required to call @ref ump_reference_add "ump_reference_add" - * for UMP handles returned from - * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id", - * because these handles are already reference counted by this function. - * - * @note There is a kernel space equivalent function called @ref ump_dd_reference_add "ump_dd_reference_add" - * - * @see ump_dd_reference_add - * - * @param mem Handle to UMP memory. - */ -UMP_API_EXPORT void ump_reference_add(ump_handle mem); - - -/** - * Releases a reference from the specified UMP memory. - * - * This function should be called once for every reference to the UMP memory handle. - * When the last reference is released, all resources associated with this UMP memory - * handle are freed. - * - * @note There is a kernel space equivalent function called @ref ump_dd_reference_release "ump_dd_reference_release" - * - * @see ump_dd_reference_release - * - * @param mem Handle to UMP memory. - */ -UMP_API_EXPORT void ump_reference_release(ump_handle mem); - - -#ifdef __cplusplus -} -#endif - - -/** @} */ /* end group ump_user_space_api */ - - -#endif /*_UNIFIED_MEMORY_PROVIDER_H_ */ diff --git a/exynos4/hal/libump/include/ump/ump_debug.h b/exynos4/hal/libump/include/ump/ump_debug.h deleted file mode 100644 index 5ede8a3..0000000 --- a/exynos4/hal/libump/include/ump/ump_debug.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_debug.h - * - * The file include several useful macros for debugging and printing. - * - UMP_PRINTF(...) Do not use this function: Will be included in Release builds. - * - UMP_DEBUG_TRACE() Prints current location in code. - * - UMP_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=UMP_DEBUG_LEVEL. - * - UMP_DEBUG_TPRINT(nr, X ) Prints the source trace and second argument if nr<=UMP_DEBUG_LEVEL. - * - UMP_DEBUG_ERROR( (X) ) Prints an errortext, a source trace, and the given error message. - * - UMP_DEBUG_ASSERT(exp,(X)) If the asserted expr is false, the program will exit. - * - UMP_DEBUG_ASSERT_RANGE(x, min, max) Triggers if variable x is not between or equal to max and min. - * - UMP_DEBUG_ASSERT_LEQ(x, max) Triggers if variable x is not less than equal to max. - * - UMP_DEBUG_ASSERT_POINTER(pointer) Triggers if the pointer is a zero pointer. - * - UMP_DEBUG_CODE( X ) The code inside the macro is only copiled in Debug builds. - * - * The (X) means that you must add an extra parantese around the argumentlist. - * - * The printf function: UMP_PRINTF(...) is routed to _ump_sys_printf - * - * Suggested range for the DEBUG-LEVEL is [1:6] where - * [1:2] Is messages with highest priority, indicate possible errors. - * [3:4] Is messages with medium priority, output important variables. - * [5:6] Is messages with low priority, used during extensive debugging. - * - */ -#ifndef _UMP_DEBUG_H_ -#define _UMP_DEBUG_H_ - -#include -#include - -/* START: Configuration */ -#ifndef UMP_PRINTF - #define UMP_PRINTF printf -#endif /* UMP_PRINTF */ - -#ifndef UMP_PRINT_FLUSH - #define UMP_PRINT_FLUSH do {} while (0) -#endif /* UMP_PRINT_FLUSH */ - -#ifndef UMP_DEBUG_LEVEL - #define UMP_DEBUG_LEVEL 1 -#endif /* UMP_DEBUG_LEVEL */ - -#ifndef UMP_DEBUG_ERROR_START_MSG - #define UMP_DEBUG_ERROR_START_MSG do {\ - UMP_PRINTF("*********************************************************************\n");\ - UMP_PRINT_FLUSH; } while (0) -#endif /* UMP_DEBUG_ERROR_START_MSG */ - -#ifndef UMP_DEBUG_ERROR_STOP_MSG - #define UMP_DEBUG_ERROR_STOP_MSG do { UMP_PRINTF("\n"); UMP_PRINT_FLUSH; } while (0) -#endif /* UMP_DEBUG_ERROR_STOP_MSG */ - -#ifndef UMP_ASSERT_QUIT_CMD - #define UMP_ASSERT_QUIT_CMD abort() -#endif /* UMP_ASSERT_QUIT_CMD */ -/* STOP: Configuration */ - -/** - * The macro UMP_FUNCTION evaluates to the name of the function enclosing - * this macro's usage, or "" if not supported. - */ -#if (defined(__SYMBIAN32__) && defined(__ARMCC__)) || defined(_MSC_VER) -# define UMP_FUNCTION __FUNCTION__ -#elif __STDC__ && __STDC_VERSION__ >= 199901L -# define UMP_FUNCTION __FUNCTION__ -#elif defined(__GNUC__) && __GNUC__ >= 2 -# define UMP_FUNCTION __FUNCTION__ -#elif defined(__func__) -# define UMP_FUNCTION __func__ -#else -# define UMP_FUNCTION "" -#endif - -/** - * Explicitly ignore a parameter passed into a function, to suppress compiler warnings. - * Should only be used with parameter names. - */ -#define UMP_IGNORE(x) (void)x - -/** - * @def UMP_DEBUG_TRACE() - * @brief Prints current location in code. - * Can be turned off by defining UMP_DEBUG_SKIP_TRACE - */ - -#ifndef UMP_DEBUG_SKIP_TRACE - #ifndef UMP_DEBUG_SKIP_PRINT_FUNCTION_NAME - #define UMP_DEBUG_TRACE() do { UMP_PRINTF( "In file: "__FILE__ \ - " function: %s() line:%4d\n" , UMP_FUNCTION, __LINE__); UMP_PRINT_FLUSH; } while (0) - #else - #define UMP_DEBUG_TRACE() do { UMP_PRINTF( "In file: "__FILE__ " line:%4d\n" , __LINE__); UMP_PRINT_FLUSH; } while (0) - #endif /* UMP_DEBUG_SKIP_PRINT_FUNCTION_NAME */ -#else - #define UMP_DEBUG_TRACE() -#endif /* UMP_DEBUG_SKIP_TRACE */ - -/** - * @def UMP_DEBUG_PRINT(nr, (X) ) - * @brief Prints the second argument if nr<=UMP_DEBUG_LEVEL. - * Can be turned off by defining UMP_DEBUG_SKIP_PRINT - * @param nr If nr <= UMP_DEBUG_LEVEL, we print the text. - * @param X A parantese with the contents to be sent to UMP_PRINTF - */ -#ifndef UMP_DEBUG_SKIP_PRINT - #define UMP_DEBUG_PRINT(nr, X ) do { if ( nr<=UMP_DEBUG_LEVEL ) { UMP_PRINTF X ; UMP_PRINT_FLUSH; } } while (0) -#else - #define UMP_DEBUG_PRINT(nr, X ) -#endif /* UMP_DEBUG_SKIP_PRINT */ - -/** - * @def UMP_DEBUG_TPRINT(nr, (X) ) - * @brief Prints the second argument if nr<=UMP_DEBUG_LEVEL. - * Can be turned off by defining UMP_DEBUG_SKIP_TPRINT. - * Can be shortened by defining UMP_DEBUG_TPRINT_SKIP_FUNCTION. - * @param nr If nr <= UMP_DEBUG_LEVEL, we print the text. - * @param X A parantese with the contents to be sent to UMP_PRINTF - */ - -/* helper to handle if the function name should be included or not */ -#ifndef UMP_DEBUG_TPRINT_SKIP_FUNCTION - #define UMP_DEBUG_TPRINT_INTERN do {UMP_PRINTF( ""__FILE__" %s()%4d " , UMP_FUNCTION, __LINE__); UMP_PRINT_FLUSH; } while (0) -#else - #define UMP_DEBUG_TPRINT_INTERN do {UMP_PRINTF( ""__FILE__ "%4d " , __LINE__); UMP_PRINT_FLUSH; } while (0) -#endif /* UMP_DEBUG_TPRINT_SKIP_FUNCTION */ - -#ifndef UMP_DEBUG_SKIP_TPRINT - #define UMP_DEBUG_TPRINT(nr, X ) \ - do{\ - if ( nr<=UMP_DEBUG_LEVEL )\ - {\ - UMP_DEBUG_TPRINT_INTERN;\ - UMP_PRINTF X ;\ - UMP_PRINT_FLUSH;\ - }\ - } while (0) -#else - #define UMP_DEBUG_TPRINT(nr, X ) -#endif /* UMP_DEBUG_SKIP_TPRINT */ - -/** - * @def UMP_DEBUG_ERROR( (X) ) - * @brief Prints an errortext, a source Trace, and the given error message. - * Prints filename, function, linenr, and the given error message. - * The error message must be inside a second parantese. - * The error message is written on a separate line, and a NL char is added. - * Can be turned of by defining UMP_DEBUG_SKIP_ERROR; - * You do not need to type the words ERROR in the message, since it will - * be added anyway. - * - * @note You should not end the text with a newline, since it is added by the macro. - * @note You should not write "ERROR" in the text, since it is added by the macro. - * @param X A parantese with the contents to be sent to UMP_PRINTF - */ - -#ifndef UMP_DEBUG_SKIP_ERROR - #define UMP_DEBUG_ERROR( X ) \ - do{ \ - UMP_DEBUG_ERROR_START_MSG;\ - UMP_PRINTF("ERROR: ");\ - UMP_PRINT_FLUSH;\ - UMP_DEBUG_TRACE(); \ - UMP_PRINTF X ; \ - UMP_PRINT_FLUSH;\ - UMP_DEBUG_ERROR_STOP_MSG;\ - } while (0) -#else - #define UMP_DEBUG_ERROR( X ) do{ ; } while ( 0 ) -#endif /* UMP_DEBUG_SKIP_ERROR */ - -/** - * @def UMP_DEBUG_ASSERT(expr, (X) ) - * @brief If the asserted expr is false, the program will exit. - * Prints filename, function, linenr, and the given error message. - * The error message must be inside a second parantese. - * The error message is written on a separate line, and a NL char is added. - * Can be turned of by defining UMP_DEBUG_SKIP_ERROR; - * You do not need to type the words ASSERT in the message, since it will - * be added anyway. - * - * @param X A parantese with the contents to be sent to UMP_PRINTF - * Prints filename, function, linenr, and the error message - * on a separte line. A newline char is added at the end. - * Can be turned of by defining UMP_DEBUG_SKIP_ASSERT - * @param expr Will exit program if \a expr is false; - * @param (X) Text that will be written if the assertion toggles. - */ - -#ifndef UMP_DEBUG_SKIP_ASSERT - #define UMP_DEBUG_ASSERT(expr, X ) \ - do{\ - if ( !(expr) ) \ - { \ - UMP_DEBUG_ERROR_START_MSG;\ - UMP_PRINTF("ASSERT EXIT: ");\ - UMP_PRINT_FLUSH;\ - UMP_DEBUG_TRACE(); \ - UMP_PRINTF X ; \ - UMP_PRINT_FLUSH;\ - UMP_DEBUG_ERROR_STOP_MSG;\ - UMP_ASSERT_QUIT_CMD;\ - }\ - } while (0) -#else - #define UMP_DEBUG_ASSERT(expr, X) -#endif /* UMP_DEBUG_SKIP_ASSERT */ - - -/** - * @def UMP_DEBUG_ASSERT_POINTER(pointer) - * @brief If the asserted pointer is NULL, the program terminates and TRACE info is printed - * The checking is disabled if "UMP_DEBUG_SKIP_ASSERT" is defined. - */ -#define UMP_DEBUG_ASSERT_POINTER(pointer) UMP_DEBUG_ASSERT(pointer, ("Null pointer " #pointer) ) - -/** - * @def UMP_DEBUG_ASSERT_HANDLE(handle) - * @brief If the asserted handle is not a valid handle, the program terminates and TRACE info is printed - * The checking is disabled if "UMP_DEBUG_SKIP_ASSERT" is defined. - */ -#define UMP_DEBUG_ASSERT_HANDLE(handle) UMP_DEBUG_ASSERT(UMP_NO_HANDLE != (handle), ("Invalid handle" #handle) ) - -/** - * @def UMP_DEBUG_ASSERT_ALIGNMENT(ptr, align) - * @brief If the asserted pointer is not aligned to align, the program terminates with trace info printed. - * The checking is disabled if "UMP_DEBUG_SKIP_ASSERT" is defined. - */ -#ifndef UMP_DEBUG_SKIP_ASSERT - #define UMP_DEBUG_ASSERT_ALIGNMENT(ptr, align) do { \ - UMP_DEBUG_ASSERT(0 == (align & (align - 1)), ("align %d is not a power-of-two", align)); \ - UMP_DEBUG_ASSERT(0 == (((u32)(ptr)) & (align - 1)), ("ptr %p not aligned to %d bytes", (void*)ptr, align)); \ - } while (0) -#else - #define UMP_DEBUG_ASSERT_ALIGNMENT(ptr, align) -#endif /* UMP_DEBUG_SKIP_ASSERT */ - -/** - * @def UMP_DEBUG_ASSERT_RANGE(x,min,max) - * @brief If variable x is not between or equal to max and min, the assertion triggers. - * The checking is disabled if "UMP_DEBUG_SKIP_ASSERT" is defined. - */ -#define UMP_DEBUG_ASSERT_RANGE(x, min, max) \ - UMP_DEBUG_ASSERT( (x) >= (min) && (x) <= (max), \ - (#x " out of range (%2.2f)", (double)x ) \ - ) - -/** - * @def UMP_DEBUG_ASSERT_LEQ(x,max) - * @brief If variable x is less than or equal to max, the assertion triggers. - * The checking is disabled if "UMP_DEBUG_SKIP_ASSERT" is defined. - */ -#define UMP_DEBUG_ASSERT_LEQ(x, max) \ - UMP_DEBUG_ASSERT( (x) <= (max), \ - (#x " out of range (%2.2f)", (double)x ) \ - ) - -/** - * @def UMP_DEBUG_CODE( X ) - * @brief Run the code X on debug builds. - * The code will not be used if UMP_DEBUG_SKIP_CODE is defined . - * - */ -#ifdef UMP_DEBUG_SKIP_CODE - #define UMP_DEBUG_CODE( X ) -#else - #define UMP_DEBUG_CODE( X ) X -#endif /* UMP_DEBUG_SKIP_CODE */ - -#endif /* _UMP_DEBUG_H_ */ - diff --git a/exynos4/hal/libump/include/ump/ump_osu.h b/exynos4/hal/libump/include/ump/ump_osu.h deleted file mode 100644 index 5c9a650..0000000 --- a/exynos4/hal/libump/include/ump/ump_osu.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_osu.h - * Defines the OS abstraction layer for the base driver - */ - -#ifndef __UMP_OSU_H__ -#define __UMP_OSU_H__ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - -typedef unsigned int u32; -#ifdef _MSC_VER - typedef unsigned __int64 u64; - typedef signed __int64 s64; -#else - typedef unsigned long long u64; - typedef signed long long s64; -#endif - -#ifndef NULL -#define NULL ((void*)0) -#endif - -typedef unsigned long ump_bool; - -#ifndef UMP_TRUE -#define UMP_TRUE ((ump_bool)1) -#endif - -#ifndef UMP_FALSE -#define UMP_FALSE ((ump_bool)0) -#endif - -#define UMP_STATIC static - -/** - * @addtogroup ump_user_space_api Unified Device Driver (UDD) APIs used by UMP - * - * @{ - */ - -/** - * @defgroup ump_osuapi UDD OS Abstraction for User-side (OSU) APIs for UMP - * - * @{ - */ - -/* The following is necessary to prevent the _ump_osk_errcode_t doxygen from - * becoming unreadable: */ -/** @cond OSU_COPY_OF__UMP_OSU_ERRCODE_T */ - -/** - * @brief OSU/OSK Error codes. - * - * Each OS may use its own set of error codes, and may require that the - * User/Kernel interface take certain error code. This means that the common - * error codes need to be sufficiently rich to pass the correct error code - * through from the OSK/OSU to U/K layer, across all OSs. - * - * The result is that some error codes will appear redundant on some OSs. - * Under all OSs, the OSK/OSU layer must translate native OS error codes to - * _ump_osk/u_errcode_t codes. Similarly, the U/K layer must translate from - * _ump_osk/u_errcode_t codes to native OS error codes. - * - */ -typedef enum -{ - _UMP_OSK_ERR_OK = 0, /**< Success. */ - _UMP_OSK_ERR_FAULT = -1, /**< General non-success */ - _UMP_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */ - _UMP_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */ - _UMP_OSK_ERR_NOMEM = -4, /**< Insufficient memory */ - _UMP_OSK_ERR_TIMEOUT = -5, /**< Timeout occured */ - _UMP_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */ - _UMP_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */ - _UMP_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */ - _UMP_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */ -} _ump_osk_errcode_t; - -/** @endcond */ /* end cond OSU_COPY_OF__UMP_OSU_ERRCODE_T */ - -/** - * @brief OSU Error codes. - * - * OSU error codes - enum values intentionally same as OSK - */ -typedef enum -{ - _UMP_OSU_ERR_OK = 0, /**< Success. */ - _UMP_OSU_ERR_FAULT = -1, /**< General non-success */ - _UMP_OSU_ERR_TIMEOUT = -2, /**< Timeout occured */ -} _ump_osu_errcode_t; - -/** @brief Translate OSU error code to base driver error code. - * - * The _UMP_OSU_TRANSLATE_ERROR macro translates an OSU error code to the - * error codes in use by the base driver. - */ -#define _UMP_OSU_TRANSLATE_ERROR(_ump_osu_errcode) ( ( _UMP_OSU_ERR_OK == (_ump_osu_errcode) ) ? UMP_ERR_NO_ERROR : UMP_ERR_FUNCTION_FAILED) - -/** @defgroup _ump_osu_lock OSU Mutual Exclusion Locks - * @{ */ - -/** @brief OSU Mutual Exclusion Lock flags type. - * - * This is made to look like and function identically to the OSK locks (refer - * to \ref _ump_osk_lock). However, please note the following \b important - * differences: - * - the OSU default lock is a Sleeping, non-interruptible mutex. - * - the OSU adds the ANYUNLOCK type of lock which allows a thread which doesn't - * own the lock to release the lock. - * - the order parameter when creating a lock is currently unused - * - * @note Pay careful attention to the difference in default locks for OSU and - * OSK locks; OSU locks are always non-interruptible, but OSK locks are by - * default, interruptible. This has implications for systems that do not - * distinguish between user and kernel mode. - */ -typedef enum -{ - _UMP_OSU_LOCKFLAG_DEFAULT = 0, /**< Default lock type. */ - /** @enum _ump_osu_lock_flags_t - * - * Flags from 0x8000--0x1 are RESERVED for Kernel-mode - */ - _UMP_OSU_LOCKFLAG_ANYUNLOCK = 0x10000, /**< Mutex that guarantees that any thread can unlock it when locked. Otherwise, this will not be possible. */ - /** @enum _ump_osu_lock_flags_t - * - * Flags from 0x80000000 are RESERVED for User-mode - */ - _UMP_OSU_LOCKFLAG_STATIC = 0x80000000, /* Flag in OSU reserved range to identify lock as a statically initialized lock */ - - } _ump_osu_lock_flags_t; - -typedef enum -{ - _UMP_OSU_LOCKMODE_UNDEF = -1, /**< Undefined lock mode. For internal use only */ - _UMP_OSU_LOCKMODE_RW = 0x0, /**< Default. Lock is used to protect data that is read from and written to */ - /** @enum _ump_osu_lock_mode_t - * - * Lock modes 0x1--0x3F are RESERVED for Kernel-mode */ -} _ump_osu_lock_mode_t; - -/** @brief Private type for Mutual Exclusion lock objects. */ -typedef struct _ump_osu_lock_t_struct _ump_osu_lock_t; - -/** @brief The number of static locks supported in _ump_osu_lock_static(). */ -#define UMP_OSU_STATIC_LOCK_COUNT (sizeof(_ump_osu_static_locks) / sizeof(_ump_osu_lock_t)) - -/** @} */ /* end group _ump_osu_lock */ - -/** @defgroup _ump_osu_memory OSU Memory Allocation - * @{ */ - -/** @brief Allocate zero-initialized memory. - * - * Returns a buffer capable of containing at least \a n elements of \a size - * bytes each. The buffer is initialized to zero. - * - * The buffer is suitably aligned for storage and subsequent access of every - * type that the compiler supports. Therefore, the pointer to the start of the - * buffer may be cast into any pointer type, and be subsequently accessed from - * such a pointer, without loss of information. - * - * When the buffer is no longer in use, it must be freed with _ump_osu_free(). - * Failure to do so will cause a memory leak. - * - * @note Most toolchains supply memory allocation functions that meet the - * compiler's alignment requirements. - * - * @param n Number of elements to allocate - * @param size Size of each element - * @return On success, the zero-initialized buffer allocated. NULL on failure - */ -void *_ump_osu_calloc( u32 n, u32 size ); - -/** @brief Allocate memory. - * - * Returns a buffer capable of containing at least \a size bytes. The - * contents of the buffer are undefined. - * - * The buffer is suitably aligned for storage and subsequent access of every - * type that the compiler supports. Therefore, the pointer to the start of the - * buffer may be cast into any pointer type, and be subsequently accessed from - * such a pointer, without loss of information. - * - * When the buffer is no longer in use, it must be freed with _ump_osu_free(). - * Failure to do so will cause a memory leak. - * - * @note Most toolchains supply memory allocation functions that meet the - * compiler's alignment requirements. - * - * Remember to free memory using _ump_osu_free(). - * @param size Number of bytes to allocate - * @return On success, the buffer allocated. NULL on failure. - */ -void *_ump_osu_malloc( u32 size ); - -/** @brief Free memory. - * - * Reclaims the buffer pointed to by the parameter \a ptr for the system. - * All memory returned from _ump_osu_malloc(), _ump_osu_calloc() and - * _ump_osu_realloc() must be freed before the application exits. Otherwise, - * a memory leak will occur. - * - * Memory must be freed once. It is an error to free the same non-NULL pointer - * more than once. - * - * It is legal to free the NULL pointer. - * - * @param ptr Pointer to buffer to free - */ -void _ump_osu_free( void *ptr ); - -/** @brief Copies memory. - * - * Copies the \a len bytes from the buffer pointed by the parameter \a src - * directly to the buffer pointed by \a dst. - * - * It is an error for \a src to overlap \a dst anywhere in \a len bytes. - * - * @param dst Pointer to the destination array where the content is to be - * copied. - * @param src Pointer to the source of data to be copied. - * @param len Number of bytes to copy. - * @return \a dst is always passed through unmodified. - */ -void *_ump_osu_memcpy( void *dst, const void *src, u32 len ); - -/** @brief Fills memory. - * - * Sets the first \a size bytes of the block of memory pointed to by \a ptr to - * the specified value - * @param ptr Pointer to the block of memory to fill. - * @param chr Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB) - * are used. - * @param size Number of bytes to be set to the value. - * @return \a ptr is always passed through unmodified - */ -void *_ump_osu_memset( void *ptr, u32 chr, u32 size ); - -/** @} */ /* end group _ump_osu_memory */ - - -/** @addtogroup _ump_osu_lock - * @{ */ - -/** @brief Initialize a Mutual Exclusion Lock. - * - * Locks are created in the signalled (unlocked) state. - * - * The parameter \a initial must be zero. - * - * At present, the parameter \a order must be zero. It remains for future - * expansion for mutex order checking. - * - * @param flags flags combined with bitwise OR ('|'), or zero. There are - * restrictions on which flags can be combined, see \ref _ump_osu_lock_flags_t. - * @param initial For future expansion into semaphores. SBZ. - * @param order The locking order of the mutex. SBZ. - * @return On success, a pointer to a \ref _ump_osu_lock_t object. NULL on failure. - */ -_ump_osu_lock_t *_ump_osu_lock_init( _ump_osu_lock_flags_t flags, u32 initial, u32 order ); - -/** @brief Obtain a statically initialized Mutual Exclusion Lock. - * - * Retrieves a reference to a statically initialized lock. Up to - * _UMP_OSU_STATIC_LOCK_COUNT statically initialized locks are - * available. Only _ump_osu_lock_wait(), _ump_osu_lock_trywait(), - * _ump_osu_lock_signal() can be used with statically initialized locks. - * _UMP_OSU_LOCKMODE_RW mode should be used when waiting and signalling - * statically initialized locks. - * - * For the same \a nr a pointer to the same statically initialized lock is - * returned. That is, given the following code: - * @code - * extern u32 n; - * - * _ump_osu_lock_t *locka = _ump_osu_lock_static(n); - * _ump_osu_lock_t *lockb = _ump_osu_lock_static(n); - * @endcode - * Then (locka == lockb), for all 0 <= n < UMP_OSU_STATIC_LOCK_COUNT. - * - * @param nr index of a statically initialized lock [0..UMP_OSU_STATIC_LOCK_COUNT-1] - * @return On success, a pointer to a _ump_osu_lock_t object. NULL on failure. - */ -_ump_osu_lock_t *_ump_osu_lock_static( u32 nr ); - -/** @brief Initialize a Mutual Exclusion Lock safely across multiple threads. - * - * The _ump_osu_lock_auto_init() function guarantees that the given lock will - * be initialized once and precisely once, even in a situation involving - * multiple threads. - * - * This is necessary because the first call to certain Public API functions must - * initialize the API. However, there can be a race involved to call the first - * library function in multi-threaded applications. To resolve this race, a - * mutex can be used. This mutex must be initialized, but initialized only once - * by any thread that might compete for its initialization. This function - * guarantees the initialization to happen correctly, even when there is an - * initialization race between multiple threads. - * - * Otherwise, the operation is identical to the _ump_osu_lock_init() function. - * For more details, refer to _ump_osu_lock_init(). - * - * @param pplock pointer to storage for a _ump_osu_lock_t pointer. This - * _ump_osu_lock_t pointer may point to a _ump_osu_lock_t that has been - * initialized already - * @param flags flags combined with bitwise OR ('|'), or zero. There are - * restrictions on which flags can be combined. Refer to - * \ref _ump_osu_lock_flags_t for more information. - * The absence of any flags (the value 0) results in a sleeping-mutex, - * which is non-interruptible. - * @param initial For future expansion into semaphores. SBZ. - * @param order The locking order of the mutex. SBZ. - * @return On success, _UMP_OSU_ERR_OK is returned and a pointer to an - * initialized \ref _ump_osu_lock_t object is written into \a *pplock. - * _UMP_OSU_ERR_FAULT is returned on failure. - */ -_ump_osu_errcode_t _ump_osu_lock_auto_init( _ump_osu_lock_t **pplock, _ump_osu_lock_flags_t flags, u32 initial, u32 order ); - -/** @brief Wait for a lock to be signalled (obtained). - * - * After a thread has successfully waited on the lock, the lock is obtained by - * the thread, and is marked as unsignalled. The thread releases the lock by - * signalling it. - * - * To prevent deadlock, locks must always be obtained in the same order. - * - * @param lock the lock to wait upon (obtain). - * @param mode the mode in which the lock should be obtained. Currently this - * must be _UMP_OSU_LOCKMODE_RW. - * @return On success, _UMP_OSU_ERR_OK, _UMP_OSU_ERR_FAULT on error. - */ -_ump_osu_errcode_t _ump_osu_lock_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode); - -/** @brief Wait for a lock to be signalled (obtained) with timeout - * - * After a thread has successfully waited on the lock, the lock is obtained by - * the thread, and is marked as unsignalled. The thread releases the lock by - * signalling it. - * - * To prevent deadlock, locks must always be obtained in the same order. - * - * This version can return early if it cannot obtain the lock within the given timeout. - * - * @param lock the lock to wait upon (obtain). - * @param mode the mode in which the lock should be obtained. Currently this - * must be _UMP_OSU_LOCKMODE_RW. - * @param timeout Relative time in microseconds for the timeout - * @return _UMP_OSU_ERR_OK if the lock was obtained, _UMP_OSU_ERR_TIMEOUT if the timeout expired or _UMP_OSU_ERR_FAULT on error. - */ -_ump_osu_errcode_t _ump_osu_lock_timed_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode, u64 timeout); - -/** @brief Test for a lock to be signalled and obtains the lock when so. - * - * Obtains the lock only when it is in signalled state. The lock is then - * marked as unsignalled. The lock is released again by signalling - * it by _ump_osu_lock_signal(). - * - * If the lock could not be obtained immediately (that is, another thread - * currently holds the lock), then this function \b does \b not wait for the - * lock to be in a signalled state. Instead, an error code is immediately - * returned to indicate that the thread could not obtain the lock. - * - * To prevent deadlock, locks must always be obtained in the same order. - * - * @param lock the lock to wait upon (obtain). - * @param mode the mode in which the lock should be obtained. Currently this - * must be _UMP_OSU_LOCKMODE_RW. - * @return When the lock was obtained, _UMP_OSU_ERR_OK. If the lock could not - * be obtained, _UMP_OSU_ERR_FAULT. - */ -_ump_osu_errcode_t _ump_osu_lock_trywait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode); - -/** @brief Signal (release) a lock. - * - * Locks may only be signalled by the thread that originally waited upon the - * lock, unless the lock was created using the _UMP_OSU_LOCKFLAG_ANYUNLOCK flag. - * - * @param lock the lock to signal (release). - * @param mode the mode in which the lock should be obtained. This must match - * the mode in which the lock was waited upon. - */ -void _ump_osu_lock_signal( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode ); - -/** @brief Terminate a lock. - * - * This terminates a lock and frees all associated resources. - * - * It is a programming error to terminate the lock when it is held (unsignalled) - * by a thread. - * - * @param lock the lock to terminate. - */ -void _ump_osu_lock_term( _ump_osu_lock_t *lock ); -/** @} */ /* end group _ump_osu_lock */ - -/** @} */ /* end group osuapi */ - -/** @} */ /* end group uddapi */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_OSU_H__ */ diff --git a/exynos4/hal/libump/include/ump/ump_platform.h b/exynos4/hal/libump/include/ump/ump_platform.h deleted file mode 100644 index 68e01be..0000000 --- a/exynos4/hal/libump/include/ump/ump_platform.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_platform.h - * - * This file should define UMP_API_EXPORT, - * which dictates how the UMP user space API should be exported/imported. - * Modify this file, if needed, to match your platform setup. - */ - -#ifndef __UMP_PLATFORM_H__ -#define __UMP_PLATFORM_H__ - -/** @addtogroup ump_user_space_api - * @{ */ - -/** - * A define which controls how UMP user space API functions are imported and exported. - * This define should be set by the implementor of the UMP API. - */ -#if defined(_WIN32) - -#define UMP_API_EXPORT - -#elif defined(__SYMBIAN32__) - -#define UMP_API_EXPORT IMPORT_C - -#else - -#if defined(__GNUC__) -#if __GNUC__ >= 4 -# define MALI_VISIBLE __attribute__ ((visibility ("default"))) /**< Function should be visible from outside the dll */ -#else -# define MALI_VISIBLE -#endif - -#elif defined(__ARMCC_VERSION) -/* ARMCC specific */ -# define MALI_VISIBLE __declspec(dllexport) - -#else -# define MALI_VISIBLE - -#endif - -#define UMP_API_EXPORT MALI_VISIBLE - -#endif - -/** @} */ /* end group ump_user_space_api */ - - -#endif /* __UMP_PLATFORM_H__ */ diff --git a/exynos4/hal/libump/include/ump/ump_ref_drv.h b/exynos4/hal/libump/include/ump/ump_ref_drv.h deleted file mode 100644 index 19fb28d..0000000 --- a/exynos4/hal/libump/include/ump/ump_ref_drv.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_ref_drv.h - * - * Reference driver extensions to the UMP user space API for allocating UMP memory - */ - -#ifndef _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ -#define _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ - -#include "ump.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - /* This enum must match with the IOCTL enum in ump_ioctl.h */ - UMP_REF_DRV_CONSTRAINT_NONE = 0, - UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR = 1, - UMP_REF_DRV_CONSTRAINT_USE_CACHE = 4, -} ump_alloc_constraints; - -/** Allocate an UMP handle containing a memory buffer. - * Input: Size: The minimum size for the allocation. - * Usage: If this is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu. - * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached. - * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported.*/ -UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage); - -typedef enum -{ - UMP_MSYNC_CLEAN = 0 , - UMP_MSYNC_CLEAN_AND_INVALIDATE = 1, - UMP_MSYNC_READOUT_CACHE_ENABLED = 128, -} ump_cpu_msync_op; - -/** Flushing cache for an ump_handle. - * The function will always CLEAN_AND_INVALIDATE as long as the \a op is not UMP_MSYNC_READOUT_CACHE_ENABLED. - * If so it will only report back if the given ump_handle is cacheable. - * At the momement the implementation does not use \a address or \a size. - * Return value is 1 if cache is enabled, and 0 if it is disabled for the given allocation.*/ -UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void* address, int size); - - -#ifdef __cplusplus -} -#endif - -#endif /*_UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ */ diff --git a/exynos4/hal/libump/include/ump/ump_uk_types.h b/exynos4/hal/libump/include/ump/ump_uk_types.h deleted file mode 100644 index 1a4c1c8..0000000 --- a/exynos4/hal/libump/include/ump/ump_uk_types.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_uk_types.h - * Defines the types and constants used in the user-kernel interface - */ - -#ifndef __UMP_UK_TYPES_H__ -#define __UMP_UK_TYPES_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Helpers for API version handling */ -#define MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) -#define IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) -#define GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) -#define IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) - -/** - * API version define. - * Indicates the version of the kernel API - * The version is a 16bit integer incremented on each API change. - * The 16bit integer is stored twice in a 32bit integer - * So for version 1 the value would be 0x00010001 - */ -#define UMP_IOCTL_API_VERSION MAKE_VERSION_ID(2) - -typedef enum -{ - _UMP_IOC_QUERY_API_VERSION = 1, - _UMP_IOC_ALLOCATE, - _UMP_IOC_RELEASE, - _UMP_IOC_SIZE_GET, - _UMP_IOC_MAP_MEM, /* not used in Linux */ - _UMP_IOC_UNMAP_MEM, /* not used in Linux */ - _UMP_IOC_MSYNC, -}_ump_uk_functions; - -typedef enum -{ - UMP_REF_DRV_UK_CONSTRAINT_NONE = 0, - UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR = 1, - UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE = 4, -} ump_uk_alloc_constraints; - -typedef enum -{ - _UMP_UK_MSYNC_CLEAN = 0, - _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1, - _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128, -} ump_uk_msync_op; - -/** - * Get API version ([in,out] u32 api_version, [out] u32 compatible) - */ -typedef struct _ump_uk_api_version_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 version; /**< Set to the user space version on entry, stores the device driver version on exit */ - u32 compatible; /**< Non-null if the device is compatible with the client */ -} _ump_uk_api_version_s; - -/** - * ALLOCATE ([out] u32 secure_id, [in,out] u32 size, [in] contraints) - */ -typedef struct _ump_uk_allocate_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Return value from DD to Userdriver */ - u32 size; /**< Input and output. Requested size; input. Returned size; output */ - ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */ -} _ump_uk_allocate_s; - -/** - * SIZE_GET ([in] u32 secure_id, [out]size ) - */ -typedef struct _ump_uk_size_get_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Input to DD */ - u32 size; /**< Returned size; output */ -} _ump_uk_size_get_s; - -/** - * Release ([in] u32 secure_id) - */ -typedef struct _ump_uk_release_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< Input to DD */ -} _ump_uk_release_s; - -typedef struct _ump_uk_map_mem_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [out] Returns user-space virtual address for the mapping */ - void *phys_addr; /**< [in] physical address */ - unsigned long size; /**< [in] size */ - u32 secure_id; /**< [in] secure_id to assign to mapping */ - void * _ukk_private; /**< Only used inside linux port between kernel frontend and common part to store vma */ - u32 cookie; - u32 is_cached; /**< [in,out] caching of CPU mappings */ -} _ump_uk_map_mem_s; - -typedef struct _ump_uk_unmap_mem_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; - u32 size; - void * _ukk_private; - u32 cookie; -} _ump_uk_unmap_mem_s; - -typedef struct _ump_uk_msync_s -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [in] mapping addr */ - void *address; /**< [in] flush start addr */ - u32 size; /**< [in] size to flush */ - ump_uk_msync_op op; /**< [in] flush operation */ - u32 cookie; /**< [in] cookie stored with reference to the kernel mapping internals */ - u32 secure_id; /**< [in] cookie stored with reference to the kernel mapping internals */ - u32 is_cached; /**< [out] caching of CPU mappings */ -} _ump_uk_msync_s; - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_UK_TYPES_H__ */ diff --git a/exynos4/hal/libump/os/linux/ump_ioctl.h b/exynos4/hal/libump/os/linux/ump_ioctl.h deleted file mode 100644 index a62c31a..0000000 --- a/exynos4/hal/libump/os/linux/ump_ioctl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UMP_IOCTL_H__ -#define __UMP_IOCTL_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -#include - -#ifndef __user -#define __user -#endif - - -/** - * @file UMP_ioctl.h - * This file describes the interface needed to use the Linux device driver. - * The interface is used by the userpace UMP driver. - */ - -#define UMP_IOCTL_NR 0x90 - - -#define UMP_IOC_QUERY_API_VERSION _IOR(UMP_IOCTL_NR, _UMP_IOC_QUERY_API_VERSION, _ump_uk_api_version_s) -#define UMP_IOC_ALLOCATE _IOWR(UMP_IOCTL_NR, _UMP_IOC_ALLOCATE, _ump_uk_allocate_s) -#define UMP_IOC_RELEASE _IOR(UMP_IOCTL_NR, _UMP_IOC_RELEASE, _ump_uk_release_s) -#define UMP_IOC_SIZE_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_SIZE_GET, _ump_uk_size_get_s) -#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_size_get_s) - - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_IOCTL_H__ */ diff --git a/exynos4/hal/libump/os/linux/ump_osu_locks.c b/exynos4/hal/libump/os/linux/ump_osu_locks.c deleted file mode 100644 index 97ba858..0000000 --- a/exynos4/hal/libump/os/linux/ump_osu_locks.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if ((!defined _XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 600)) -#undef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 -#endif - - -#define _POSIX_C_SOURCE 200112L - -#include -#include - -#include -#include -#include -#include - -/** - * @file ump_osu_locks.c - * File implements the user side of the OS interface - */ - -/** @opt Most of the time, we use the plain mutex type of osu_lock, and so - * only require the flags and mutex members. This costs 2 extra DWORDS, but - * most of the time we don't use those DWORDS. - * Therefore, ANY_UNLOCK type osu_locks can be implemented as a second - * structure containing the member _ump_osu_lock_t lock_t, plus the extra - * state required. Then, we use &container->lock_t when passing out of the - * OSU api, and CONTAINER_OF() when passing back in to recover the original - * structure. */ - -/** Private declaration of the OSU lock type */ -struct _ump_osu_lock_t_struct -{ - /** At present, only two types of mutex, so we store this information as - * the flags supplied at init time */ - _ump_osu_lock_flags_t flags; - - pthread_mutex_t mutex; /**< Used in both plain and ANY_UNLOCK osu_locks */ - - /* Extra State for ANY_UNLOCK osu_locks. These are UNINITIALIZED when - * flags does not contain _UMP_OSU_LOCKFLAG_ANYUNLOCK: */ - pthread_cond_t condition; /**< The condition object to use while blocking */ - ump_bool state; /**< The boolean which indicates the event's state */ - - UMP_DEBUG_CODE( - /** debug checking of locks */ - _ump_osu_lock_mode_t locked_as; - ) /* UMP_DEBUG_CODE */ - -}; - -/* Provide two statically initialized locks */ -UMP_STATIC _ump_osu_lock_t _ump_osu_static_locks[] = -{ - { - _UMP_OSU_LOCKFLAG_STATIC, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_COND_INITIALIZER, - UMP_FALSE, - UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF ) - }, - { - _UMP_OSU_LOCKFLAG_STATIC, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_COND_INITIALIZER, - UMP_FALSE, - UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF ) - }, - { - _UMP_OSU_LOCKFLAG_STATIC, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_COND_INITIALIZER, - UMP_FALSE, - UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF ) - }, - { - _UMP_OSU_LOCKFLAG_STATIC, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_COND_INITIALIZER, - UMP_FALSE, - UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF ) - }, -}; - -/* Critical section for auto_init */ -UMP_STATIC pthread_mutex_t static_auto_init_mutex = PTHREAD_MUTEX_INITIALIZER; - - -_ump_osu_errcode_t _ump_osu_lock_auto_init( _ump_osu_lock_t **pplock, _ump_osu_lock_flags_t flags, u32 initial, u32 order ) -{ - int call_result; - /* Validate parameters: */ - UMP_DEBUG_ASSERT_POINTER( pplock ); - - /** @opt We don't lock the Critical Section or do anything if this is already non-null */ - if ( NULL != *pplock) - { - return _UMP_OSU_ERR_OK; - } - - /* We MIGHT need to initialize it, lock the Critical Section and check again */ - call_result = pthread_mutex_lock(&static_auto_init_mutex); - /* It would be a programming error for this to fail: */ - UMP_DEBUG_ASSERT( 0 == call_result, - ("failed to lock critical section\n") ); - - if ( NULL != *pplock ) - { - /* - We caught a race condition to initialize this osu_lock. - The other thread won the race, so the osu_lock is now initialized. - */ - call_result = pthread_mutex_unlock(&static_auto_init_mutex); - - UMP_DEBUG_ASSERT(0 == call_result, - ("failed to unlock critical section\n")); - - return _UMP_OSU_ERR_OK; - } - - /* We're the first thread in: initialize the osu_lock */ - *pplock = _ump_osu_lock_init( flags, initial, order ); - - if ( NULL == *pplock ) - { - /* osu_lock creation failed */ - call_result = pthread_mutex_unlock(&static_auto_init_mutex); - UMP_DEBUG_ASSERT(0 == call_result, - ("failed to unlock critical section\n")); - - return _UMP_OSU_ERR_FAULT; - } - - - /* osu_lock created OK */ - call_result = pthread_mutex_unlock(&static_auto_init_mutex); - - UMP_DEBUG_ASSERT(0 == call_result, - ("failed to unlock critical section\n")); - - UMP_IGNORE( call_result ); - - return _UMP_OSU_ERR_OK; -} - - -_ump_osu_lock_t *_ump_osu_lock_init( _ump_osu_lock_flags_t flags, u32 initial, u32 order ) -{ - _ump_osu_lock_t * lock; - pthread_mutexattr_t mutex_attributes; - - /* Validate parameters: */ - /* Flags acceptable */ - UMP_DEBUG_ASSERT( 0 == ( flags & ~( _UMP_OSU_LOCKFLAG_ANYUNLOCK)), - ("incorrect flags or trying to initialise a statically initialized lock, %.8X\n", flags) ); - - /* Parameter initial SBZ - for future expansion */ - UMP_DEBUG_ASSERT( 0 == initial, - ("initial must be zero\n") ); - - if (0 != pthread_mutexattr_init(&mutex_attributes)) - { - return NULL; - } - -#if UMP_DEBUG_EXTENDED_MUTEX_LOCK_CHECKING -#define UMP_PTHREADS_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK -#else -#define UMP_PTHREADS_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT -#endif - - if (0 != pthread_mutexattr_settype(&mutex_attributes, UMP_PTHREADS_MUTEX_TYPE)) - { - /** Return NULL on failure */ - pthread_mutexattr_destroy(&mutex_attributes); - return NULL; - - } - -#undef UMP_PTHREADS_MUTEX_TYPE - - /** @opt use containing structures for the ANY_UNLOCK type, to - * save 2 DWORDS when not in use */ - lock = _ump_osu_malloc( sizeof(_ump_osu_lock_t) ); - - if( NULL == lock ) - { - /** Return NULL on failure */ - pthread_mutexattr_destroy(&mutex_attributes); - return NULL; - } - - if (0 != pthread_mutex_init( &lock->mutex, &mutex_attributes )) - { - pthread_mutexattr_destroy(&mutex_attributes); - _ump_osu_free( lock ); - return NULL; - } - - /* done with the mutexattr object */ - pthread_mutexattr_destroy(&mutex_attributes); - - /* ANY_UNLOCK type */ - if ( flags & _UMP_OSU_LOCKFLAG_ANYUNLOCK ) - { - if (0 != pthread_cond_init( &lock->condition, NULL )) - { - /* cleanup */ - pthread_mutex_destroy( &lock->mutex ); - _ump_osu_free( lock ); - return NULL; - } - lock->state = UMP_FALSE; /* mark as unlocked by default */ - } - - lock->flags = flags; - - /** Debug lock checking */ - UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF ); - - return lock; -} - -_ump_osu_errcode_t _ump_osu_lock_timed_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode, u64 timeout) -{ - /* absolute time specifier */ - struct timespec ts; - struct timeval tv; - - /* Parameter validation */ - UMP_DEBUG_ASSERT_POINTER( lock ); - - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode, - ("unrecognised mode, %.8X\n", mode) ); - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKFLAG_ANYUNLOCK == lock->flags, ("Timed operations only implemented for ANYUNLOCK type locks")); - - /* calculate the realtime timeout value */ - - if (0 != gettimeofday(&tv, NULL)) - { - UMP_DEBUG_PRINT(1,("Could not get the current realtime value to calculate the absolute value for a timed mutex lock with a timeout")); - return _UMP_OSU_ERR_FAULT; - } - - tv.tv_usec += timeout; - -#define UMP_USECS_PER_SECOND 1000000ULL -#define UMP_NANOSECS_PER_USEC 1000ULL - - /* did we overflow a second in the usec part? */ - while (tv.tv_usec >= UMP_USECS_PER_SECOND) - { - tv.tv_usec -= UMP_USECS_PER_SECOND; - tv.tv_sec++; - } - - /* copy to the correct struct */ - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = (tv.tv_usec * UMP_NANOSECS_PER_USEC); - -#undef UMP_USECS_PER_SECOND -#undef UMP_NANOSECS_PER_USEC - - /* lock the mutex protecting access to the state field */ - pthread_mutex_lock( &lock->mutex ); - /* loop while locked (state is UMP_TRUE) */ - /* pthread_cond_timedwait unlocks the mutex, wait, and locks the mutex once unblocked (either due to the event or the timeout) */ - while ( UMP_TRUE == lock->state ) - { - int res; - res = pthread_cond_timedwait( &lock->condition, &lock->mutex, &ts ); - if (0 == res) continue; /* test the state variable again (loop condition) */ - else if (ETIMEDOUT == res) - { - /* timeout, need to clean up and return the correct error code */ - pthread_mutex_unlock(&lock->mutex); - return _UMP_OSU_ERR_TIMEOUT; - } - else - { - UMP_DEBUG_PRINT(1, ("Unexpected return from pthread_cond_timedwait 0x%08X\n", res)); - - pthread_mutex_unlock(&lock->mutex); - return _UMP_OSU_ERR_FAULT; - } - - } - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as, - ("This lock was already locked\n") ); - UMP_DEBUG_CODE( lock->locked_as = mode ); - - /* the state is UMP_FALSE (unlocked), so we set it to UMP_TRUE to indicate that it's locked and can return knowing that we own the lock */ - lock->state = UMP_TRUE; - /* final unlock of the mutex */ - pthread_mutex_unlock(&lock->mutex); - - return _UMP_OSU_ERR_OK; - -} - -_ump_osu_errcode_t _ump_osu_lock_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode) -{ - /* Parameter validation */ - UMP_DEBUG_ASSERT_POINTER( lock ); - - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode, - ("unrecognised mode, %.8X\n", mode) ); - - /** @note since only one flag can be set, we use a switch statement here. - * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the - * implemented lock type */ - switch ( lock->flags ) - { - case _UMP_OSU_LOCKFLAG_STATIC: - case 0: - /* Usual Mutex type */ - { - int call_result; - call_result = pthread_mutex_lock( &lock->mutex ); - UMP_DEBUG_ASSERT( 0 == call_result, - ("pthread_mutex_lock call failed with error code %d\n", call_result)); - UMP_IGNORE( call_result ); - } - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as, - ("This lock was already locked\n") ); - UMP_DEBUG_CODE( lock->locked_as = mode ); - break; - - case _UMP_OSU_LOCKFLAG_ANYUNLOCK: - /** @note Use of bitflags in a case statement ONLY works because this - * is the ONLY flag that is supported */ - - /* lock the mutex protecting access to the state field */ - pthread_mutex_lock( &lock->mutex ); - /* loop while locked (state is UMP_TRUE) */ - /* pthread_cond_wait unlocks the mutex, wait, and locks the mutex once unblocked */ - while ( UMP_TRUE == lock->state ) pthread_cond_wait( &lock->condition, &lock->mutex ); - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as, - ("This lock was already locked\n") ); - UMP_DEBUG_CODE( lock->locked_as = mode ); - - /* the state is UMP_FALSE (unlocked), so we set it to UMP_TRUE to indicate that it's locked and can return knowing that we own the lock */ - lock->state = UMP_TRUE; - /* final unlock of the mutex */ - pthread_mutex_unlock(&lock->mutex); - break; - - default: - UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) ); - break; - } - - return _UMP_OSU_ERR_OK; -} - -_ump_osu_errcode_t _ump_osu_lock_trywait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode) -{ - _ump_osu_errcode_t err = _UMP_OSU_ERR_FAULT; - /* Parameter validation */ - UMP_DEBUG_ASSERT_POINTER( lock ); - - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode, - ("unrecognised mode, %.8X\n", mode) ); - - /** @note since only one flag can be set, we use a switch statement here. - * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the - * implemented lock type */ - switch ( lock->flags ) - { - case _UMP_OSU_LOCKFLAG_STATIC: - case 0: - /* Usual Mutex type */ - { - /* This is not subject to UMP_CHECK - overriding the result would cause a programming error */ - if ( 0 == pthread_mutex_trylock( &lock->mutex ) ) - { - err = _UMP_OSU_ERR_OK; - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as - || mode == lock->locked_as, - ("tried as mode==%.8X, but was locked as %.8X\n", mode, lock->locked_as) ); - UMP_DEBUG_CODE( lock->locked_as = mode ); - } - } - break; - - case _UMP_OSU_LOCKFLAG_ANYUNLOCK: - /** @note Use of bitflags in a case statement ONLY works because this - * is the ONLY flag that is supported */ - - /* lock the mutex protecting access to the state field */ - pthread_mutex_lock(&lock->mutex); - - if ( UMP_FALSE == lock->state) - { - /* unlocked, take the lock */ - lock->state = UMP_TRUE; - err = _UMP_OSU_ERR_OK; - } - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - /* Can do this regardless of whether we obtained ANYUNLOCK: */ - - - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as - || mode == lock->locked_as, - ("tried as mode==%.8X, but was locked as %.8X\n", mode, lock->locked_as) ); - /* If we were already locked, this does no harm, because of the above assert: */ - UMP_DEBUG_CODE( lock->locked_as = mode ); - - pthread_mutex_unlock(&lock->mutex); - break; - - default: - UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) ); - break; - } - - return err; -} - - -void _ump_osu_lock_signal( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode ) -{ - /* Parameter validation */ - UMP_DEBUG_ASSERT_POINTER( lock ); - - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode, - ("unrecognised mode, %.8X\n", mode) ); - - /** @note since only one flag can be set, we use a switch statement here. - * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the - * implemented lock type */ - switch ( lock->flags ) - { - case _UMP_OSU_LOCKFLAG_STATIC: - case 0: - /* Usual Mutex type */ - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( mode == lock->locked_as, - ("This lock was locked as==%.8X, but tried to unlock as mode==%.8X\n", lock->locked_as, mode)); - UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF ); - - { - int call_result; - call_result = pthread_mutex_unlock( &lock->mutex ); - UMP_DEBUG_ASSERT( 0 == call_result, - ("pthread_mutex_lock call failed with error code %d\n", call_result)); - UMP_IGNORE( call_result ); - } - break; - - case _UMP_OSU_LOCKFLAG_ANYUNLOCK: - /** @note Use of bitflags in a case statement ONLY works because this - * is the ONLY flag that is supported */ - - pthread_mutex_lock(&lock->mutex); - UMP_DEBUG_ASSERT( UMP_TRUE == lock->state, ("Unlocking a _ump_osu_lock_t %p which is not locked\n", lock)); - - /* DEBUG tracking of previously locked state - occurs while lock is obtained */ - UMP_DEBUG_ASSERT( mode == lock->locked_as, - ("This lock was locked as==%.8X, but tried to unlock as %.8X\n", lock->locked_as, mode )); - UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF ); - - /* mark as unlocked */ - lock->state = UMP_FALSE; - - /* signal the condition, only wake a single thread */ - pthread_cond_signal(&lock->condition); - - pthread_mutex_unlock(&lock->mutex); - break; - - default: - UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) ); - break; - } -} - -void _ump_osu_lock_term( _ump_osu_lock_t *lock ) -{ - int call_result; - UMP_DEBUG_ASSERT_POINTER( lock ); - - /** Debug lock checking: */ - /* Lock is signalled on terminate - not a guarantee, since we could be locked immediately beforehand */ - UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as, - ("cannot terminate held lock\n") ); - - call_result = pthread_mutex_destroy( &lock->mutex ); - UMP_DEBUG_ASSERT( 0 == call_result, - ("Incorrect mutex use detected: pthread_mutex_destroy call failed with error code %d\n", call_result) ); - - /* Destroy extra state for ANY_UNLOCK type osu_locks */ - if ( lock->flags & _UMP_OSU_LOCKFLAG_ANYUNLOCK ) - { - UMP_DEBUG_ASSERT( UMP_FALSE == lock->state, ("terminate called on locked object %p\n", lock)); - call_result = pthread_cond_destroy(&lock->condition); - UMP_DEBUG_ASSERT( 0 == call_result, - ("Incorrect condition-variable use detected: pthread_cond_destroy call failed with error code %d\n", call_result) ); - } - - UMP_IGNORE(call_result); - - _ump_osu_free( lock ); -} - -_ump_osu_lock_t *_ump_osu_lock_static( u32 nr ) -{ - UMP_DEBUG_ASSERT( nr < UMP_OSU_STATIC_LOCK_COUNT, - ("provided static lock index (%d) out of bounds (0 < nr < %d)\n", nr, UMP_OSU_STATIC_LOCK_COUNT) ); - return &_ump_osu_static_locks[nr]; -} diff --git a/exynos4/hal/libump/os/linux/ump_osu_memory.c b/exynos4/hal/libump/os/linux/ump_osu_memory.c deleted file mode 100644 index 5807594..0000000 --- a/exynos4/hal/libump/os/linux/ump_osu_memory.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include /* memcmp, memchr, memset */ - -/** - * @file ump_osu_memory.c - * File implements the user side of the OS interface - */ - -void *_ump_osu_calloc( u32 n, u32 size ) -{ - return calloc( n, size ); -} - -void *_ump_osu_malloc( u32 size ) -{ - return malloc( size ); -} - -void *_ump_osu_realloc( void *ptr, u32 size ) -{ - return realloc( ptr, size ); -} - -void _ump_osu_free( void *ptr ) -{ - free( ptr ); -} - -void *_ump_osu_memcpy( void *dst, const void *src, u32 len ) -{ - return memcpy( dst, src, len ); -} - -void *_ump_osu_memset( void *ptr, u32 chr, u32 size ) -{ - return memset( ptr, chr, size ); -} - -int _ump_osu_memcmp( const void *ptr1, const void *ptr2, u32 size ) -{ - return memcmp( ptr1, ptr2, size ); -} diff --git a/exynos4/hal/libump/os/linux/ump_uku.c b/exynos4/hal/libump/os/linux/ump_uku.c deleted file mode 100644 index f46a2c7..0000000 --- a/exynos4/hal/libump/os/linux/ump_uku.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_uku.c - * File implements the user side of the user-kernel interface - */ - -#include "../ump_uku.h" -#include -#include "ump_ioctl.h" - -#include - -/* Needed for file operations on the device file*/ -#include -#include -#include -#include -#include - -static _ump_osu_errcode_t ump_driver_ioctl(void *context, u32 command, void *args); - -static int ump_ioctl_api_version_used = UMP_IOCTL_API_VERSION; - -/** - * The device file to access the UMP device driver - * This is a character special file giving access to the device driver. - * Usually created using the mknod command line utility. - */ -static const char ump_device_file_name[] = "/dev/ump"; - -_ump_osu_errcode_t _ump_uku_open( void **context ) -{ - int ump_device_file; - if(NULL == context) - { - return _UMP_OSU_ERR_FAULT; - } - - ump_device_file = open(ump_device_file_name, O_RDWR); - - if (-1 == ump_device_file) - { - return _UMP_OSU_ERR_FAULT; - } - - { - struct _ump_uk_api_version_s args; - args.ctx = (void*)ump_device_file; - args.version = UMP_IOCTL_API_VERSION; - args.compatible = 3; - ump_driver_ioctl(args.ctx, UMP_IOC_QUERY_API_VERSION, &args); - if ( 1 != args.compatible ) - { - if (IS_API_MATCH(MAKE_VERSION_ID(1), args.version)) - { - ump_ioctl_api_version_used = MAKE_VERSION_ID(1); - UMP_PRINTF("The UMP devicedriver does not support cached UMP. Update it if this is needed.\n"); - } - else - { - UMP_PRINTF("The UMP devicedriver is version: %d, UMP libraries is version: %d.\n", GET_VERSION(args.version), GET_VERSION(UMP_IOCTL_API_VERSION) ); - close(ump_device_file); - return _UMP_OSU_ERR_FAULT; - } - } - } - - *context = (void *) ump_device_file; - return _UMP_OSU_ERR_OK; -} - -_ump_osu_errcode_t _ump_uku_close( void **context ) -{ - if(NULL == context) - { - return _UMP_OSU_ERR_FAULT; - } - - if(-1 == (int)*context) - { - return _UMP_OSU_ERR_FAULT; - } - - close((int)*context); - *context = (void *)-1; - - return _UMP_OSU_ERR_OK; -} - -int _ump_uku_allocate(_ump_uk_allocate_s *args) -{ - return ump_driver_ioctl(args->ctx, UMP_IOC_ALLOCATE, args); -} - -_ump_osu_errcode_t _ump_uku_release(_ump_uk_release_s *args) -{ - return ump_driver_ioctl(args->ctx, UMP_IOC_RELEASE, args); -} - -_ump_osu_errcode_t _ump_uku_size_get(_ump_uk_size_get_s *args) -{ - return ump_driver_ioctl(args->ctx, UMP_IOC_SIZE_GET, args); -} - - -void _ump_uku_msynch(_ump_uk_msync_s *args) -{ - /* This is for backwards compatibillity */ - if ( MAKE_VERSION_ID(1) == ump_ioctl_api_version_used) - { - args->is_cached = 0; - if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED != args->op ) - { - UMP_DEBUG_PRINT(3, ("Warning: Doing UMP cache flush operations on a Device Driver that does not support cached UMP mem.\n")); - } - return; - } - ump_driver_ioctl(args->ctx, UMP_IOC_MSYNC, args); -} - -int _ump_uku_map_mem(_ump_uk_map_mem_s *args) -{ - int flags; - if( -1 == (int)args->ctx ) - { - return -1; - } - - flags = MAP_SHARED; - - /* This is for backwards compatibillity */ - if ( MAKE_VERSION_ID(1) == ump_ioctl_api_version_used) - { - args->is_cached = 0; - } - - /* If we want the Caching to be enabled we set the flags to be PRIVATE. The UMP DD reads this and do proper handling - Note: this enforces the user to use proper invalidation*/ - if ( args->is_cached ) flags = MAP_PRIVATE; - - args->mapping = mmap(NULL, args->size, PROT_READ | PROT_WRITE ,flags , (int)args->ctx, (off_t)args->secure_id * sysconf(_SC_PAGE_SIZE)); - if (MAP_FAILED == args->mapping) - { - return -1; - } - - args->cookie = 0; /* Cookie is not used in linux _ump_uku_unmap_mem */ - - return 0; -} - -void _ump_uku_unmap_mem( _ump_uk_unmap_mem_s *args ) -{ - /* - * If a smaller size is used Linux will just remove the requested range but don't tell - * the ump driver before all of it is unmapped, either via another unmap request or upon process shutdown. - * Unmapping too much will just ignore the overhead or hit undefined behavior, - * only affecting the calling process which could mess itself up in other ways anyway. - * So we don't need any security checks here. - */ - munmap(args->mapping, args->size); -} - -static _ump_osu_errcode_t ump_driver_ioctl(void *context, u32 command, void *args) -{ - /*UMP_CHECK_NON_NULL(args, _UMP_OSK_ERR_INVALID_ARGS);*/ - - /* check for a valid file descriptor */ - /** @note manual type safety check-point */ - if( -1 == (int)context ) - { - return _UMP_OSU_ERR_FAULT; - } - - /* call ioctl handler of driver */ - if (0 != ioctl((int)context, command, args)) return -1; - return _UMP_OSU_ERR_OK; -} diff --git a/exynos4/hal/libump/os/ump_uku.h b/exynos4/hal/libump/os/ump_uku.h deleted file mode 100644 index 7da7185..0000000 --- a/exynos4/hal/libump/os/ump_uku.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file ump_uku.h - * Defines the user-side interface of the user-kernel interface - */ - -#ifndef __UMP_UKU_H__ -#define __UMP_UKU_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -_ump_osu_errcode_t _ump_uku_open( void **context ); - -_ump_osu_errcode_t _ump_uku_close( void **context ); - -_ump_osu_errcode_t _ump_uku_allocate( _ump_uk_allocate_s *args ); - -_ump_osu_errcode_t _ump_uku_release( _ump_uk_release_s *args ); - -_ump_osu_errcode_t _ump_uku_size_get( _ump_uk_size_get_s *args ); - -_ump_osu_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args ); - -int _ump_uku_map_mem( _ump_uk_map_mem_s *args ); - -void _ump_uku_unmap_mem( _ump_uk_unmap_mem_s *args ); - -void _ump_uku_msynch(_ump_uk_msync_s *args); - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_UKU_H__ */ diff --git a/exynos4/hal/libump/readme.txt b/exynos4/hal/libump/readme.txt deleted file mode 100644 index 297df38..0000000 --- a/exynos4/hal/libump/readme.txt +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2010-2011 ARM Limited. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -Building the UMP user space library for Linux ---------------------------------------------- - -A simple Makefile is provided, and the UMP user space library can be built -simply by issuing make. This Makefile is setup to use the ARM GCC compiler -from CodeSourcery, and it builds for ARMv6. Modification to this Makefile -is needed in order to build for other configurations. - -In order to use this library from the Mali GPU driver, invoke the Mali GPU -driver build system with the following two make variables set; -- UMP_INCLUDE_DIR should point to the include folder inside this package -- UMP_LIB should point to the built library (libUMP.so) - -This does not apply to Android builds, where the Android.mk file for the -Mali GPU driver needs to be manually edited in order to add the correct -include path and link against the correct library. diff --git a/exynos4/hal/libump/ump.mak b/exynos4/hal/libump/ump.mak deleted file mode 100644 index e417313..0000000 --- a/exynos4/hal/libump/ump.mak +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (C) 2011 ARM Limited. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -ifeq ($(UMP_NO_UMP),1) - -UMP_SRCS = \ - $(UMP_DIR)/arch_999_no_ump/ump_frontend.c \ - $(UMP_DIR)/arch_999_no_ump/ump_ref_drv.c - -else - -UMP_SRCS = \ - $(UMP_DIR)/arch_011_udd/ump_frontend.c \ - $(UMP_DIR)/arch_011_udd/ump_ref_drv.c \ - $(UMP_DIR)/arch_011_udd/ump_arch.c \ - $(UMP_DIR)/os/$(UDD_OS)/ump_uku.c \ - $(UMP_DIR)/os/$(UDD_OS)/ump_osu_memory.c \ - $(UMP_DIR)/os/$(UDD_OS)/ump_osu_locks.c - -endif - diff --git a/exynos4/multimedia/Android.mk b/exynos4/multimedia/Android.mk deleted file mode 100644 index 6571161..0000000 --- a/exynos4/multimedia/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/exynos4/multimedia/codecs/Android.mk b/exynos4/multimedia/codecs/Android.mk deleted file mode 100644 index 6571161..0000000 --- a/exynos4/multimedia/codecs/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/exynos4/multimedia/codecs/sec_codecs/Android.mk b/exynos4/multimedia/codecs/sec_codecs/Android.mk deleted file mode 100644 index 6571161..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk deleted file mode 100644 index 3bc3577..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk +++ /dev/null @@ -1,11 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -include $(LOCAL_PATH)/exynos4/Android.mk -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -include $(LOCAL_PATH)/exynos5/Android.mk -endif diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk deleted file mode 100644 index df938be..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_AUDIO_PATH :=$(LOCAL_PATH) - -ifeq ($(BOARD_USE_ALP_AUDIO), true) - include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk -else - ifeq ($(USE_ULP_AUDIO), true) - include $(LOCAL_AUDIO_PATH)/srp/ulp/Android.mk - include $(LOCAL_AUDIO_PATH)/srp/libsa_jni/Android.mk - endif -endif diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk deleted file mode 100644 index 7393f68..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - include/srp_api.h \ - include/srp_ioctl.h \ - include/srp_error.h - -LOCAL_SRC_FILES := \ - src/srp_api.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include - -LOCAL_MODULE := libsrpapi - -LOCAL_MODULE_TAGS := optional - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := - -LOCAL_SHARED_LIBRARIES := - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h deleted file mode 100644 index ad65b90..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __SRP_API_H__ -#define __SRP_API_H__ - -#include "srp_ioctl.h" -#include "srp_error.h" - -#define SRP_DEV_NAME "dev/srp" - -#define SRP_INIT_BLOCK_MODE 0 -#define SRP_INIT_NONBLOCK_MODE 1 - -#define SRP_PENDING_STATE_RUNNING 0 -#define SRP_PENDING_STATE_PENDING 1 - -struct srp_buf_info { - void *mmapped_addr; - void *addr; - unsigned int mmapped_size; - unsigned int size; - int num; -}; - -struct srp_dec_info { - unsigned int sample_rate; - unsigned int channels; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int SRP_Create(int block_mode); -int SRP_Init(); -int SRP_Decode(void *buff, int size_byte); -int SRP_Send_EOS(void); -int SRP_SetParams(int id, unsigned long val); -int SRP_GetParams(int id, unsigned long *pval); -int SRP_Deinit(void); -int SRP_Terminate(void); -int SRP_IsOpen(void); - -int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num); -int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num); -int SRP_Get_Dec_Info(struct srp_dec_info *dec_info); -int SRP_Get_PCM(void **addr, unsigned int *size); -int SRP_Flush(void); - -#ifdef __cplusplus -} -#endif - -#endif /*__SRP_API_H__ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h deleted file mode 100644 index 7f79452..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SRP_ERROR_H_ -#define _SRP_ERROR_H_ - -typedef enum { - SRP_RETURN_OK = 0, - - SRP_ERROR_OPEN_FAIL = -1000, - SRP_ERROR_ALREADY_OPEN = -1001, - SRP_ERROR_NOT_READY = -1002, - - SRP_ERROR_IBUF_OVERFLOW = -2000, - SRP_ERROR_IBUF_INFO = -2001, - - SRP_ERROR_OBUF_READ = -3000, - SRP_ERROR_OBUF_INFO = -3001, - SRP_ERROR_OBUF_MMAP = -3002, - - SRP_ERROR_INVALID_SETTING = -4000, - SRP_ERROR_GETINFO_FAIL = -4001 -} SRP_ERRORTYPE; - -#endif /* _SRP_ERROR_H_ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h deleted file mode 100644 index 21d55df..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __SRP_IOCTL_H__ -#define __SRP_IOCTL_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SRP_INIT (0x10000) -#define SRP_DEINIT (0x10001) -#define SRP_GET_MMAP_SIZE (0x10002) -#define SRP_FLUSH (0x20002) -#define SRP_SEND_EOS (0x20005) -#define SRP_GET_IBUF_INFO (0x20007) -#define SRP_GET_OBUF_INFO (0x20008) -#define SRP_STOP_EOS_STATE (0x30007) -#define SRP_GET_DEC_INFO (0x30008) - -#ifdef __cplusplus -} -#endif - -#endif /* __SRP_IOCTL_H__ */ - diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c deleted file mode 100644 index 56125fb..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srp_api.h" - -#define LOG_NDEBUG 1 -#define LOG_TAG "libsrpapi" -#include - -static struct srp_buf_info ibuf_info; -static struct srp_buf_info obuf_info; -static struct srp_buf_info pcm_info; - -static int srp_dev = -1; -static int srp_block_mode = SRP_INIT_BLOCK_MODE; - -int SRP_Create(int block_mode) -{ - if (srp_dev == -1) { - srp_block_mode = block_mode; - srp_dev = open(SRP_DEV_NAME, O_RDWR | - ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); - if (srp_dev > 0) - return srp_dev; - else - return SRP_ERROR_OPEN_FAIL; - } - - LOGE("%s: Device is already opened", __func__); - return SRP_ERROR_ALREADY_OPEN; -} - -int SRP_Init() -{ - int ret = SRP_RETURN_OK; - unsigned int mmapped_size = 0; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_INIT); - if (ret < 0) - return ret; - - /* mmap for OBUF */ - ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size); - if (ret < 0) { - LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__); - return SRP_ERROR_OBUF_MMAP; - } - obuf_info.mmapped_addr = mmap(0, mmapped_size, - PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0); - if (!obuf_info.mmapped_addr) { - LOGE("%s: mmap is failed", __func__); - return SRP_ERROR_OBUF_MMAP; - } - obuf_info.mmapped_size = mmapped_size; - - ret = SRP_RETURN_OK; - } else { - LOGE("%s: Device is not ready", __func__); - ret = SRP_ERROR_NOT_READY; /* device is not created */ - } - - return ret; -} - -int SRP_Decode(void *buff, int size_byte) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - if (size_byte > 0) { - LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte); - - ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ - if (ret < 0) { - if (ret != SRP_ERROR_IBUF_OVERFLOW) - LOGE("SRP_Decode returned error code: %d", ret); - } - return ret; /* Write Success */ - } else { - return ret; - } - } - - LOGE("%s: Device is not ready", __func__); - return SRP_ERROR_NOT_READY; -} - -int SRP_Send_EOS(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_SEND_EOS); - - return SRP_ERROR_NOT_READY; -} - -int SRP_SetParams(int id, unsigned long val) -{ - if (srp_dev != -1) - return 0; /* not yet */ - - return SRP_ERROR_NOT_READY; -} - -int SRP_GetParams(int id, unsigned long *pval) -{ - if (srp_dev != -1) - return ioctl(srp_dev, id, pval); - - return SRP_ERROR_NOT_READY; -} - -int SRP_Flush(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_FLUSH); - - return SRP_ERROR_NOT_READY; -} - -int SRP_Get_PCM(void **addr, unsigned int *size) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - ret = read(srp_dev, &pcm_info, 0); - if (ret == -1) { - *size = 0; - LOGE("%s: PCM read fail", __func__); - return SRP_ERROR_OBUF_READ; - } - - *addr = pcm_info.addr; - *size = pcm_info.size; - } else { - return SRP_ERROR_NOT_READY; - } - - return ret; /* Read Success */ -} - -int SRP_Get_Dec_Info(struct srp_dec_info *dec_info) -{ - int ret; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info); - if (ret < 0) { - LOGE("%s: Failed to get dec info", __func__); - return SRP_ERROR_GETINFO_FAIL; - } - - LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate); - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info); - if (ret == -1) { - LOGE("%s: Failed to get Ibuf info", __func__); - return SRP_ERROR_IBUF_INFO; - } - - *addr = ibuf_info.addr; - *size = ibuf_info.size; - *num = ibuf_info.num; - - if (*num == 0) { - LOGE("%s: IBUF num is 0", __func__); - return SRP_ERROR_INVALID_SETTING; - } - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - if (obuf_info.addr == NULL) { - ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info); - if (ret < 0) { - LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__); - return SRP_ERROR_OBUF_INFO; - } - } - - *addr = obuf_info.addr; - *size = obuf_info.size; - *num = obuf_info.num; - - if (*num == 0) { - LOGE("%s: OBUF num is 0", __func__); - return SRP_ERROR_INVALID_SETTING; - } - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Deinit(void) -{ - if (srp_dev != -1) { - munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size); - return ioctl(srp_dev, SRP_DEINIT); - } - - return SRP_ERROR_NOT_READY; -} - -int SRP_Terminate(void) -{ - int ret; - - if (srp_dev != -1) { - ret = close(srp_dev); - - if (ret == 0) { - srp_dev = -1; /* device closed */ - return SRP_RETURN_OK; - } - } - - return SRP_ERROR_NOT_READY; -} - -int SRP_IsOpen(void) -{ - if (srp_dev == -1) { - LOGV("%s: Device is not opened", __func__); - return 0; - } - - LOGV("%s: Device is opened", __func__); - return 1; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk deleted file mode 100644 index 8450845..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional -LOCAL_PRELINK_MODULE := false - -LOCAL_MODULE := libsa_jni -LOCAL_SRC_FILES := SACtrl.c - -LOCAL_SHARED_LIBRARIES := libcutils -LOCAL_STATIC_LIBRARIES := libsrpapi - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c deleted file mode 100644 index 6b99dc3..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "srp_api_ctrl.h" - -#define LOG_TAG "libsa_jni" -#include - -void Java_com_android_music_SetSACtrlJNI_set(JNIEnv * env, jobject obj, int effect_num) -{ - unsigned long effect_enable = effect_num ? 1 : 0; - unsigned int ret; - - LOGD("Sound effect[%d]", effect_num); - - ret = SRP_Ctrl_Enable_Effect(effect_enable); - if (ret < 0) { - LOGE("%s: Couldn't enabled effect\n", __func__); - return; - } - - SRP_Ctrl_Set_Effect_Def(effect_num << 5); - if (ret < 0) { - LOGE("%s: Couldn't defined effect\n", __func__); - return; - } - - return; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk deleted file mode 100644 index 5b1d397..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - src/srp_api.c \ - src/srp_api_ctrl.c - -LOCAL_MODULE := libsrpapi - -LOCAL_MODULE_TAGS := optional - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := - -LOCAL_SHARED_LIBRARIES := - -LOCAL_COPY_HEADERS := \ - include/srp_api.h \ - include/srp_api_ctrl.h \ - include/srp_ioctl.h - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h deleted file mode 100644 index 74598e5..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __SRP_API_H__ -#define __SRP_API_H__ - -#include "srp_ioctl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int SRP_Create(int block_mode); -int SRP_Init(unsigned int ibuf_size); -int SRP_Decode(void *buff, int size_byte); -int SRP_Send_EOS(void); -int SRP_Resume_EOS(void); -int SRP_Pause(void); -int SRP_Stop(void); -int SRP_Flush(void); -int SRP_SetParams(int id, unsigned long val); -int SRP_GetParams(int id, unsigned long *pval); -int SRP_Deinit(void); -int SRP_Terminate(void); -int SRP_IsOpen(void); - -#define SRP_DEV_NAME "dev/srp" - -#define SRP_INIT_BLOCK_MODE 0 -#define SRP_INIT_NONBLOCK_MODE 1 - -#define SRP_PENDING_STATE_RUNNING 0 -#define SRP_PENDING_STATE_PENDING 1 - -#define SRP_ERROR_LOSTSYNC 0x00101 -#define SRP_ERROR_BADLAYER 0x00102 -#define SRP_ERROR_BADBITRATE 0x00103 -#define SRP_ERROR_BADSAMPLERATE 0x00104 -#define SRP_ERROR_BADEMPHASIS 0x00105 - -#define SRP_ERROR_BADCRC 0x00201 -#define SRP_ERROR_BADBITALLOC 0x00211 -#define SRP_ERROR_BADBADSCALEFACTOR 0x00221 -#define SRP_ERROR_BADFRAMELEN 0x00231 -#define SRP_ERROR_BADBIGVALUES 0x00232 -#define SRP_ERROR_BADBLOCKTYPE 0x00233 -#define SRP_ERROR_BADSCFSI 0x00234 -#define SRP_ERROR_BADDATAPTR 0x00235 -#define SRP_ERROR_BADPART3LEN 0x00236 -#define SRP_ERROR_BADHUFFTABLE 0x00237 -#define SRP_ERROR_BADHUFFDATA 0x00238 -#define SRP_ERROR_BADSTEREO 0x00239 - -#ifdef __cplusplus -} -#endif - -#endif /*__SRP_API_H__ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h deleted file mode 100644 index 3b17acf..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __SRP_API_CTRL_H__ -#define __SRP_API_CTRL_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SRP_CTRL_DEV_NAME "dev/srp_ctrl" - -int SRP_Ctrl_Set_Effect(int effect); /* test only */ -int SRP_Ctrl_Enable_Effect(int on); -int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def); -int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user); -int SRP_Ctrl_Set_Pcm_Dump(int on); -int SRP_Ctrl_Get_Pcm_Dump_State(void); -int SRP_Ctrl_Set_Gain(float value); -int SRP_Ctrl_Get_Running_Stat(void); -int SRP_Ctrl_Get_Open_Stat(void); -short *SRP_Ctrl_Get_Pcm(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __SRP_API_CTRL_H__ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h deleted file mode 100644 index a20b1ac..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __SRP_IOCTL_H__ -#define __SRP_IOCTL_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* constants for srp device node */ -#define SRP_INIT (0x10000) -#define SRP_DEINIT (0x10001) - -#define SRP_PAUSE (0x20000) -#define SRP_STOP (0x20001) -#define SRP_FLUSH (0x20002) -#define SRP_WAIT_EOS (0x20003) -#define SRP_EFFECT (0x20004) -#define SRP_SEND_EOS (0x20005) -#define SRP_RESUME_EOS (0x20006) - -#define SRP_PENDING_STATE (0x30000) -#define SRP_ERROR_STATE (0x30001) -#define SRP_DECODED_FRAME_NO (0x30002) -#define SRP_DECODED_ONE_FRAME_SIZE (0x30003) -#define SRP_DECODED_FRAME_SIZE (0x30004) -#define SRP_DECODED_PCM_SIZE (0x30005) -#define SRP_CHANNEL_COUNT (0x30006) -#define SRP_STOP_EOS_STATE (0x30007) - -/* constants for srp_ctrl device node*/ -#define SRP_CTRL_SET_GAIN (0xFF000) -#define SRP_CTRL_SET_EFFECT (0xFF001) -#define SRP_CTRL_GET_PCM_1KFRAME (0xFF002) -#define SRP_CTRL_PCM_DUMP_OP (0xFF003) - -#define SRP_CTRL_EFFECT_ENABLE (0xFF010) -#define SRP_CTRL_EFFECT_DEF (0xFF011) -#define SRP_CTRL_EFFECT_EQ_USR (0xFF012) -#define SRP_CTRL_EFFECT_SPEAKER (0xFF013) - -#define SRP_CTRL_IS_RUNNING (0xFF100) -#define SRP_CTRL_IS_OPENED (0xFF101) -#define SRP_CTRL_GET_OP_LEVEL (0xFF102) -#define SRP_CTRL_IS_PCM_DUMP (0xFF103) - -#define SRP_CTRL_ALTFW_STATE (0xFF200) -#define SRP_CTRL_ALTFW_LOAD (0xFF201) - -/* constants for SRP firmware */ -#define SRP_FW_CODE1 0 -#define SRP_FW_CODE20 1 -#define SRP_FW_CODE21 2 -#define SRP_FW_CODE22 3 -#define SRP_FW_CODE30 4 -#define SRP_FW_CODE31 5 - -#define SRP_FW_VLIW 0 -#define SRP_FW_CGA 1 -#define SRP_FW_CGA_SA 2 -#define SRP_FW_DATA 3 - -#ifdef __cplusplus -} -#endif - -#endif /* __SRP_IOCTL_H__ */ - diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c deleted file mode 100644 index b0c0e5e..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c +++ /dev/null @@ -1,381 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srp_api.h" - -#define LOG_TAG "libsrpapi" -#include - -/* Disable LOGD message */ -#ifdef LOGD -#undef LOGD -#endif -#define LOGD(...) - -//#define _USE_WBUF_ /* Buffering before writing srp-rp device */ -//#define _DUMP_TO_FILE_ -//#define _USE_FW_FROM_DISK_ - -#ifdef _USE_WBUF_ -#define WBUF_LEN_MUL 2 -#endif - -static int srp_dev = -1; -static int srp_ibuf_size = 0; -static int srp_block_mode = SRP_INIT_BLOCK_MODE; - -static unsigned char *wbuf; -static int wbuf_size; -static int wbuf_pos; - -#ifdef _DUMP_TO_FILE_ -static FILE *fp_dump = NULL; -#endif - -#ifdef _USE_WBUF_ -static int WriteBuff_Init(void) -{ - if (wbuf == NULL) { - wbuf_size = srp_ibuf_size * WBUF_LEN_MUL; - wbuf_pos = 0; - wbuf = (unsigned char *)malloc(wbuf_size); - LOGD("%s: WriteBuffer %dbytes allocated", __func__, wbuf_size); - return 0; - } - - LOGE("%s: WriteBuffer already allocated", __func__); - return -1; -} - -static int WriteBuff_Deinit(void) -{ - if (wbuf != NULL) { - free(wbuf); - wbuf = NULL; - return 0; - } - - LOGE("%s: WriteBuffer is not ready", __func__); - return -1; -} - -static int WriteBuff_Write(unsigned char *buff, int size_byte) -{ - int write_byte; - - if ((wbuf_pos + size_byte) < wbuf_size) { - memcpy(&wbuf[wbuf_pos], buff, size_byte); - wbuf_pos += size_byte; - } else { - LOGE("%s: WriteBuffer is filled [%d], ignoring write [%d]", __func__, wbuf_pos, size_byte); - return -1; /* Insufficient buffer */ - } - - return wbuf_pos; -} - -static void WriteBuff_Consume(void) -{ - memcpy(wbuf, &wbuf[srp_ibuf_size], srp_ibuf_size * (WBUF_LEN_MUL - 1)); - wbuf_pos -= srp_ibuf_size; -} - -static void WriteBuff_Flush(void) -{ - wbuf_pos = 0; -} -#endif - -int SRP_Create(int block_mode) -{ - if (srp_dev == -1) { -#ifdef _USE_FW_FROM_DISK_ - SRP_Check_AltFirmware(); -#endif - - srp_block_mode = block_mode; - srp_dev = open(SRP_DEV_NAME, O_RDWR | - ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); - - return srp_dev; - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device alreay opened */ -} - -int SRP_Init(unsigned int ibuf_size) -{ - int ret; - - if (srp_dev != -1) { - srp_ibuf_size = ibuf_size; - ret = ioctl(srp_dev, SRP_INIT, srp_ibuf_size); /* Initialize IBUF size (4KB ~ 18KB) */ - -#ifdef _DUMP_TO_FILE_ - char outname[256]; - int cnt = 0; - - while (1) { - sprintf(outname, "/data/rp_dump_%04d.mp3", cnt++); - if (fp_dump = fopen(outname, "rb")) { /* file exist? */ - fclose(fp_dump); - } else { - break; - } - } - - LOGD("%s: Dump MP3 to %s", __func__, outname); - if (fp_dump = fopen(outname, "wb")) - LOGD("%s: Success to open %s", __func__, outname); - else - LOGD("%s: Fail to open %s", __func__, outname); -#endif - -#ifdef _USE_WBUF_ - if (ret != -1) - return WriteBuff_Init(); -#else - return ret; -#endif - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device is not created */ -} - -#ifdef _USE_WBUF_ -int SRP_Decode(void *buff, int size_byte) -{ - int ret; - int val; - int err_code = 0; - - if (srp_dev != -1) { - /* Check wbuf before writing buff */ - while (wbuf_pos >= srp_ibuf_size) { /* Write_Buffer filled? (IBUF Size)*/ - LOGD("%s: Write Buffer is full, Send data to RP", __func__); - - ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ - if (ret == -1) { /* Fail? */ - ioctl(srp_dev, SRP_ERROR_STATE, &val); - if (!val) { /* Write error? */ - LOGE("%s: IBUF write fail", __func__); - return -1; - } else { /* Write OK, but RP decode error? */ - err_code = val; - LOGE("%s: RP decode error [0x%05X]", __func__, err_code); - } - } -#ifdef _DUMP_TO_FILE_ - if (fp_dump) - fwrite(wbuf, srp_ibuf_size, 1, fp_dump); -#endif - WriteBuff_Consume(); - } - - ret = WriteBuff_Write((unsigned char *)buff, size_byte); - if (ret == -1) - return -1; /* Buffering error */ - - LOGD("%s: Write Buffer remain [%d]", __func__, wbuf_pos); - return err_code; /* Write Success */ - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device is not created */ -} - -int SRP_Send_EOS(void) -{ - int ret; - int val; - - if (srp_dev != -1) { - /* Check wbuf before writing buff */ - while (wbuf_pos) { /* Write_Buffer ramain?*/ - if (wbuf_pos < srp_ibuf_size) { - memset(wbuf + wbuf_pos, 0xFF, srp_ibuf_size - wbuf_pos); /* Fill dummy data */ - wbuf_pos = srp_ibuf_size; - } - - ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ - if (ret == -1) { /* Fail? */ - ret = ioctl(srp_dev, SRP_ERROR_STATE, &val); - if (!val) { /* Write error? */ - LOGE("%s: IBUF write fail", __func__); - return -1; - } else { /* RP decoe error? */ - LOGE("%s: RP decode error [0x%05X]", __func__, val); - return -1; - } - } else { /* Success? */ -#ifdef _DUMP_TO_FILE_ - if (fp_dump) - fwrite(wbuf, srp_ibuf_size, 1, fp_dump); -#endif - WriteBuff_Consume(); - } - } - - memset(wbuf, 0xFF, srp_ibuf_size); /* Fill dummy data */ - write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */ - - /* Wait until RP decoding over */ - return ioctl(srp_dev, SRP_WAIT_EOS); - } - - return -1; /* device is not created */ -} -#else /* Without WBUF */ -int SRP_Decode(void *buff, int size_byte) -{ - int ret; - int val; - int err_code = 0; - - if (srp_dev != -1) { - LOGD("%s: Send data to RP (%d bytes)", __func__, size_byte); - - ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ - if (ret == -1) { /* Fail? */ - ioctl(srp_dev, SRP_ERROR_STATE, &val); - if (!val) { /* Write error? */ - LOGE("%s: IBUF write fail", __func__); - return -1; - } else { /* Write OK, but RP decode error? */ - err_code = val; - LOGE("%s: RP decode error [0x%05X]", __func__, err_code); - } - } -#ifdef _DUMP_TO_FILE_ - if (fp_dump) - fwrite(buff, size_byte, 1, fp_dump); -#endif - - return err_code; /* Write Success */ - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device is not created */ -} - -int SRP_Send_EOS(void) -{ - /* Wait until RP decoding over */ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_SEND_EOS); - - return -1; /* device is not created */ -} - -int SRP_Resume_EOS(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_RESUME_EOS); - - return -1; /* device is not created */ -} -#endif - -int SRP_Pause(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_PAUSE); - - return -1; /* device is not created */ -} - -int SRP_Stop(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_STOP); - - return -1; /* device is not created */ -} - -int SRP_Flush(void) -{ - if (srp_dev != -1) { - if (ioctl(srp_dev, SRP_FLUSH) != -1) { -#ifdef _USE_WBUF_ - WriteBuff_Flush(); -#endif - return 0; - } - } - - return -1; /* device is not created */ -} - - -int SRP_SetParams(int id, unsigned long val) -{ - if (srp_dev != -1) - return 0; /* not yet */ - - return -1; /* device is not created */ -} - -int SRP_GetParams(int id, unsigned long *pval) -{ - if (srp_dev != -1) - return ioctl(srp_dev, id, pval); - - return -1; /* device is not created */ -} - -int SRP_Deinit(void) -{ - if (srp_dev != -1) { -#ifdef _DUMP_TO_FILE_ - if (fp_dump) - fclose(fp_dump); -#endif - -#ifdef _USE_WBUF_ - WriteBuff_Deinit(); -#endif - return ioctl(srp_dev, SRP_DEINIT); /* Deinialize */ - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device is not created */ -} - -int SRP_Terminate(void) -{ - int ret; - - if (srp_dev != -1) { - ret = close(srp_dev); - - if (ret == 0) { - srp_dev = -1; /* device closed */ - return 0; - } - } - - LOGE("%s: Device is not ready", __func__); - return -1; /* device is not created or close error*/ -} - -int SRP_IsOpen(void) -{ - if (srp_dev == -1) { - LOGD("%s: Device is not opened", __func__); - return 0; - } - - LOGD("%s: Device is opened", __func__); - return 1; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c deleted file mode 100644 index bdc2310..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srp_api_ctrl.h" -#include "srp_ioctl.h" - -#define LOG_TAG "libsrpapi" -#include - -/* Disable LOGD message */ -#ifdef LOGD -#undef LOGD -#endif -#define LOGD(...) - -static int srp_ctrl = -1; -static int srp_ctrl_cnt = 0; -static short pcm_buf[2048]; /* 4KBytes data, 1K frames (16bit stereo data) */ - -#ifdef _USE_FW_FROM_DISK_ -static char srp_alt_fw_name_pre[6][32] = { - "sdcard/rp_fw/rp_fw_code1", - "sdcard/rp_fw/rp_fw_code20", - "sdcard/rp_fw/rp_fw_code21", - "sdcard/rp_fw/rp_fw_code22", - "sdcard/rp_fw/rp_fw_code30", - "sdcard/rp_fw/rp_fw_code31", -}; -#endif - -static int SRP_Ctrl_Open(void) -{ - if (srp_ctrl_cnt == 0) { - srp_ctrl = open(SRP_CTRL_DEV_NAME, O_RDWR | O_NDELAY); - if (srp_ctrl < 0) { - LOGE("%s: Failed open device file %d", __func__, srp_ctrl); - return -1; - } - srp_ctrl_cnt++; - LOGV("%s: Device is opened[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt); - } - - return srp_ctrl; -} - -static int SRP_Ctrl_Close(void) -{ - int ret = 0; - - if (srp_ctrl_cnt == 1) { - ret = close(srp_ctrl); - if (ret < 0) { - LOGE("%s: Failed closen device file %d", __func__, srp_ctrl); - return -1; - } - srp_ctrl_cnt--; - LOGV("%s: Device is closed[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt); - srp_ctrl = -1; - } - - return ret; -} - -#ifdef _USE_FW_FROM_DISK_ -/* This will check & download alternate firmware */ -static int SRP_Check_AltFirmware(void) -{ - unsigned long *temp_buff; - FILE *fp = NULL; - - char alt_fw_name[128]; - unsigned long alt_fw_set; - unsigned long alt_fw_loaded = 0; - int alt_fw_text_ok,alt_fw_data_ok; - - if ((srp_ctrl = SRP_Ctrl_Open()) >= 0) { - ioctl(srp_ctrl, SRP_CTRL_ALTFW_STATE, &alt_fw_loaded); - - if (!alt_fw_loaded) { /* Not loaded yet? */ - LOGE("Try to download alternate RP firmware"); - temp_buff = (unsigned long *)malloc(256*1024); /* temp buffer */ - - for (alt_fw_set = 0; alt_fw_set < 6; alt_fw_set++) { - sprintf(alt_fw_name, "%s_text.bin", srp_alt_fw_name_pre[alt_fw_set]); - if (fp = fopen(alt_fw_name, "rb")) { - LOGE("RP Alt-Firmware Loading: %s", alt_fw_name); - fread(temp_buff, 64*1024, 1, fp); - close(fp); - alt_fw_text_ok = 1; - } else { - alt_fw_text_ok = 0; - } - - sprintf(alt_fw_name, "%s_data.bin", srp_alt_fw_name_pre[alt_fw_set]); - if (fp = fopen(alt_fw_name, "rb")) { - LOGE("RP Alt-Firmware Loading: %s", alt_fw_name); - fread(&temp_buff[64*1024/4], 96*1024, 1, fp); - close(fp); - alt_fw_data_ok = 1; - } else { - alt_fw_data_ok = 0; - } - - if (alt_fw_text_ok && alt_fw_data_ok) { - temp_buff[160*1024/4] = alt_fw_set; - ioctl(srp_ctrl, SRP_CTRL_ALTFW_LOAD, temp_buff); - } - } - free(temp_buff); - } - SRP_Ctrl_Close(); - } - - return 0; -} -#endif - -int SRP_Ctrl_Set_Effect(int effect) -{ - int ret; - unsigned long effect_mode = (unsigned long)effect; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_SET_EFFECT, effect_mode); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Enable_Effect(int on) -{ - int ret; - unsigned long effect_switch = on ? 1 : 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_EFFECT_ENABLE, effect_switch); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def) -{ - int ret; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_EFFECT_DEF, effect_def); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user) -{ - int ret; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_EFFECT_EQ_USR, eq_user); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Set_Pcm_Dump(int on) -{ - int ret; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, on); - - LOGV("dump_op: %d", on); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Get_Pcm_Dump_State(void) -{ - int ret; - int srp_dump_stat = 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &srp_dump_stat); - - LOGV("srp_dump_stat: %d", srp_dump_stat); - - SRP_Ctrl_Close(); - - return srp_dump_stat; -} - -int SRP_Ctrl_Set_Gain(float value) -{ - int ret; - unsigned long gain = 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - gain = (unsigned long)((1 << 24) * value); - ioctl(srp_ctrl, SRP_CTRL_SET_GAIN, gain); - - SRP_Ctrl_Close(); - - return 0; -} - -int SRP_Ctrl_Get_Running_Stat(void) -{ - int ret; - int srp_running_stat = 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &srp_running_stat); - - LOGV("srp_running_stat: %d", srp_running_stat); - - SRP_Ctrl_Close(); - - return srp_running_stat; -} - -int SRP_Ctrl_Get_Open_Stat(void) -{ - int ret; - int srp_open_stat = 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return -1; - } - - ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &srp_open_stat); - - LOGV("srp_open_stat: %d", srp_open_stat); - - SRP_Ctrl_Close(); - - return srp_open_stat; -} - -short *SRP_Ctrl_Get_Pcm(void) -{ - int ret; - int rp_is_running = 0; - int dump_is_on = 0; - int rp_is_opened = 0; - - ret = SRP_Ctrl_Open(); - if (ret < 0) { - LOGE("%s: SRP_Ctrl_Open error", __func__); - return NULL; - } - - ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &rp_is_running); - if (rp_is_running) { - ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &dump_is_on); - if (dump_is_on == 0) { - ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 1); - dump_is_on = 1; - } - - ioctl(srp_ctrl, SRP_CTRL_GET_PCM_1KFRAME, pcm_buf); - return pcm_buf; - } - - /* SRP is not running */ - if (srp_ctrl > 0) { - if (dump_is_on) { - ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &rp_is_opened); - if (rp_is_opened) - ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 0); - } - SRP_Ctrl_Close(); - } - - return NULL; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk deleted file mode 100644 index 4b113e7..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk +++ /dev/null @@ -1,9 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_AUDIO_PATH :=$(LOCAL_PATH) - -ifeq ($(BOARD_USE_ALP_AUDIO), true) - include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk -endif diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk deleted file mode 100644 index 7393f68..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - include/srp_api.h \ - include/srp_ioctl.h \ - include/srp_error.h - -LOCAL_SRC_FILES := \ - src/srp_api.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include - -LOCAL_MODULE := libsrpapi - -LOCAL_MODULE_TAGS := optional - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := - -LOCAL_SHARED_LIBRARIES := - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h deleted file mode 100644 index ad65b90..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __SRP_API_H__ -#define __SRP_API_H__ - -#include "srp_ioctl.h" -#include "srp_error.h" - -#define SRP_DEV_NAME "dev/srp" - -#define SRP_INIT_BLOCK_MODE 0 -#define SRP_INIT_NONBLOCK_MODE 1 - -#define SRP_PENDING_STATE_RUNNING 0 -#define SRP_PENDING_STATE_PENDING 1 - -struct srp_buf_info { - void *mmapped_addr; - void *addr; - unsigned int mmapped_size; - unsigned int size; - int num; -}; - -struct srp_dec_info { - unsigned int sample_rate; - unsigned int channels; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int SRP_Create(int block_mode); -int SRP_Init(); -int SRP_Decode(void *buff, int size_byte); -int SRP_Send_EOS(void); -int SRP_SetParams(int id, unsigned long val); -int SRP_GetParams(int id, unsigned long *pval); -int SRP_Deinit(void); -int SRP_Terminate(void); -int SRP_IsOpen(void); - -int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num); -int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num); -int SRP_Get_Dec_Info(struct srp_dec_info *dec_info); -int SRP_Get_PCM(void **addr, unsigned int *size); -int SRP_Flush(void); - -#ifdef __cplusplus -} -#endif - -#endif /*__SRP_API_H__ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h deleted file mode 100644 index 7f79452..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SRP_ERROR_H_ -#define _SRP_ERROR_H_ - -typedef enum { - SRP_RETURN_OK = 0, - - SRP_ERROR_OPEN_FAIL = -1000, - SRP_ERROR_ALREADY_OPEN = -1001, - SRP_ERROR_NOT_READY = -1002, - - SRP_ERROR_IBUF_OVERFLOW = -2000, - SRP_ERROR_IBUF_INFO = -2001, - - SRP_ERROR_OBUF_READ = -3000, - SRP_ERROR_OBUF_INFO = -3001, - SRP_ERROR_OBUF_MMAP = -3002, - - SRP_ERROR_INVALID_SETTING = -4000, - SRP_ERROR_GETINFO_FAIL = -4001 -} SRP_ERRORTYPE; - -#endif /* _SRP_ERROR_H_ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h deleted file mode 100644 index 21d55df..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __SRP_IOCTL_H__ -#define __SRP_IOCTL_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SRP_INIT (0x10000) -#define SRP_DEINIT (0x10001) -#define SRP_GET_MMAP_SIZE (0x10002) -#define SRP_FLUSH (0x20002) -#define SRP_SEND_EOS (0x20005) -#define SRP_GET_IBUF_INFO (0x20007) -#define SRP_GET_OBUF_INFO (0x20008) -#define SRP_STOP_EOS_STATE (0x30007) -#define SRP_GET_DEC_INFO (0x30008) - -#ifdef __cplusplus -} -#endif - -#endif /* __SRP_IOCTL_H__ */ - diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c deleted file mode 100644 index 56125fb..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srp_api.h" - -#define LOG_NDEBUG 1 -#define LOG_TAG "libsrpapi" -#include - -static struct srp_buf_info ibuf_info; -static struct srp_buf_info obuf_info; -static struct srp_buf_info pcm_info; - -static int srp_dev = -1; -static int srp_block_mode = SRP_INIT_BLOCK_MODE; - -int SRP_Create(int block_mode) -{ - if (srp_dev == -1) { - srp_block_mode = block_mode; - srp_dev = open(SRP_DEV_NAME, O_RDWR | - ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0)); - if (srp_dev > 0) - return srp_dev; - else - return SRP_ERROR_OPEN_FAIL; - } - - LOGE("%s: Device is already opened", __func__); - return SRP_ERROR_ALREADY_OPEN; -} - -int SRP_Init() -{ - int ret = SRP_RETURN_OK; - unsigned int mmapped_size = 0; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_INIT); - if (ret < 0) - return ret; - - /* mmap for OBUF */ - ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size); - if (ret < 0) { - LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__); - return SRP_ERROR_OBUF_MMAP; - } - obuf_info.mmapped_addr = mmap(0, mmapped_size, - PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0); - if (!obuf_info.mmapped_addr) { - LOGE("%s: mmap is failed", __func__); - return SRP_ERROR_OBUF_MMAP; - } - obuf_info.mmapped_size = mmapped_size; - - ret = SRP_RETURN_OK; - } else { - LOGE("%s: Device is not ready", __func__); - ret = SRP_ERROR_NOT_READY; /* device is not created */ - } - - return ret; -} - -int SRP_Decode(void *buff, int size_byte) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - if (size_byte > 0) { - LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte); - - ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */ - if (ret < 0) { - if (ret != SRP_ERROR_IBUF_OVERFLOW) - LOGE("SRP_Decode returned error code: %d", ret); - } - return ret; /* Write Success */ - } else { - return ret; - } - } - - LOGE("%s: Device is not ready", __func__); - return SRP_ERROR_NOT_READY; -} - -int SRP_Send_EOS(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_SEND_EOS); - - return SRP_ERROR_NOT_READY; -} - -int SRP_SetParams(int id, unsigned long val) -{ - if (srp_dev != -1) - return 0; /* not yet */ - - return SRP_ERROR_NOT_READY; -} - -int SRP_GetParams(int id, unsigned long *pval) -{ - if (srp_dev != -1) - return ioctl(srp_dev, id, pval); - - return SRP_ERROR_NOT_READY; -} - -int SRP_Flush(void) -{ - if (srp_dev != -1) - return ioctl(srp_dev, SRP_FLUSH); - - return SRP_ERROR_NOT_READY; -} - -int SRP_Get_PCM(void **addr, unsigned int *size) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - ret = read(srp_dev, &pcm_info, 0); - if (ret == -1) { - *size = 0; - LOGE("%s: PCM read fail", __func__); - return SRP_ERROR_OBUF_READ; - } - - *addr = pcm_info.addr; - *size = pcm_info.size; - } else { - return SRP_ERROR_NOT_READY; - } - - return ret; /* Read Success */ -} - -int SRP_Get_Dec_Info(struct srp_dec_info *dec_info) -{ - int ret; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info); - if (ret < 0) { - LOGE("%s: Failed to get dec info", __func__); - return SRP_ERROR_GETINFO_FAIL; - } - - LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate); - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info); - if (ret == -1) { - LOGE("%s: Failed to get Ibuf info", __func__); - return SRP_ERROR_IBUF_INFO; - } - - *addr = ibuf_info.addr; - *size = ibuf_info.size; - *num = ibuf_info.num; - - if (*num == 0) { - LOGE("%s: IBUF num is 0", __func__); - return SRP_ERROR_INVALID_SETTING; - } - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num) -{ - int ret = SRP_RETURN_OK; - - if (srp_dev != -1) { - if (obuf_info.addr == NULL) { - ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info); - if (ret < 0) { - LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__); - return SRP_ERROR_OBUF_INFO; - } - } - - *addr = obuf_info.addr; - *size = obuf_info.size; - *num = obuf_info.num; - - if (*num == 0) { - LOGE("%s: OBUF num is 0", __func__); - return SRP_ERROR_INVALID_SETTING; - } - - ret = SRP_RETURN_OK; - } else { - ret = SRP_ERROR_NOT_READY; - } - - return ret; -} - -int SRP_Deinit(void) -{ - if (srp_dev != -1) { - munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size); - return ioctl(srp_dev, SRP_DEINIT); - } - - return SRP_ERROR_NOT_READY; -} - -int SRP_Terminate(void) -{ - int ret; - - if (srp_dev != -1) { - ret = close(srp_dev); - - if (ret == 0) { - srp_dev = -1; /* device closed */ - return SRP_RETURN_OK; - } - } - - return SRP_ERROR_NOT_READY; -} - -int SRP_IsOpen(void) -{ - if (srp_dev == -1) { - LOGV("%s: Device is not opened", __func__); - return 0; - } - - LOGV("%s: Device is opened", __func__); - return 1; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/video/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/Android.mk deleted file mode 100644 index 3bc3577..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/Android.mk +++ /dev/null @@ -1,11 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -include $(LOCAL_PATH)/exynos4/Android.mk -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -include $(LOCAL_PATH)/exynos5/Android.mk -endif diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk deleted file mode 100644 index 1a8c419..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk +++ /dev/null @@ -1,11 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_VIDEO_PATH :=$(LOCAL_PATH) - -ifeq ($(BOARD_USE_V4L2), true) -include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk -else -include $(LOCAL_VIDEO_PATH)/mfc/Android.mk -endif diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk deleted file mode 100644 index b23f603..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk +++ /dev/null @@ -1,38 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - include/mfc_errno.h \ - include/mfc_interface.h \ - include/SsbSipMfcApi.h - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - dec/src/SsbSipMfcDecAPI.c \ - enc/src/SsbSipMfcEncAPI.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include/ - -LOCAL_MODULE := libsecmfcapi - -LOCAL_PRELINK_MODULE := false - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS := -DCONFIG_MFC_FPS -#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_LOG -endif - -ifeq ($(BOARD_USE_S3D_SUPPORT), true) -LOCAL_CFLAGS += -DS3D_SUPPORT -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := liblog - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c deleted file mode 100644 index 5cc7c88..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" - -#include -/*#define LOG_NDEBUG 0*/ -#undef LOG_TAG -#define LOG_TAG "MFC_DEC_APP" - -#ifdef CONFIG_MFC_FPS -#include -#endif - -#define _MFCLIB_MAGIC_NUMBER 0x92241000 - -#define USR_DATA_START_CODE (0x000001B2) -#define VOP_START_CODE (0x000001B6) -#define MP4_START_CODE (0x000001) - -#ifdef CONFIG_MFC_FPS -unsigned int framecount, over30ms; -struct timeval mDec1, mDec2, mAvg; -#endif - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; - -static void getAByte(char *buff, int *code) -{ - int byte; - - *code = (*code << 8); - byte = (int)*buff; - byte &= 0xFF; - *code |= byte; -} - -static int isPBPacked(_MFCLIB *pCtx, int Frameleng) -{ - char *strmBuffer = NULL; - int startCode = 0xFFFFFFFF; - int leng_idx = 1; - - strmBuffer = (char*)pCtx->virStrmBuf; - - while (1) { - while (startCode != USR_DATA_START_CODE) { - if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { - LOGI("isPBPacked] VOP START Found !!.....return"); - LOGW("isPBPacked] Non Packed PB"); - return 0; - } - getAByte(strmBuffer, &startCode); - LOGV(">> StartCode = 0x%08x <<\n", startCode); - strmBuffer++; - leng_idx++; - } - LOGI("isPBPacked] User Data Found !!"); - - do { - if (*strmBuffer == 'p') { - /*LOGI(">> peter strmBuffer = 0x%08x <<\n", *strmBuffer);*/ - LOGW("isPBPacked] Packed PB\n"); - return 1; - } - getAByte(strmBuffer, &startCode); - strmBuffer++; leng_idx++; - } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); - - if (leng_idx > Frameleng) - break; - } - - LOGW("isPBPacked] Non Packed PB"); - - return 0; -} - -void SsbSipMfcDecSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcDecOpen(void) -{ - int hMFCOpen; - unsigned int mapped_addr; - _MFCLIB *pCTX = NULL; - int mapped_size; - struct mfc_common_args CommonArg; - - LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); -#ifdef CONFIG_MFC_FPS - framecount = 0; - over30ms = 0; - mAvg.tv_sec = 0; - mAvg.tv_usec = 0; -#endif - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("SsbSipMfcDecOpen] malloc failed.\n"); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("SsbSipMfcDecOpen] MFC device node not exists"); - free(pCTX); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); - if (hMFCOpen < 0) { - LOGE("SsbSipMfcDecOpen] MFC Open failure"); - free(pCTX); - return NULL; - } - - mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); - if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcDecOpen] IOCTL_MFC_GET_MMAP_SIZE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); - if (!mapped_addr) { - LOGE("SsbSipMfcDecOpen] FIMV5.x driver address mapping failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - pCTX->magic = _MFCLIB_MAGIC_NUMBER; - pCTX->hMFC = hMFCOpen; - pCTX->mapped_addr = mapped_addr; - pCTX->mapped_size = mapped_size; - pCTX->inter_buff_status = MFC_USE_NONE; - - return (void *)pCTX; -} - -void *SsbSipMfcDecOpenExt(void *value) -{ - int hMFCOpen; - unsigned int mapped_addr; - _MFCLIB *pCTX = NULL; - int mapped_size; - int err; - struct mfc_common_args CommonArg; - - LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("SsbSipMfcDecOpenExt] malloc failed.\n"); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("SsbSipMfcDecOpen] MFC device node not exists"); - free(pCTX); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); - if (hMFCOpen < 0) { - LOGE("SsbSipMfcDecOpenExt] MFC Open failure"); - free(pCTX); - return NULL; - } - - CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value; - - err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg); - if ((err < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_SET_BUF_CACHE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); - if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); - if (!mapped_addr) { - LOGE("SsbSipMfcDecOpenExt] FIMV5.x driver address mapping failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - pCTX->magic = _MFCLIB_MAGIC_NUMBER; - pCTX->hMFC = hMFCOpen; - pCTX->mapped_addr = mapped_addr; - pCTX->mapped_size = mapped_size; - pCTX->inter_buff_status = MFC_USE_NONE; - - return (void *)pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit (void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) -{ - int r; - int packedPB = 0; - struct mfc_common_args DecArg; - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecInit] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - memset(&DecArg, 0x00, sizeof(DecArg)); - - if ((codec_type != MPEG4_DEC) && - (codec_type != H264_DEC) && - (codec_type != H263_DEC) && - (codec_type != MPEG1_DEC) && - (codec_type != MPEG2_DEC) && - (codec_type != FIMV1_DEC) && - (codec_type != FIMV2_DEC) && - (codec_type != FIMV3_DEC) && - (codec_type != FIMV4_DEC) && - (codec_type != XVID_DEC) && - (codec_type != VC1RCV_DEC) && - (codec_type != VC1_DEC)) { - LOGE("SsbSipMfcDecInit] Undefined codec type"); - return MFC_RET_INVALID_PARAM; - } - pCTX->codecType = codec_type; - - if ((pCTX->codecType == MPEG4_DEC) || - (pCTX->codecType == XVID_DEC) || - (pCTX->codecType == FIMV1_DEC) || - (pCTX->codecType == FIMV2_DEC) || - (pCTX->codecType == FIMV3_DEC) || - (pCTX->codecType == FIMV4_DEC)) - packedPB = isPBPacked(pCTX, Frameleng); - - /* init args */ - DecArg.args.dec_init.in_codec_type = pCTX->codecType; - DecArg.args.dec_init.in_strm_size = Frameleng; - DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf; - - DecArg.args.dec_init.in_numextradpb = pCTX->dec_numextradpb; - DecArg.args.dec_init.in_slice= pCTX->dec_slice; - DecArg.args.dec_init.in_crc = pCTX->dec_crc; - DecArg.args.dec_init.in_pixelcache = pCTX->dec_pixelcache; - - DecArg.args.dec_init.in_packed_PB = packedPB; - - /* mem alloc args */ - DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr; - - /* get pyhs addr args */ - /* no needs */ - - /* sequence start args */ - /* no needs */ - - r = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg); - if (DecArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcDecInit] IOCTL_MFC_DEC_INIT failed"); - return MFC_RET_DEC_INIT_FAIL; - } - - pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_frm_width; - pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_frm_height; - pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width; - pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height; - - pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset; - pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset; - pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset; - pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset; - - /* - pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma; - pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma; - - pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma; - pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma; - pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma; - pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma; - */ - - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) -{ - int ret; - int Yoffset; - int Coffset; - _MFCLIB *pCTX; - struct mfc_common_args DecArg; - -#ifdef CONFIG_MFC_FPS - long int diffTime, avgTime; -#endif - if (openHandle == NULL) { - LOGE("SsbSipMfcDecExe] openHandle is NULL\n"); - return MFC_RET_INVALID_PARAM; - } - - if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("SsbSipMfcDecExe] lengthBufFill is invalid. (lengthBufFill=%d)", lengthBufFill); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - memset(&DecArg, 0x00, sizeof(DecArg)); - - DecArg.args.dec_exe.in_codec_type = pCTX->codecType; - DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf; - DecArg.args.dec_exe.in_strm_size = lengthBufFill; - DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma; - DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma; - DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma; - DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma; - DecArg.args.dec_exe.in_frametag = pCTX->inframetag; - DecArg.args.dec_exe.in_immediately_disp = pCTX->immediatelydisp; - -#ifdef CONFIG_MFC_FPS - gettimeofday(&mDec1, NULL); - -#ifdef CONFIG_MFC_PERF_LOG - if (framecount != 0) { - if (mDec2.tv_sec == mDec1.tv_sec) - LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (mDec1.tv_usec - mDec2.tv_usec)); - else - LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (1000000 + (mDec1.tv_usec - mDec2.tv_usec))); - } -#endif -#endif - - ret = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg); - - if (DecArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcDecExe] IOCTL_MFC_DEC_EXE failed(ret : %d)", DecArg.ret_code); - return MFC_RET_DEC_EXE_ERR; - } - -#ifdef CONFIG_MFC_FPS - gettimeofday(&mDec2, NULL); - framecount++; - - if (mDec1.tv_sec == mDec2.tv_sec) { - if (mDec2.tv_usec - mDec1.tv_usec > 30000) - over30ms++; -#ifdef CONFIG_MFC_PERF_LOG - LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", ((mDec2.tv_usec - mDec1.tv_usec))); -#endif - } else { - if (1000000 + mDec2.tv_usec - mDec1.tv_usec > 30000) - over30ms++; -#ifdef CONFIG_MFC_PERF_LOG - LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", (1000000 + (mDec2.tv_usec - mDec1.tv_usec))); -#endif - } - - diffTime = ((mDec2.tv_sec * 1000000) + mDec2.tv_usec) - ((mDec1.tv_sec * 1000000) + mDec1.tv_usec); - avgTime = (mAvg.tv_sec * 1000000) + mAvg.tv_usec; - avgTime = ((framecount - 1) * avgTime + diffTime) / framecount; - - mAvg.tv_sec = avgTime / 1000000; - mAvg.tv_usec = avgTime % 1000000; -#endif - - /* FIXME: dynamic resolution change */ - if (DecArg.args.dec_exe.out_display_status == 4) { - LOGI("SsbSipMfcDecExe] Resolution is chagned"); - /* - pCTX->virFrmBuf.chroma = DecArg.args.dec_exe.out_u_addr.chroma; - pCTX->virFrmBuf.luma = DecArg.args.dec_exe.out_u_addr.luma; - pCTX->phyFrmBuf.chroma = DecArg.args.dec_exe.out_p_addr.chroma; - pCTX->phyFrmBuf.luma = DecArg.args.dec_exe.out_p_addr.luma; - pCTX->sizeFrmBuf.chroma = DecArg.args.dec_exe.out_frame_buf_size.chroma; - pCTX->sizeFrmBuf.luma = DecArg.args.dec_exe.out_frame_buf_size.luma; - */ - pCTX->decOutInfo.img_width = DecArg.args.dec_exe.out_img_width; - pCTX->decOutInfo.img_height = DecArg.args.dec_exe.out_img_height; - pCTX->decOutInfo.buf_width = DecArg.args.dec_exe.out_buf_width; - pCTX->decOutInfo.buf_height = DecArg.args.dec_exe.out_buf_height; - } - - Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma; - Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma; - - pCTX->decOutInfo.YPhyAddr = (void*)(DecArg.args.dec_exe.out_display_Y_addr); - pCTX->decOutInfo.CPhyAddr = (void*)(DecArg.args.dec_exe.out_display_C_addr); - - pCTX->decOutInfo.YVirAddr = (void*)(pCTX->virFrmBuf.luma + Yoffset); - pCTX->decOutInfo.CVirAddr = (void*)(pCTX->virFrmBuf.chroma + Coffset); - - /* for new driver */ - pCTX->decOutInfo.YVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_y_offset); - pCTX->decOutInfo.CVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_c_offset); - - pCTX->displayStatus = DecArg.args.dec_exe.out_display_status; - - pCTX->decOutInfo.disp_pic_frame_type = DecArg.args.dec_exe.out_disp_pic_frame_type; - - /* clear immediately display flag */ - pCTX->immediatelydisp = 0; - pCTX->outframetagtop = DecArg.args.dec_exe.out_frametag_top; - pCTX->outframetagbottom = DecArg.args.dec_exe.out_frametag_bottom; - pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_pic_time_top; - pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_pic_time_bottom; - pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consumed_byte; - - pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset; - pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset; - pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset; - pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) -{ - int ret; - _MFCLIB *pCTX; - struct mfc_common_args free_arg; - -#ifdef CONFIG_MFC_FPS - LOGI(">>> Statistics in MFC API:"); - LOGI(">>> Total number of IOCTL_MFC_DEC_EXE = %d", framecount); - LOGI(">>> Number of IOCTL_MFC_DEC_EXE taking more than 30ms = %d", over30ms); - LOGI(">>> Avg IOCTL_MFC_DEC_EXE time = %dsec %.2fmsec", (int)mAvg.tv_sec, (float)(mAvg.tv_usec / 1000.0)); -#endif - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecClose] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - /* FIXME: free buffer? */ -#if 0 - if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { - free_arg.args.mem_free.key = pCTX->virFrmBuf.luma; - ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - free_arg.args.mem_free.key = pCTX->virFrmBuf.chroma; - ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - } -#endif - - if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { - free_arg.args.mem_free.key = pCTX->virStrmBuf; - ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - } - - pCTX->inter_buff_status = MFC_USE_NONE; - - munmap((void *)pCTX->mapped_addr, pCTX->mapped_size); - close(pCTX->hMFC); - free(pCTX); - - return MFC_RET_OK; -} - - -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args user_addr_arg, phys_addr_arg; - - if (inputBufferSize < 0) { - LOGE("SsbSipMfcDecGetInBuf] inputBufferSize = %d is invalid", inputBufferSize); - return NULL; - } - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecGetInBuf] openHandle is NULL\n"); - return NULL; - } - - pCTX = (_MFCLIB *) openHandle; - - /*user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; */ - user_addr_arg.args.mem_alloc.type = DECODER; - user_addr_arg.args.mem_alloc.buff_size = inputBufferSize; - user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_IN_BUF failed"); - return NULL; - } - - phys_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &phys_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_PHYS_ADDR failed"); - return NULL; - } - - /* - pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.offset; - */ - pCTX->virStrmBuf = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset; - pCTX->phyStrmBuf = phys_addr_arg.args.real_addr.addr; - - pCTX->sizeStrmBuf = inputBufferSize; - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - *phyInBuf = (void *)pCTX->phyStrmBuf; - - return (void *)pCTX->virStrmBuf; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecSetInBuf] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - pCTX->phyStrmBuf = (int)phyInBuf; - pCTX->virStrmBuf = (int)virInBuf; - pCTX->sizeStrmBuf = size; - return MFC_RET_OK; -} - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecGetOutBuf] openHandle is NULL"); - return MFC_GETOUTBUF_DISPLAY_END; - } - - pCTX = (_MFCLIB *) openHandle; - - output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; - output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; - - output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; - output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; - - output_info->img_width = pCTX->decOutInfo.img_width; - output_info->img_height= pCTX->decOutInfo.img_height; - - output_info->buf_width = pCTX->decOutInfo.buf_width; - output_info->buf_height= pCTX->decOutInfo.buf_height; - - output_info->timestamp_top = pCTX->decOutInfo.timestamp_top; - output_info->timestamp_bottom = pCTX->decOutInfo.timestamp_bottom; - output_info->consumedByte = pCTX->decOutInfo.consumedByte; - - output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - - output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; - - if (pCTX->displayStatus == 3) - return MFC_GETOUTBUF_DISPLAY_END; - else if (pCTX->displayStatus == 1) - return MFC_GETOUTBUF_DISPLAY_DECODING; - else if (pCTX->displayStatus == 2) - return MFC_GETOUTBUF_DISPLAY_ONLY; - else if (pCTX->displayStatus == 0) - return MFC_GETOUTBUF_DECODING_ONLY; - else if (pCTX->displayStatus == 4) - return MFC_GETOUTBUF_CHANGE_RESOL; - else - return MFC_GETOUTBUF_DISPLAY_END; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args DecArg; - struct mfc_dec_fimv1_info *fimv1_res; - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecSetConfig] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("SsbSipMfcDecSetConfig] value is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - memset(&DecArg, 0x00, sizeof(DecArg)); -#ifdef S3D_SUPPORT - DecArg.args.config.type = conf_type; -#else - DecArg.args.set_config.in_config_param = conf_type; -#endif - switch (conf_type) { - case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: - pCTX->dec_numextradpb = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_SLICE_ENABLE: - pCTX->dec_slice = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_CRC_ENABLE: - pCTX->dec_crc = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_PIXEL_CACHE: - pCTX->dec_pixelcache = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_FRAME_TAG: /* be set before calling SsbSipMfcDecExe */ - pCTX->inframetag = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY: /* be set before calling SsbSipMfcDecExe */ - pCTX->immediatelydisp = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: - fimv1_res = (struct mfc_dec_fimv1_info *)value; - LOGI("fimv1->width = %d\n", fimv1_res->width); - LOGI("fimv1->height = %d\n", fimv1_res->height); -#ifdef S3D_SUPPORT - DecArg.args.config.args.basic.values[0] = (int)(fimv1_res->width); - DecArg.args.config.args.basic.values[1] = (int)(fimv1_res->height); -#else - DecArg.args.set_config.in_config_value[0] = (int)(fimv1_res->width); - DecArg.args.set_config.in_config_value[1] = (int)(fimv1_res->height); -#endif - break; - case MFC_DEC_SETCONF_IS_LAST_FRAME: - case MFC_DEC_SETCONF_DPB_FLUSH: -#ifdef S3D_SUPPORT - case MFC_DEC_SETCONF_SEI_PARSE: - default: - DecArg.args.config.args.basic.values[0] = *((int *) value); - DecArg.args.config.args.basic.values[1] = 0; -#else - default: - DecArg.args.set_config.in_config_value[0] = *((unsigned int *) value); - DecArg.args.set_config.in_config_value[1] = 0; -#endif - break; - } - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg); - if (DecArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcDecSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); - return MFC_RET_DEC_SET_CONF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args DecArg; - - /* - s3c_mfc_common_args phys_addr_arg; - SSBSIP_MFC_BUFFER_ADDR *buf_addr; - */ - - SSBSIP_MFC_IMG_RESOLUTION *img_resolution; - SSBSIP_MFC_CRC_DATA *crc_data; - SSBSIP_MFC_CROP_INFORMATION *crop_information; -#ifdef S3D_SUPPORT - SSBSIP_MFC_FRAME_PACKING *frame_packing; -#endif - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecGetConfig] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("SsbSipMfcDecGetConfig] value is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - switch (conf_type) { -#if 0 - case MFC_DEC_GETCONF_PHYS_ADDR: - buf_addr = (SSBSIP_MFC_BUFFER_ADDR *)value; - phys_addr_arg.args.get_phys_addr.u_addr = buf_addr->u_addr; - r = ioctl(pCTX->hMFC, IOCTL_MFC_GET_PHYS_ADDR, &phys_addr_arg); - if (r < 0) { - LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_PHYS_ADDR failed"); - return MFC_API_FAIL; - } - buf_addr->p_addr = phys_addr_arg.args.get_phys_addr.p_addr; - break; -#endif - case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: - img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; - img_resolution->width = pCTX->decOutInfo.img_width; - img_resolution->height = pCTX->decOutInfo.img_height; - img_resolution->buf_width = pCTX->decOutInfo.buf_width; - img_resolution->buf_height = pCTX->decOutInfo.buf_height; - break; - case MFC_DEC_GETCONF_FRAME_TAG: - *((unsigned int *)value) = pCTX->outframetagtop; - break; - case MFC_DEC_GETCONF_CROP_INFO: - crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; - crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - break; - case MFC_DEC_GETCONF_CRC_DATA: -#ifdef S3D_SUPPORT - case MFC_DEC_GETCONF_FRAME_PACKING: - memset(&DecArg, 0x00, sizeof(DecArg)); - DecArg.args.config.type = conf_type; - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); - if (DecArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); - return MFC_RET_DEC_GET_CONF_FAIL; - } - - if (conf_type == MFC_DEC_GETCONF_CRC_DATA) { - crc_data = (SSBSIP_MFC_CRC_DATA *)value; - - crc_data->luma0 = DecArg.args.config.args.basic.values[0]; - crc_data->chroma0 = DecArg.args.config.args.basic.values[1]; - } else { - frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value; - memcpy(frame_packing, &DecArg.args.config.args.frame_packing, - sizeof(SSBSIP_MFC_FRAME_PACKING)); - } -#else - crc_data = (SSBSIP_MFC_CRC_DATA *)value; - - memset(&DecArg, 0x00, sizeof(DecArg)); - DecArg.args.get_config.in_config_param = conf_type; - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); - if (DecArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type); - return MFC_RET_DEC_GET_CONF_FAIL; - } - crc_data->luma0 = DecArg.args.get_config.out_config_value[0]; - crc_data->chroma0 = DecArg.args.get_config.out_config_value[1]; -#endif - break; - default: - LOGE("SsbSipMfcDecGetConfig] No such conf_type is supported"); - return MFC_RET_DEC_GET_CONF_FAIL; - } - - return MFC_RET_OK; -} - -void *SsbSipMfcDecAllocInputBuffer(void *openHandle, void **phyInBuf, int inputBufferSize) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args user_addr_arg, phys_addr_arg; - - if (inputBufferSize < 0) { - LOGE("SsbSipMfcDecAllocInputBuffer] inputBufferSize = %d is invalid\n", inputBufferSize); - return NULL; - } - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecAllocInputBuffer] openHandle is NULL\n"); - return NULL; - } - - pCTX = (_MFCLIB *)openHandle; - - user_addr_arg.args.mem_alloc.type = DECODER; - user_addr_arg.args.mem_alloc.buff_size = inputBufferSize; - user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcDecAllocInputBuffer] IOCTL_MFC_GET_IN_BUF failed"); - return NULL; - } - - phys_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &phys_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_PHYS_ADDR failed"); - return NULL; - } - - pCTX->virStrmBuf = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset; - pCTX->phyStrmBuf = phys_addr_arg.args.real_addr.addr; - pCTX->sizeStrmBuf = inputBufferSize; - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - *phyInBuf = (void *)pCTX->phyStrmBuf; - - return (void *)pCTX->virStrmBuf; -} - -void SsbSipMfcDecFreeInputBuffer(void *openHandle, void *phyInBuf) -{ - int ret; - _MFCLIB *pCTX; - struct mfc_common_args free_arg; - - if (openHandle == NULL) { - LOGE("SsbSipMfcDecFreeInputBuffer] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - - if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { - free_arg.args.mem_free.key = pCTX->virStrmBuf; - ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - } - pCTX->inter_buff_status = MFC_USE_NONE; - return MFC_RET_OK; -} - -/* CRESPO */ -#if 1 -int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) -{ - int pixel_x_m1, pixel_y_m1; - int roundup_x, roundup_y; - int linear_addr0, linear_addr1, bank_addr ; - int x_addr; - int trans_addr; - - pixel_x_m1 = x_size -1; - pixel_y_m1 = y_size -1; - - roundup_x = ((pixel_x_m1 >> 7) + 1); - roundup_y = ((pixel_x_m1 >> 6) + 1); - - x_addr = x_pos >> 2; - - if ((y_size <= y_pos+32) && ( y_pos < y_size) && - (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) { - linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); - - if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) - bank_addr = ((x_addr >> 4) & 0x1); - else - bank_addr = 0x2 | ((x_addr >> 4) & 0x1); - } else { - linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); - - if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) - bank_addr = ((x_addr >> 4) & 0x1); - else - bank_addr = 0x2 | ((x_addr >> 4) & 0x1); - } - - linear_addr0 = linear_addr0 << 2; - trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; - - return trans_addr; -} - -void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) -{ - int trans_addr; - unsigned int i, j, k, index; - unsigned char data8[4]; - unsigned int max_index = x_size * y_size; - - for (i = 0; i < y_size; i = i + 16) { - for (j = 0; j < x_size; j = j + 16) { - trans_addr = tile_4x2_read(x_size, y_size, j, i); - for (k = 0; k < 16; k++) { - /* limit check - prohibit segmentation fault */ - index = (i * x_size) + (x_size * k) + j; - /* remove equal condition to solve thumbnail bug */ - if (index + 16 > max_index) { - continue; - } - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; - - p_linear_addr[index] = data8[0]; - p_linear_addr[index + 1] = data8[1]; - p_linear_addr[index + 2] = data8[2]; - p_linear_addr[index + 3] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; - - p_linear_addr[index + 4] = data8[0]; - p_linear_addr[index + 5] = data8[1]; - p_linear_addr[index + 6] = data8[2]; - p_linear_addr[index + 7] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; - - p_linear_addr[index + 8] = data8[0]; - p_linear_addr[index + 9] = data8[1]; - p_linear_addr[index + 10] = data8[2]; - p_linear_addr[index + 11] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; - - p_linear_addr[index + 12] = data8[0]; - p_linear_addr[index + 13] = data8[1]; - p_linear_addr[index + 14] = data8[2]; - p_linear_addr[index + 15] = data8[3]; - } - } - } -} - -void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) -{ - int trans_addr; - unsigned int i, j, k, index; - unsigned char data8[4]; - unsigned int half_y_size = y_size / 2; - unsigned int max_index = x_size * half_y_size; - unsigned char *pUVAddr[2]; - - pUVAddr[0] = p_linear_addr; - pUVAddr[1] = p_linear_addr + ((x_size * half_y_size) / 2); - - for (i = 0; i < half_y_size; i = i + 16) { - for (j = 0; j < x_size; j = j + 16) { - trans_addr = tile_4x2_read(x_size, half_y_size, j, i); - for (k = 0; k < 16; k++) { - /* limit check - prohibit segmentation fault */ - index = (i * x_size) + (x_size * k) + j; - /* remove equal condition to solve thumbnail bug */ - if (index + 16 > max_index) { - continue; - } - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; - - pUVAddr[index%2][index/2] = data8[0]; - pUVAddr[(index+1)%2][(index+1)/2] = data8[1]; - pUVAddr[(index+2)%2][(index+2)/2] = data8[2]; - pUVAddr[(index+3)%2][(index+3)/2] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; - - pUVAddr[(index+4)%2][(index+4)/2] = data8[0]; - pUVAddr[(index+5)%2][(index+5)/2] = data8[1]; - pUVAddr[(index+6)%2][(index+6)/2] = data8[2]; - pUVAddr[(index+7)%2][(index+7)/2] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; - - pUVAddr[(index+8)%2][(index+8)/2] = data8[0]; - pUVAddr[(index+9)%2][(index+9)/2] = data8[1]; - pUVAddr[(index+10)%2][(index+10)/2] = data8[2]; - pUVAddr[(index+11)%2][(index+11)/2] = data8[3]; - - data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; - data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; - data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; - data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; - - pUVAddr[(index+12)%2][(index+12)/2] = data8[0]; - pUVAddr[(index+13)%2][(index+13)/2] = data8[1]; - pUVAddr[(index+14)%2][(index+14)/2] = data8[2]; - pUVAddr[(index+15)%2][(index+15)/2] = data8[3]; - } - } - } -} -#else -int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) -{ - int pixel_x_m1, pixel_y_m1; - int roundup_x, roundup_y; - int linear_addr0, linear_addr1, bank_addr; - int x_addr; - int trans_addr; - - pixel_x_m1 = x_size -1; - pixel_y_m1 = y_size -1; - - roundup_x = ((pixel_x_m1 >> 7) + 1); - roundup_y = ((pixel_x_m1 >> 6) + 1); - - x_addr = x_pos >> 2; - - if ((y_size <= y_pos+32) && - ( y_pos < y_size) && - (((pixel_y_m1 >> 5) & 0x1) == 0) && - (((y_pos >> 5) & 0x1) == 0)) { - linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); - - if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) - bank_addr = ((x_addr >> 4) & 0x1); - else - bank_addr = 0x2 | ((x_addr >> 4) & 0x1); - } else { - linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); - linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); - - if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) - bank_addr = ((x_addr >> 4) & 0x1); - else - bank_addr = 0x2 | ((x_addr >> 4) & 0x1); - } - - linear_addr0 = linear_addr0 << 2; - trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; - - return trans_addr; -} - - -void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) -{ - int trans_addr; - unsigned int i, j, k, nn, mm; - unsigned int ix,iy, nx, ny; - - nx = x_size % 16; - ny = y_size % 16; - - if (nx != 0) - ix = 16; - else - ix = 1; - - if (ny != 0) - iy = 16; - else - iy = 1; - - for (i = 0; i < y_size - iy; i = i + 16) { - for (j = 0; j < x_size -ix; j = j + 16) { - trans_addr = tile_4x2_read(x_size, y_size, j, i); - - k = 0; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 1; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 2; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 3; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 4; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 5; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 6; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 7; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 8; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 9; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 10; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 11; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 12; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 13; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 14; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - - k = 15; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j; - memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16); - } - } -} -#endif diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c deleted file mode 100644 index 797baad..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" - -#include -/* #define LOG_NDEBUG 0 */ -#undef LOG_TAG -#define LOG_TAG "MFC_ENC_APP" - -#define _MFCLIB_MAGIC_NUMBER 0x92241001 - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; - -void SsbSipMfcEncSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcEncOpen(void) -{ - int hMFCOpen; - _MFCLIB *pCTX = NULL; - unsigned int mapped_addr; - int mapped_size; - struct mfc_common_args CommonArg; - - LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); - -#if 0 - if ((codecType != MPEG4_ENC) && - (codecType != H264_ENC) && - (codecType != H263_ENC)) { - LOGE("SsbSipMfcEncOpen] Undefined codec type"); - return NULL; - } -#endif - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("SsbSipMfcEncOpen] MFC device node not exists"); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); - if (hMFCOpen < 0) { - LOGE("SsbSipMfcEncOpen] MFC Open failure"); - return NULL; - } - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("SsbSipMfcEncOpen] malloc failed."); - close(hMFCOpen); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); - if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcEncOpen] IOCTL_MFC_GET_MMAP_SIZE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); - if (!mapped_addr) { - LOGE("SsbSipMfcEncOpen] FIMV5.x driver address mapping failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - pCTX->magic = _MFCLIB_MAGIC_NUMBER; - pCTX->hMFC = hMFCOpen; - pCTX->mapped_addr = mapped_addr; - pCTX->mapped_size = mapped_size; - pCTX->inter_buff_status = MFC_USE_NONE; - - return (void *) pCTX; -} - - -void *SsbSipMfcEncOpenExt(void *value) -{ - int hMFCOpen; - _MFCLIB *pCTX = NULL; - unsigned int mapped_addr; - int mapped_size; - int err; - struct mfc_common_args CommonArg; - - LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); - -#if 0 - if ((codecType != MPEG4_ENC) && - (codecType != H264_ENC) && - (codecType != H263_ENC)) { - LOGE("SsbSipMfcEncOpen] Undefined codec type"); - return NULL; - } -#endif - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("SsbSipMfcEncOpenExt] MFC device node not exists"); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY); - if (hMFCOpen < 0) { - LOGE("SsbSipMfcEncOpenExt] MFC Open failure"); - return NULL; - } - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("SsbSipMfcEncOpenExt] malloc failed."); - close(hMFCOpen); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value; - - err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg); - if ((err < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_SET_BUF_CACHE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg); - if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) { - LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); - if (!mapped_addr) { - LOGE("SsbSipMfcEncOpenExt] FIMV5.x driver address mapping failed"); - free(pCTX); - close(hMFCOpen); - return NULL; - } - - pCTX->magic = _MFCLIB_MAGIC_NUMBER; - pCTX->hMFC = hMFCOpen; - pCTX->mapped_addr = mapped_addr; - pCTX->mapped_size = mapped_size; - pCTX->inter_buff_status = MFC_USE_NONE; - - return (void *) pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) -{ - int ret_code; - - _MFCLIB *pCTX; - struct mfc_common_args EncArg; - SSBSIP_MFC_ENC_H264_PARAM *h264_arg; - SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; - SSBSIP_MFC_ENC_H263_PARAM *h263_arg; - - pCTX = (_MFCLIB *) openHandle; - memset(&EncArg, 0, sizeof(struct mfc_common_args)); - - pCTX->encode_cnt = 0; - - mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; - if (mpeg4_arg->codecType == MPEG4_ENC) { - pCTX->codecType= MPEG4_ENC; - } else { - h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; - if (h263_arg->codecType == H263_ENC) { - pCTX->codecType = H263_ENC; - } else { - h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; - if (h264_arg->codecType == H264_ENC) { - pCTX->codecType = H264_ENC; - } else { - LOGE("SsbSipMfcEncInit] Undefined codec type"); - return MFC_RET_INVALID_PARAM; - } - } - } - - LOGI("SsbSipMfcEncInit] Encode Init start"); - - switch (pCTX->codecType) { - case MPEG4_ENC: - LOGI("SsbSipMfcEncInit] MPEG4 Encode"); - mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; - - pCTX->width = mpeg4_arg->SourceWidth; - pCTX->height = mpeg4_arg->SourceHeight; - break; - - case H263_ENC: - LOGI("SsbSipMfcEncInit] H263 Encode"); - h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; - - pCTX->width = h263_arg->SourceWidth; - pCTX->height = h263_arg->SourceHeight; - break; - - case H264_ENC: - LOGI("SsbSipMfcEncInit] H264 Encode"); - h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; - - pCTX->width = h264_arg->SourceWidth; - pCTX->height = h264_arg->SourceHeight; - break; - - default: - break; - } - - switch (pCTX->codecType) { - case MPEG4_ENC: - mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; - - EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType; - - EncArg.args.enc_init.cmn.in_width = mpeg4_arg->SourceWidth; - EncArg.args.enc_init.cmn.in_height = mpeg4_arg->SourceHeight; - EncArg.args.enc_init.cmn.in_gop_num = mpeg4_arg->IDRPeriod; - - EncArg.args.enc_init.cmn.in_ms_mode = mpeg4_arg->SliceMode; - EncArg.args.enc_init.cmn.in_ms_arg = mpeg4_arg->SliceArgument; - - EncArg.args.enc_init.cmn.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh; - - /* rate control*/ - EncArg.args.enc_init.cmn.in_rc_fr_en = mpeg4_arg->EnableFRMRateControl; - if ((mpeg4_arg->QSCodeMin > 31) || (mpeg4_arg->QSCodeMax > 31)) { - LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_rc_qbound_min = mpeg4_arg->QSCodeMin; - EncArg.args.enc_init.cmn.in_rc_qbound_max = mpeg4_arg->QSCodeMax; - EncArg.args.enc_init.cmn.in_rc_rpara = mpeg4_arg->CBRPeriodRf; - - /* pad control */ - EncArg.args.enc_init.cmn.in_pad_ctrl_on = mpeg4_arg->PadControlOn; - if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) { - LOGE("SsbSipMfcEncInit] No such Pad value is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_y_pad_val = mpeg4_arg->LumaPadVal; - EncArg.args.enc_init.cmn.in_cb_pad_val = mpeg4_arg->CbPadVal; - EncArg.args.enc_init.cmn.in_cr_pad_val = mpeg4_arg->CrPadVal; - - /* Input stream Mode NV12_Linear or NV12_Tile*/ - EncArg.args.enc_init.cmn.in_frame_map = mpeg4_arg->FrameMap; - - EncArg.args.enc_init.cmn.in_rc_bitrate = mpeg4_arg->Bitrate; - if ((mpeg4_arg->FrameQp > 31) || (mpeg4_arg->FrameQp_P > 31)) { - LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_vop_quant = mpeg4_arg->FrameQp; - EncArg.args.enc_init.cmn.in_vop_quant_p = mpeg4_arg->FrameQp_P; - - /* MPEG4 only */ - EncArg.args.enc_init.codec.mpeg4.in_profile = mpeg4_arg->ProfileIDC; - EncArg.args.enc_init.codec.mpeg4.in_level = mpeg4_arg->LevelIDC; - - if (mpeg4_arg->FrameQp_B > 31) { - LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.mpeg4.in_vop_quant_b = mpeg4_arg->FrameQp_B; - - if (mpeg4_arg->NumberBFrames > 2) { - LOGE("SsbSipMfcEncInit] No such BframeNum is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.mpeg4.in_bframenum = mpeg4_arg->NumberBFrames; - - EncArg.args.enc_init.codec.mpeg4.in_quart_pixel = mpeg4_arg->DisableQpelME; - - EncArg.args.enc_init.codec.mpeg4.in_TimeIncreamentRes = mpeg4_arg->TimeIncreamentRes; - EncArg.args.enc_init.codec.mpeg4.in_VopTimeIncreament = mpeg4_arg->VopTimeIncreament; - - break; - - case H263_ENC: - h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; - - EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType; - - EncArg.args.enc_init.cmn.in_width = h263_arg->SourceWidth; - EncArg.args.enc_init.cmn.in_height = h263_arg->SourceHeight; - EncArg.args.enc_init.cmn.in_gop_num = h263_arg->IDRPeriod; - - EncArg.args.enc_init.cmn.in_ms_mode = h263_arg->SliceMode; - EncArg.args.enc_init.cmn.in_ms_arg = 0; - - EncArg.args.enc_init.cmn.in_mb_refresh = h263_arg->RandomIntraMBRefresh; - - /* rate control*/ - EncArg.args.enc_init.cmn.in_rc_fr_en = h263_arg->EnableFRMRateControl; - if ((h263_arg->QSCodeMin > 31) || (h263_arg->QSCodeMax > 31)) { - LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_rc_qbound_min = h263_arg->QSCodeMin; - EncArg.args.enc_init.cmn.in_rc_qbound_max = h263_arg->QSCodeMax; - EncArg.args.enc_init.cmn.in_rc_rpara = h263_arg->CBRPeriodRf; - - /* pad control */ - EncArg.args.enc_init.cmn.in_pad_ctrl_on = h263_arg->PadControlOn; - if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) { - LOGE("SsbSipMfcEncInit] No such Pad value is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_y_pad_val = h263_arg->LumaPadVal; - EncArg.args.enc_init.cmn.in_cb_pad_val = h263_arg->CbPadVal; - EncArg.args.enc_init.cmn.in_cr_pad_val = h263_arg->CrPadVal; - - /* Input stream Mode NV12_Linear or NV12_Tile*/ - EncArg.args.enc_init.cmn.in_frame_map = h263_arg->FrameMap; - - EncArg.args.enc_init.cmn.in_rc_bitrate = h263_arg->Bitrate; - if ((h263_arg->FrameQp > 31) || (h263_arg->FrameQp_P > 31)) { - LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_vop_quant = h263_arg->FrameQp; - EncArg.args.enc_init.cmn.in_vop_quant_p = h263_arg->FrameQp_P; - - /* H.263 only */ - EncArg.args.enc_init.codec.h263.in_rc_framerate = h263_arg->FrameRate; - - break; - - case H264_ENC: - h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; - - EncArg.args.enc_init.cmn.in_codec_type = H264_ENC; - - EncArg.args.enc_init.cmn.in_width = h264_arg->SourceWidth; - EncArg.args.enc_init.cmn.in_height = h264_arg->SourceHeight; - EncArg.args.enc_init.cmn.in_gop_num = h264_arg->IDRPeriod; - - if ((h264_arg->SliceMode == 0)||(h264_arg->SliceMode == 1)|| - (h264_arg->SliceMode == 2)||(h264_arg->SliceMode == 4)) { - EncArg.args.enc_init.cmn.in_ms_mode = h264_arg->SliceMode; - } else { - LOGE("SsbSipMfcEncInit] No such slice mode is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_ms_arg = h264_arg->SliceArgument; - - EncArg.args.enc_init.cmn.in_mb_refresh = h264_arg->RandomIntraMBRefresh; - /* pad control */ - EncArg.args.enc_init.cmn.in_pad_ctrl_on = h264_arg->PadControlOn; - if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) { - LOGE("SsbSipMfcEncInit] No such Pad value is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_y_pad_val = h264_arg->LumaPadVal; - EncArg.args.enc_init.cmn.in_cb_pad_val = h264_arg->CbPadVal; - EncArg.args.enc_init.cmn.in_cr_pad_val = h264_arg->CrPadVal; - - /* Input stream Mode NV12_Linear or NV12_Tile*/ - EncArg.args.enc_init.cmn.in_frame_map = h264_arg->FrameMap; - - /* rate control*/ - EncArg.args.enc_init.cmn.in_rc_fr_en = h264_arg->EnableFRMRateControl; - EncArg.args.enc_init.cmn.in_rc_bitrate = h264_arg->Bitrate; - if ((h264_arg->FrameQp > 51) || (h264_arg->FrameQp_P > 51)) { - LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_vop_quant = h264_arg->FrameQp; - EncArg.args.enc_init.cmn.in_vop_quant_p = h264_arg->FrameQp_P; - - if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) { - LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.cmn.in_rc_qbound_min = h264_arg->QSCodeMin; - EncArg.args.enc_init.cmn.in_rc_qbound_max = h264_arg->QSCodeMax; - EncArg.args.enc_init.cmn.in_rc_rpara = h264_arg->CBRPeriodRf; - - - /* H.264 Only */ - EncArg.args.enc_init.codec.h264.in_profile = h264_arg->ProfileIDC; - EncArg.args.enc_init.codec.h264.in_level = h264_arg->LevelIDC; - - if (h264_arg->FrameQp_B > 51) { - LOGE("SsbSipMfcEncInit] No such FrameQp is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.h264.in_vop_quant_b = h264_arg->FrameQp_B; - - if (h264_arg->NumberBFrames > 2) { - LOGE("SsbSipMfcEncInit] No such BframeNum is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.h264.in_bframenum = h264_arg->NumberBFrames; - - EncArg.args.enc_init.codec.h264.in_interlace_mode = h264_arg->PictureInterlace; - - if ((h264_arg->NumberRefForPframes > 2)||(h264_arg->NumberReferenceFrames >2)) { - LOGE("SsbSipMfcEncInit] No such ref Num is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.h264.in_reference_num = h264_arg->NumberReferenceFrames; - EncArg.args.enc_init.codec.h264.in_ref_num_p = h264_arg->NumberRefForPframes; - - EncArg.args.enc_init.codec.h264.in_rc_framerate = h264_arg->FrameRate; - - EncArg.args.enc_init.codec.h264.in_rc_mb_en = h264_arg->EnableMBRateControl; - EncArg.args.enc_init.codec.h264.in_rc_mb_dark_dis = h264_arg->DarkDisable; - EncArg.args.enc_init.codec.h264.in_rc_mb_smooth_dis = h264_arg->SmoothDisable; - EncArg.args.enc_init.codec.h264.in_rc_mb_static_dis = h264_arg->StaticDisable; - EncArg.args.enc_init.codec.h264.in_rc_mb_activity_dis = h264_arg->ActivityDisable; - - EncArg.args.enc_init.codec.h264.in_deblock_dis = h264_arg->LoopFilterDisable; - if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) { - LOGE("SsbSipMfcEncInit] No such AlphaC0Offset or BetaOffset is supported"); - return MFC_RET_INVALID_PARAM; - } - EncArg.args.enc_init.codec.h264.in_deblock_alpha_c0 = h264_arg->LoopFilterAlphaC0Offset; - EncArg.args.enc_init.codec.h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset; - - EncArg.args.enc_init.codec.h264.in_symbolmode = h264_arg->SymbolMode; - EncArg.args.enc_init.codec.h264.in_transform8x8_mode = h264_arg->Transform8x8Mode; - - /* FIXME: is it removed? */ - EncArg.args.enc_init.codec.h264.in_md_interweight_pps = 300; - EncArg.args.enc_init.codec.h264.in_md_intraweight_pps = 170; - - break; - - default: - LOGE("SsbSipMfcEncInit] No such codec type is supported"); - return MFC_RET_INVALID_PARAM; - } - - EncArg.args.enc_init.cmn.in_mapped_addr = pCTX->mapped_addr; - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg); - if (EncArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcEncInit] IOCTL_MFC_ENC_INIT failed"); - return MFC_RET_ENC_INIT_FAIL; - } - - pCTX->virStrmBuf = EncArg.args.enc_init.cmn.out_u_addr.strm_ref_y; - pCTX->phyStrmBuf = EncArg.args.enc_init.cmn.out_p_addr.strm_ref_y; - - pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; - pCTX->encodedHeaderSize = EncArg.args.enc_init.cmn.out_header_size; - - pCTX->virMvRefYC = EncArg.args.enc_init.cmn.out_u_addr.mv_ref_yc; - - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args EncArg; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncExe] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - - memset(&EncArg, 0x00, sizeof(struct mfc_common_args)); - - EncArg.args.enc_exe.in_codec_type = pCTX->codecType; - EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma; - EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma; -#if 0 /* peter for debug */ - EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma; - EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma; -#endif - EncArg.args.enc_exe.in_frametag = pCTX->inframetag; - if (pCTX->encode_cnt == 0) { - EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; - EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; - } else { - EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); - EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); - } - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg); - if (EncArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcEncExe] IOCTL_MFC_ENC_EXE failed(ret : %d)", EncArg.ret_code); - return MFC_RET_ENC_EXE_ERR; - } - - pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size; - pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type; - pCTX->encodedphyFrmBuf.luma = EncArg.args.enc_exe.out_Y_addr; - pCTX->encodedphyFrmBuf.chroma = EncArg.args.enc_exe.out_CbCr_addr; - pCTX->outframetagtop = EncArg.args.enc_exe.out_frametag_top; - pCTX->outframetagbottom = EncArg.args.enc_exe.out_frametag_bottom; - - LOGV("SsbSipMfcEncExe] Encode success =================="); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args free_arg; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncClose] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - - /* FIXME: free buffer? */ - if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { - free_arg.args.mem_free.key = pCTX->virFrmBuf.luma; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - } - - if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { - free_arg.args.mem_free.key = pCTX->virStrmBuf; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - free_arg.args.mem_free.key = pCTX->virMvRefYC; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); - } - - pCTX->inter_buff_status = MFC_USE_NONE; - - munmap((void *)pCTX->mapped_addr, pCTX->mapped_size); - - close(pCTX->hMFC); - - free(pCTX); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args user_addr_arg, real_addr_arg; - int y_size, c_size; - int aligned_y_size, aligned_c_size; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncGetInBuf] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - /* FIXME: */ - y_size = pCTX->width * pCTX->height; - c_size = (pCTX->width * pCTX->height) >> 1; - - /* lenear: 2KB, tile: 8KB */ - aligned_y_size = Align(y_size, 64 * BUF_L_UNIT); - aligned_c_size = Align(c_size, 64 * BUF_L_UNIT); - - /* Allocate luma & chroma buf */ - user_addr_arg.args.mem_alloc.type = ENCODER; - user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size; - user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_IN_BUF failed"); - return MFC_RET_ENC_GET_INBUF_FAIL; - } - - pCTX->virFrmBuf.luma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset; - pCTX->virFrmBuf.chroma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset + (unsigned int)aligned_y_size; - - real_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset; - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &real_addr_arg); - if (ret_code < 0) { - LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_REAL_ADDR failed"); - return MFC_RET_ENC_GET_INBUF_FAIL; - } - pCTX->phyFrmBuf.luma = real_addr_arg.args.real_addr.addr; - pCTX->phyFrmBuf.chroma = real_addr_arg.args.real_addr.addr + (unsigned int)aligned_y_size; - - pCTX->sizeFrmBuf.luma = (unsigned int)y_size; - pCTX->sizeFrmBuf.chroma = (unsigned int)c_size; - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma; - input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma; - input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma; - input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - _MFCLIB *pCTX; - int ret_code; - struct mfc_common_args user_addr_arg, real_addr_arg; - int y_size, c_size; - int aligned_y_size, aligned_c_size; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncSetInBuf] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - LOGV("SsbSipMfcEncSetInBuf] input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned"); - - pCTX = (_MFCLIB *) openHandle; - - /* FIXME: */ - y_size = pCTX->width * pCTX->height; - c_size = (pCTX->width * pCTX->height) >> 1; - - /* lenear: 2KB, tile: 8KB */ - aligned_y_size = Align(y_size, 64 * BUF_L_UNIT); - aligned_c_size = Align(c_size, 64 * BUF_L_UNIT); - - pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr; - pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr; - - pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize; - pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncGetOutBuf] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *)openHandle; - - output_info->headerSize = pCTX->encodedHeaderSize; - output_info->dataSize = pCTX->encodedDataSize; - output_info->frameType = pCTX->encodedframeType; - - if (pCTX->encode_cnt == 0) { - output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; - output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr; - } else { - output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); - output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2); - } - - pCTX->encode_cnt ++; - pCTX->encode_cnt %= 2; - - output_info->encodedYPhyAddr = (void*)pCTX->encodedphyFrmBuf.luma; - output_info->encodedCPhyAddr = (void*)pCTX->encodedphyFrmBuf.chroma; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncSetOutBuf] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - pCTX->phyStrmBuf = (int)phyOutbuf; - pCTX->virStrmBuf = (int)virOutbuf; - pCTX->sizeStrmBuf = outputBufferSize; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - int ret_code; - _MFCLIB *pCTX; - struct mfc_common_args EncArg; - struct mfc_enc_vui_info vui_info; - struct mfc_enc_hier_p_qp hier_p_qp; -#ifdef S3D_SUPPORT - struct mfc_enc_set_config set_info; - struct mfc_frame_packing *frame_packing; -#endif - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncSetConfig] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("SsbSipMfcEncSetConfig] value is NULL"); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - memset(&EncArg, 0x00, sizeof(struct mfc_common_args)); - -#ifdef S3D_SUPPORT - EncArg.args.config.type = conf_type; - - switch (conf_type) { - case MFC_ENC_SETCONF_FRAME_TAG: - pCTX->inframetag = *((unsigned int *)value); - return MFC_RET_OK; - case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: - set_info = *((struct mfc_enc_set_config *) value); - EncArg.args.config.args.basic.values[0] = set_info.enable; - if (set_info.enable == 2) - EncArg.args.config.args.basic.values[1] = set_info.number; - else - EncArg.args.config.args.basic.values[1] = 0; - break; - case MFC_ENC_SETCONF_VUI_INFO: - set_info = *((struct mfc_enc_set_config *) value); - EncArg.args.config.args.basic.values[0] = set_info.enable; - if (set_info.enable == 255) //Re-check this part of code with Jeongtae Park - EncArg.args.config.args.basic.values[1] = set_info.number; - else - EncArg.args.config.args.basic.values[1] = 0; - - EncArg.args.config.args.basic.values[1] = set_info.number; - break; - case MFC_ENC_SETCONF_FRAME_PACKING: - frame_packing = (struct mfc_frame_packing *)value; - /* - memcpy(&EncArg.args.config.args.frame_packing, frame_packing, - sizeof(struct mfc_frame_packing)); - */ - EncArg.args.config.args.basic.values[0] = frame_packing->arrangement_type; - EncArg.args.config.args.basic.values[1] = frame_packing->current_frame_is_frame0_flag; - break; - case MFC_ENC_SETCONF_FRAME_TYPE: - case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: - case MFC_ENC_SETCONF_CHANGE_BIT_RATE: - case MFC_ENC_SETCONF_I_PERIOD: - case MFC_ENC_SETCONF_HIER_P: - case MFC_ENC_SETCONF_SEI_GEN: - EncArg.args.config.args.basic.values[0] = *((int *) value); - EncArg.args.config.args.basic.values[1] = 0; - break; - default: - LOGE("SsbSipMfcEncSetConfig] not supported type"); - return MFC_RET_ENC_SET_CONF_FAIL; - } -#else - EncArg.args.set_config.in_config_param = conf_type; - switch (conf_type) { - case MFC_ENC_SETCONF_FRAME_TAG: - pCTX->inframetag = *((unsigned int *)value); - return MFC_RET_OK; - case MFC_ENC_SETCONF_VUI_INFO: - vui_info = *((struct mfc_enc_vui_info *) value); - EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); - EncArg.args.set_config.in_config_value[1] = 0; - break; - case MFC_ENC_SETCONF_HIER_P: - hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); - EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp); - EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp); - EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp); - break; - default: - EncArg.args.set_config.in_config_value[0] = *((int *) value); - EncArg.args.set_config.in_config_value[1] = 0; - break; - } -#endif - - ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg); - if (EncArg.ret_code != MFC_OK) { - LOGE("SsbSipMfcEncSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d)", EncArg.ret_code); - return MFC_RET_ENC_SET_CONF_FAIL; - } - - return MFC_RET_OK; -} - - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - /* - unsigned int *encoded_header_size; - */ - - pCTX = (_MFCLIB *)openHandle; - - if (openHandle == NULL) { - LOGE("SsbSipMfcEncGetConfig] openHandle is NULL"); - return MFC_RET_INVALID_PARAM; - } - if (value == NULL) { - LOGE("SsbSipMfcEncGetConfig] value is NULL"); - return MFC_RET_INVALID_PARAM; - } - - switch (conf_type) { - case MFC_ENC_GETCONF_FRAME_TAG: - *((unsigned int *)value) = pCTX->outframetagtop; - break; -#if 0 - case MFC_ENC_GETCONF_HEADER_SIZE: - encoded_header_size = (unsigned int *)value; - *encoded_header_size = pCTX->encodedHeaderSize; - break; -#endif - default: - LOGE("SsbSipMfcEncGetConfig] No such conf_type is supported."); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} - diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h deleted file mode 100644 index fed3e34..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SSBSIP_MFC_API_H_ -#define _SSBSIP_MFC_API_H_ - -/*--------------------------------------------------------------------------------*/ -/* Definition */ -/*--------------------------------------------------------------------------------*/ -#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) -#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) - -#define SUPPORT_1080P 1 - -#if SUPPORT_1080P -#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ -#else -#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) -#endif - -#define SAMSUNG_MFC_DEV_NAME "/dev/s3c-mfc" - - -/*--------------------------------------------------------------------------------*/ -/* Structure and Type */ -/*--------------------------------------------------------------------------------*/ -typedef enum { - H264_DEC, - VC1_DEC, /* VC1 advaced Profile decoding */ - MPEG4_DEC, - XVID_DEC, - MPEG1_DEC, - MPEG2_DEC, - H263_DEC, - VC1RCV_DEC, /* VC1 simple/main profile decoding */ - FIMV1_DEC, - FIMV2_DEC, - FIMV3_DEC, - FIMV4_DEC, - H264_ENC, - MPEG4_ENC, - H263_ENC, - UNKNOWN_TYPE -} SSBSIP_MFC_CODEC_TYPE; - -typedef enum { - DONT_CARE = 0, - I_FRAME = 1, - NOT_CODED = 2 -} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; - -typedef enum { - NV12_LINEAR = 0, - NV12_TILE, - NV21_LINEAR -} SSBSIP_MFC_INSTRM_MODE_TYPE; - -typedef enum { - FRAME = 0, - SLICE, -} SSBSIP_MFC_OUTSTRM_MODE_TYPE; - -typedef enum { - NO_CACHE = 0, - CACHE = 1 -} SSBIP_MFC_BUFFER_TYPE; - -typedef enum { - MFC_DEC_SETCONF_POST_ENABLE = 1, - MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, - MFC_DEC_SETCONF_DISPLAY_DELAY, - MFC_DEC_SETCONF_IS_LAST_FRAME, - MFC_DEC_SETCONF_SLICE_ENABLE, - MFC_DEC_SETCONF_CRC_ENABLE, - MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, - MFC_DEC_SETCONF_FRAME_TAG, - MFC_DEC_GETCONF_CRC_DATA, - MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, - MFC_DEC_GETCONF_CROP_INFO, - MFC_DEC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, - MFC_DEC_SETCONF_DPB_FLUSH, - MFC_DEC_SETCONF_PIXEL_CACHE, -#ifndef S3D_SUPPORT - MFC_DEC_GETCONF_WIDTH_HEIGHT -#else - MFC_DEC_GETCONF_WIDTH_HEIGHT, - MFC_DEC_SETCONF_SEI_PARSE, - MFC_DEC_GETCONF_FRAME_PACKING -#endif -} SSBSIP_MFC_DEC_CONF; - -typedef enum { - MFC_ENC_SETCONF_FRAME_TYPE = 100, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - MFC_ENC_SETCONF_FRAME_TAG, - MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, - MFC_ENC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_ENC_SETCONF_VUI_INFO, - MFC_ENC_SETCONF_I_PERIOD, -#ifndef S3D_SUPPORT - MFC_ENC_SETCONF_HIER_P -#else - MFC_ENC_SETCONF_HIER_P, - MFC_ENC_SETCONF_SEI_GEN, - MFC_ENC_SETCONF_FRAME_PACKING -#endif -} SSBSIP_MFC_ENC_CONF; - -typedef enum { - MFC_GETOUTBUF_STATUS_NULL = 0, - MFC_GETOUTBUF_DECODING_ONLY = 1, - MFC_GETOUTBUF_DISPLAY_DECODING, - MFC_GETOUTBUF_DISPLAY_ONLY, - MFC_GETOUTBUF_DISPLAY_END, - MFC_GETOUTBUF_CHANGE_RESOL -} SSBSIP_MFC_DEC_OUTBUF_STATUS; - -typedef enum { - MFC_FRAME_TYPE_NOT_CODED, - MFC_FRAME_TYPE_I_FRAME, - MFC_FRAME_TYPE_P_FRAME, - MFC_FRAME_TYPE_B_FRAME, - MFC_FRAME_TYPE_OTHERS -} SSBSIP_MFC_FRAME_TYPE; - -typedef enum { - MFC_RET_OK = 1, - MFC_RET_FAIL = -1000, - MFC_RET_OPEN_FAIL = -1001, - MFC_RET_CLOSE_FAIL = -1002, - - MFC_RET_DEC_INIT_FAIL = -2000, - MFC_RET_DEC_EXE_TIME_OUT = -2001, - MFC_RET_DEC_EXE_ERR = -2002, - MFC_RET_DEC_GET_INBUF_FAIL = -2003, - MFC_RET_DEC_SET_INBUF_FAIL = -2004, - MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, - MFC_RET_DEC_GET_CONF_FAIL = -2006, - MFC_RET_DEC_SET_CONF_FAIL = -2007, - - MFC_RET_ENC_INIT_FAIL = -3000, - MFC_RET_ENC_EXE_TIME_OUT = -3001, - MFC_RET_ENC_EXE_ERR = -3002, - MFC_RET_ENC_GET_INBUF_FAIL = -3003, - MFC_RET_ENC_SET_INBUF_FAIL = -3004, - MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, - MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, - MFC_RET_ENC_GET_CONF_FAIL = -3007, - MFC_RET_ENC_SET_CONF_FAIL = -3008, - - MFC_RET_INVALID_PARAM = -4000 -} SSBSIP_MFC_ERROR_CODE; - -typedef struct { - void *YPhyAddr; /* [OUT] physical address of Y */ - void *CPhyAddr; /* [OUT] physical address of CbCr */ - void *YVirAddr; /* [OUT] virtual address of Y */ - void *CVirAddr; /* [OUT] virtual address of CbCr */ - - int img_width; /* [OUT] width of real image */ - int img_height; /* [OUT] height of real image */ - int buf_width; /* [OUT] width aligned to 16 */ - int buf_height; /* [OUT] height alighed to 16 */ - - int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ - int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ - int consumedByte; /* [OUT] the number of byte consumed during decoding */ - int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ - int crop_top_offset; /* [OUT] crop information, top_offset */ - int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ - int crop_left_offset; /* [OUT] crop information, left_offset */ - int crop_right_offset; /* [OUT] crop information, right_offset */ - int disp_pic_frame_type; /* [OUT] display picture frame type information */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_DEC_OUTPUT_INFO; - -typedef struct { - void *YPhyAddr; /* [IN/OUT] physical address of Y */ - void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ - void *YVirAddr; /* [IN/OUT] virtual address of Y */ - void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ - int YSize; /* [IN/OUT] input size of Y data */ - int CSize; /* [IN/OUT] input size of CbCr data */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_INPUT_INFO; - -typedef struct { - unsigned int dataSize; /* [OUT] encoded data size(without header) */ - unsigned int headerSize; /* [OUT] encoded header size */ - unsigned int frameType; /* [OUT] frame type of encoded stream */ - void *StrmPhyAddr; /* [OUT] physical address of Y */ - void *StrmVirAddr; /* [OUT] virtual address of Y */ - void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ - void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ - - /* C210 UMP feature */ - unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ - unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ - unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_OUTPUT_INFO; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */ - - /* H.264 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int NumberReferenceFrames; /* [IN] The number of reference pictures used */ - int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ - int LoopFilterDisable; /* [IN] disable the loop filter */ - int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ - int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ - int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ - int PictureInterlace; /* [IN] Enables the interlace mode */ - int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ - int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ - int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ - int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ - int StaticDisable; /* [IN] Disable adaptive rate control on static region */ - int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ -} SSBSIP_MFC_ENC_H264_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */ - - /* MPEG4 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int TimeIncreamentRes; /* [IN] frame rate */ - int VopTimeIncreament; /* [IN] frame rate */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ -} SSBSIP_MFC_ENC_MPEG4_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - - /* H.263 specific parameters */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ -} SSBSIP_MFC_ENC_H263_PARAM; - -typedef struct { - int width; - int height; - int buf_width; - int buf_height; -} SSBSIP_MFC_IMG_RESOLUTION; - -typedef struct { - int crop_top_offset; - int crop_bottom_offset; - int crop_left_offset; - int crop_right_offset; -} SSBSIP_MFC_CROP_INFORMATION; - -#ifdef S3D_SUPPORT -typedef struct { - int available; - unsigned int arrangement_id; - int arrangement_cancel_flag; - unsigned char arrangement_type; - int quincunx_sampling_flag; - unsigned char content_interpretation_type; - int spatial_flipping_flag; - int frame0_flipped_flag; - int field_views_flag; - int current_frame_is_frame0_flag; - unsigned char frame0_grid_pos_x; - unsigned char frame0_grid_pos_y; - unsigned char frame1_grid_pos_x; - unsigned char frame1_grid_pos_y; -} SSBSIP_MFC_FRAME_PACKING; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*--------------------------------------------------------------------------------*/ -/* Decoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcDecOpen(void); -void *SsbSipMfcDecOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); - - -#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); -#else -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); -#endif - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); - -void *SsbSipMfcDecAllocInputBuffer(void *openHandle, void **phyInBuf, int inputBufferSize); -void SsbSipMfcDecFreeInputBuffer(void *openHandle, void *phyInBuf); - -/*--------------------------------------------------------------------------------*/ -/* Encoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcEncOpen(void); -void *SsbSipMfcEncOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h deleted file mode 100644 index 305a28e..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_ERRNO_H -#define __MFC_ERRNO_H __FILE__ - -enum mfc_ret_code { - MFC_OK = 1, - MFC_FAIL = -1000, - MFC_OPEN_FAIL = -1001, - MFC_CLOSE_FAIL = -1002, - - MFC_DEC_INIT_FAIL = -2000, - MFC_DEC_EXE_TIME_OUT = -2001, - MFC_DEC_EXE_ERR = -2002, - MFC_DEC_GET_INBUF_FAIL = 2003, - MFC_DEC_SET_INBUF_FAIL = 2004, - MFC_DEC_GET_OUTBUF_FAIL = -2005, - MFC_DEC_GET_CONF_FAIL = -2006, - MFC_DEC_SET_CONF_FAIL = -2007, - - MFC_ENC_INIT_FAIL = -3000, - MFC_ENC_EXE_TIME_OUT = -3001, - MFC_ENC_EXE_ERR = -3002, - MFC_ENC_GET_INBUF_FAIL = -3003, - MFC_ENC_SET_INBUF_FAIL = -3004, - MFC_ENC_GET_OUTBUF_FAIL = -3005, - MFC_ENC_SET_OUTBUF_FAIL = -3006, - MFC_ENC_GET_CONF_FAIL = -3007, - MFC_ENC_SET_CONF_FAIL = -3008, - - MFC_STATE_INVALID = -4000, - MFC_DEC_HEADER_FAIL = -4001, - MFC_DEC_INIT_BUF_FAIL = -4002, - MFC_ENC_HEADER_FAIL = -5000, - MFC_ENC_PARAM_FAIL = -5001, - MFC_FRM_BUF_SIZE_FAIL = -6000, - MFC_FW_LOAD_FAIL = -6001, - MFC_FW_INIT_FAIL = -6002, - MFC_INST_NUM_EXCEEDED_FAIL = -6003, - MFC_MEM_ALLOC_FAIL = -6004, - MFC_MEM_INVALID_ADDR_FAIL = -6005, - MFC_MEM_MAPPING_FAIL = -6006, - MFC_GET_CONF_FAIL = -6007, - MFC_SET_CONF_FAIL = -6008, - MFC_INVALID_PARAM_FAIL = -6009, - MFC_API_FAIL = -9000, - - MFC_CMD_FAIL = -1003, - MFC_SLEEP_FAIL = -1010, - MFC_WAKEUP_FAIL = -1020, - - MFC_CLK_ON_FAIL = -1030, - MFC_CLK_OFF_FAIL = -1030, - MFC_PWR_ON_FAIL = -1040, - MFC_PWR_OFF_FAIL = -1041, -} ; - -#endif /* __MFC_ERRNO_H */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h deleted file mode 100644 index 968da44..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_INTERFACE_H -#define __MFC_INTERFACE_H __FILE__ - -#include "mfc_errno.h" -#include "SsbSipMfcApi.h" - -#define IOCTL_MFC_DEC_INIT (0x00800001) -#define IOCTL_MFC_ENC_INIT (0x00800002) -#define IOCTL_MFC_DEC_EXE (0x00800003) -#define IOCTL_MFC_ENC_EXE (0x00800004) - -#define IOCTL_MFC_GET_IN_BUF (0x00800010) -#define IOCTL_MFC_FREE_BUF (0x00800011) -#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) -#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) -#define IOCTL_MFC_SET_IN_BUF (0x00800018) - -#define IOCTL_MFC_SET_CONFIG (0x00800101) -#define IOCTL_MFC_GET_CONFIG (0x00800102) - -#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) - -/* MFC H/W support maximum 32 extra DPB. */ -#define MFC_MAX_EXTRA_DPB 5 -#define MFC_MAX_DISP_DELAY 0xF - -#define MFC_LIB_VER_MAJOR 1 -#define MFC_LIB_VER_MINOR 00 - -#define BUF_L_UNIT (1024) -#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) - -enum inst_type { - DECODER = 0x1, - ENCODER = 0x2, -}; - -typedef enum { - MFC_UNPACKED_PB = 0, - MFC_PACKED_PB = 1 -} mfc_packed_mode; - - -typedef enum -{ - MFC_USE_NONE = 0x00, - MFC_USE_YUV_BUFF = 0x01, - MFC_USE_STRM_BUFF = 0x10 -} s3c_mfc_interbuff_status; - -typedef struct -{ - int luma0; /* per frame (or top field) */ - int chroma0; /* per frame (or top field) */ - int luma1; /* per frame (or bottom field) */ - int chroma1; /* per frame (or bottom field) */ -} SSBSIP_MFC_CRC_DATA; - -struct mfc_strm_ref_buf_arg { - unsigned int strm_ref_y; - unsigned int mv_ref_yc; -}; - -struct mfc_frame_buf_arg { - unsigned int luma; - unsigned int chroma; -}; - - -struct mfc_enc_init_common_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - - int in_width; /* [IN] width of YUV420 frame to be encoded */ - int in_height; /* [IN] height of YUV420 frame to be encoded */ - - int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ - int in_vop_quant; /* [IN] VOP quant */ - int in_vop_quant_p; /* [IN] VOP quant for P frame */ - - /* [IN] RC enable */ - /* [IN] RC enable (0:disable, 1:frame level RC) */ - int in_rc_fr_en; - int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ - - int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ - int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ - int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ - - /* [IN] Multi-slice mode (0:single, 1:multiple) */ - int in_ms_mode; - /* [IN] Multi-slice size (in num. of mb or byte) */ - int in_ms_arg; - - int in_mb_refresh; /* [IN] Macroblock refresh */ - - /* [IN] Enable (1) / Disable (0) padding with the specified values */ - int in_pad_ctrl_on; - - /* [IN] pad value if pad_ctrl_on is Enable */ - int in_y_pad_val; - int in_cb_pad_val; - int in_cr_pad_val; - - /* linear or tiled */ - int in_frame_map; - - unsigned int in_pixelcache; - - - unsigned int in_mapped_addr; - struct mfc_strm_ref_buf_arg out_u_addr; - struct mfc_strm_ref_buf_arg out_p_addr; - struct mfc_strm_ref_buf_arg out_buf_size; - unsigned int out_header_size; -}; - -struct mfc_enc_init_h263_arg { - int in_rc_framerate; /* [IN] RC parameter (framerate) */ -}; - -struct mfc_enc_init_mpeg4_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ - int in_quart_pixel; - - int in_TimeIncreamentRes; /* [IN] VOP time resolution */ - int in_VopTimeIncreament; /* [IN] Frame delta */ -}; - -struct mfc_enc_init_h264_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] interlace mode(0:progressive, 1:interlace) */ - int in_interlace_mode; - - /* [IN] reference number */ - int in_reference_num; - /* [IN] reference number of P frame */ - int in_ref_num_p; - - int in_rc_framerate; /* [IN] RC parameter (framerate) */ - int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ - /* [IN] MB level rate control dark region adaptive feature */ - int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control smooth region adaptive feature */ - int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control static region adaptive feature */ - int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control activity region adaptive feature */ - int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ - - /* [IN] disable deblocking filter idc */ - int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ - /* [IN] slice alpha c0 offset of deblocking filter */ - int in_deblock_alpha_c0; - /* [IN] slice beta offset of deblocking filter */ - int in_deblock_beta; - - /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ - int in_symbolmode; - /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ - int in_transform8x8_mode; - - /* [IN] Inter weighted parameter for mode decision */ - int in_md_interweight_pps; - /* [IN] Intra weighted parameter for mode decision */ - int in_md_intraweight_pps; -}; - -struct mfc_enc_init_arg { - struct mfc_enc_init_common_arg cmn; - union { - struct mfc_enc_init_h264_arg h264; - struct mfc_enc_init_mpeg4_arg mpeg4; - struct mfc_enc_init_h263_arg h263; - } codec; -}; - -struct mfc_enc_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ - unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ - unsigned int in_frametag; /* [IN] unique frame ID */ - - unsigned int out_frame_type; /* [OUT] frame type */ - int out_encoded_size; /* [OUT] Length of Encoded video stream */ - unsigned int out_Y_addr; /* [OUT]Out-buffer addr of encoded Y component */ - unsigned int out_CbCr_addr; /* [OUT]Out-buffer addr of encoded CbCr component */ - unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */ - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif -}; - -struct mfc_dec_init_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] address of stream buffer */ - int in_strm_size; /* [IN] filled size in stream buffer */ - int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ - - unsigned int in_crc; /* [IN] */ - unsigned int in_pixelcache; /* [IN] */ - unsigned int in_slice; /* [IN] */ - unsigned int in_numextradpb; /* [IN] */ - - unsigned int in_mapped_addr; - - int out_frm_width; /* [OUT] width of YUV420 frame */ - int out_frm_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ - - int out_crop_right_offset; /* [OUT] crop information for h264 */ - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; -}; - -struct mfc_dec_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] the physical address of STRM_BUF */ - /* [IN] Size of video stream filled in STRM_BUF */ - int in_strm_size; - /* [IN] the address of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_buf; - /* [IN] size of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_size; - /* [IN] Unique frame ID eg. application specific timestamp */ - unsigned int in_frametag; - /* [IN] immdiate Display for seek,thumbnail and one frame */ - int in_immediately_disp; - /* [OUT] the physical address of display buf */ - int out_display_Y_addr; - /* [OUT] the physical address of display buf */ - int out_display_C_addr; - int out_display_status; - /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_top; - /* [OUT] unique frame ID of bottom field */ - unsigned int out_frametag_bottom; - int out_pic_time_top; - int out_pic_time_bottom; - int out_consumed_byte; - - int out_crop_right_offset; - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; - - /* in new driver, each buffer offset must be return to the user */ - int out_y_offset; - int out_c_offset; - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif - int out_img_width; /* [OUT] width of YUV420 frame */ - int out_img_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ -}; - -#ifdef S3D_SUPPORT -struct mfc_basic_config { - int values[4]; -}; - -struct mfc_frame_packing { - int available; - unsigned int arrangement_id; - int arrangement_cancel_flag; - unsigned char arrangement_type; - int quincunx_sampling_flag; - unsigned char content_interpretation_type; - int spatial_flipping_flag; - int frame0_flipped_flag; - int field_views_flag; - int current_frame_is_frame0_flag; - unsigned char frame0_grid_pos_x; - unsigned char frame0_grid_pos_y; - unsigned char frame1_grid_pos_x; - unsigned char frame1_grid_pos_y; -}; - -union _mfc_config_arg { - struct mfc_basic_config basic; - struct mfc_frame_packing frame_packing; -}; - -struct mfc_config_arg { - int type; - union _mfc_config_arg args; -}; -#else -struct mfc_get_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to get for the configurable parameter. */ - /* Maximum four integer values can be obtained; */ - int out_config_value[4]; -}; - -struct mfc_set_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to be set for the configurable parameter. */ - /* Maximum four integer values can be set. */ - int in_config_value[4]; -}; -#endif - -struct mfc_get_real_addr_arg { - unsigned int key; - unsigned int addr; -}; - -struct mfc_buf_alloc_arg { - enum inst_type type; - int size; - /* - unsigned int mapped; - */ - unsigned int align; - - unsigned int addr; - /* - unsigned int phys; - */ -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - /* FIMXE: invalid secure id == -1 */ - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_buf_free_arg { - unsigned int addr; -}; - - -/* RMVME */ -struct mfc_mem_alloc_arg { - enum inst_type type; - int buff_size; - SSBIP_MFC_BUFFER_TYPE buf_cache_type; - unsigned int mapped_addr; -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_mem_free_arg { - unsigned int key; -}; -/* RMVME */ - -union mfc_args { - /* - struct mfc_enc_init_arg enc_init; - - struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; - struct mfc_enc_init_mpeg4_arg enc_init_h263; - struct mfc_enc_init_h264_arg enc_init_h264; - */ - struct mfc_enc_init_arg enc_init; - struct mfc_enc_exe_arg enc_exe; - - struct mfc_dec_init_arg dec_init; - struct mfc_dec_exe_arg dec_exe; - -#ifdef S3D_SUPPORT - struct mfc_config_arg config; -#else - struct mfc_get_config_arg get_config; - struct mfc_set_config_arg set_config; -#endif - - struct mfc_buf_alloc_arg buf_alloc; - struct mfc_buf_free_arg buf_free; - struct mfc_get_real_addr_arg real_addr; - - /* RMVME */ - struct mfc_mem_alloc_arg mem_alloc; - struct mfc_mem_free_arg mem_free; - /* RMVME */ -}; - -struct mfc_common_args { - enum mfc_ret_code ret_code; /* [OUT] error code */ - union mfc_args args; -}; - -struct mfc_enc_vui_info { - int aspect_ratio_idc; -}; - -struct mfc_dec_fimv1_info { - int width; - int height; -}; - -struct mfc_enc_hier_p_qp { - int t0_frame_qp; - int t2_frame_qp; - int t3_frame_qp; -}; - -#ifdef S3D_SUPPORT -struct mfc_enc_set_config { - int enable; - int number; -}; -#endif - -typedef struct -{ - int magic; - int hMFC; - int hVMEM; - int width; - int height; - int sizeStrmBuf; - struct mfc_frame_buf_arg sizeFrmBuf; - int displayStatus; - int inter_buff_status; - unsigned int virFreeStrmAddr; - unsigned int phyStrmBuf; - unsigned int virStrmBuf; - unsigned int virMvRefYC; - struct mfc_frame_buf_arg phyFrmBuf; - struct mfc_frame_buf_arg virFrmBuf; - unsigned int mapped_addr; - unsigned int mapped_size; - struct mfc_common_args MfcArg; - SSBSIP_MFC_CODEC_TYPE codecType; - SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; - unsigned int inframetag; - unsigned int outframetagtop; - unsigned int outframetagbottom; - unsigned int immediatelydisp; - unsigned int encodedHeaderSize; - int encodedDataSize; - unsigned int encodedframeType; - struct mfc_frame_buf_arg encodedphyFrmBuf; - - unsigned int dec_crc; - unsigned int dec_pixelcache; - unsigned int dec_slice; - unsigned int dec_numextradpb; - - int input_cookie; - int input_secure_id; - int input_size; - - /* to support non-blocking mode */ - unsigned int encode_cnt; -} _MFCLIB; - -#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) -#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) - -#endif /* __MFC_INTERFACE_H */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk deleted file mode 100644 index f135163..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - include/mfc_errno.h \ - include/mfc_interface.h \ - include/SsbSipMfcApi.h - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - dec/src/SsbSipMfcDecAPI.c \ - enc/src/SsbSipMfcEncAPI.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - $(BOARD_HAL_PATH)/include - -LOCAL_MODULE := libsecmfcapi - -LOCAL_PRELINK_MODULE := false - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS := -DCONFIG_MFC_FPS -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := liblog - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c deleted file mode 100644 index 510a351..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c +++ /dev/null @@ -1,1352 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include "videodev2.h" - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" - -/* #define LOG_NDEBUG 0 */ -#define LOG_TAG "MFC_DEC_APP" -#include - -#ifdef CONFIG_MFC_FPS -#include -#endif - -/*#define CRC_ENABLE -#define SLICE_MODE_ENABLE */ -#define POLL_DEC_WAIT_TIMEOUT 25 - -#define USR_DATA_START_CODE (0x000001B2) -#define VOP_START_CODE (0x000001B6) -#define MP4_START_CODE (0x000001) - -#ifdef CONFIG_MFC_FPS -unsigned int framecount, over30ms; -struct timeval mTS1, mTS2, mDec1, mDec2; -#endif - -#define DEFAULT_NUMBER_OF_EXTRA_DPB 5 - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; -static int mfc_dev_node = 6; - -static void getAByte(char *buff, int *code) -{ - int byte; - - *code = (*code << 8); - byte = (int)*buff; - byte &= 0xFF; - *code |= byte; -} - -static int isPBPacked(_MFCLIB *pCtx, int Frameleng) -{ - char *strmBuffer = NULL; - int startCode = 0xFFFFFFFF; - int leng_idx = 1; - - strmBuffer = (char*)pCtx->virStrmBuf; - - while (1) { - while (startCode != USR_DATA_START_CODE) { - if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { - LOGI("[%s] VOP START Found !!.....return",__func__); - LOGW("[%s] Non Packed PB",__func__); - return 0; - } - getAByte(strmBuffer, &startCode); - LOGV(">> StartCode = 0x%08x <<\n", startCode); - strmBuffer++; - leng_idx++; - } - LOGI("[%s] User Data Found !!",__func__); - - do { - if (*strmBuffer == 'p') { - LOGW("[%s] Packed PB",__func__); - return 1; - } - getAByte(strmBuffer, &startCode); - strmBuffer++; leng_idx++; - } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); - - if (leng_idx > Frameleng) - break; - } - - LOGW("[%s] Non Packed PB",__func__); - - return 0; -} - -static void getMFCName(char *devicename, int size) -{ - snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); -} - -void SsbSipMfcDecSetMFCNode(int devicenode) -{ - mfc_dev_node = devicenode; -} - -void SsbSipMfcDecSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcDecOpen(void) -{ - int hMFCOpen; - _MFCLIB *pCTX; - - char mfc_dev_name[64]; - - int ret; - unsigned int i, j; - struct v4l2_capability cap; - struct v4l2_format fmt; - - struct v4l2_requestbuffers reqbuf; - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); -#ifdef CONFIG_MFC_FPS - framecount = 0; - over30ms = 0; - gettimeofday(&mTS1, NULL); -#endif - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("[%s] malloc failed.",__func__); - return NULL; - } - - memset(pCTX, 0, sizeof(_MFCLIB)); - - getMFCName(mfc_dev_name, 64); - LOGI("[%s] dev name is %s",__func__,mfc_dev_name); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("[%s] MFC device node not exists",__func__); - goto error_case1; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR|O_NONBLOCK, 0); - if (hMFCOpen < 0) { - LOGE("[%s] Failed to open MFC device",__func__); - goto error_case1; - } - - pCTX->hMFC = hMFCOpen; - - memset(&cap, 0, sizeof(cap)); - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); - goto error_case2; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - LOGE("[%s] Device does not support capture",__func__); - goto error_case2; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { - LOGE("[%s] Device does not support output",__func__); - goto error_case2; - } - - if (!(cap.capabilities & V4L2_CAP_STREAMING)) { - LOGE("[%s] Device does not support streaming",__func__); - goto error_case2; - } - - pCTX->inter_buff_status = MFC_USE_NONE; - memset(&fmt, 0, sizeof(fmt)); - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; /* Default is set to H264 */ - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed",__func__); - goto error_case2; - } - - pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE; - - memset(&(reqbuf), 0, sizeof (reqbuf)); - reqbuf.count = MFC_DEC_NUM_SRC_BUFS; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_REQBUFS failed",__func__); - goto error_case2; - } - - pCTX->v4l2_dec.mfc_num_src_bufs = reqbuf.count; - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; ++i) { - memset(&(buf), 0, sizeof (buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - buf.m.planes = planes; - buf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYBUF failed",__func__); - goto error_case3; - } - - pCTX->v4l2_dec.mfc_src_bufs[i] = mmap(NULL, buf.m.planes[0].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_dec.mfc_src_bufs[i] == MAP_FAILED) { - LOGE("[%s] mmap failed (%d)",__func__,i); - goto error_case3; - } - } - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - /* set extra DPB size to 5 as default for optimal performce (heuristic method) */ - pCTX->dec_numextradpb = DEFAULT_NUMBER_OF_EXTRA_DPB; - - pCTX->v4l2_dec.bBeingFinalized = 0; - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED; - - pCTX->cacheablebuffer = NO_CACHE; - - for (i = 0; iv4l2_dec.mfc_src_buf_flags[i] = BUF_DEQUEUED; - - pCTX->v4l2_dec.beingUsedIndex = 0; - - return (void *) pCTX; - -error_case3: - for (j = 0; j < i; j++) - munmap(pCTX->v4l2_dec.mfc_src_bufs[j], pCTX->v4l2_dec.mfc_src_bufs_len); - -error_case2: - close(pCTX->hMFC); - -error_case1: - free(pCTX); - - return NULL; -} - -void *SsbSipMfcDecOpenExt(void *value) -{ - _MFCLIB *pCTX; - - pCTX = SsbSipMfcDecOpen(); - - if (pCTX == NULL) - return NULL; - - if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { - pCTX->cacheablebuffer = NO_CACHE; - LOGI("[%s] non cacheable buffer",__func__); - } else { - pCTX->cacheablebuffer = CACHE; - LOGI("[%s] cacheable buffer",__func__); - } - - return (void *)pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) -{ - int ret, i; - _MFCLIB *pCTX; - - enum v4l2_buf_type type; -#ifdef CONFIG_MFC_FPS - LOGI(">>> MFC"); - gettimeofday(&mTS2, NULL); - LOGI(">>> time=%d", mTS2.tv_sec-mTS1.tv_sec); - LOGI(">>> framecount=%d", framecount); - LOGI(">>> 30ms over=%d", over30ms); -#endif - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - } - - if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); - } - - if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { - for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; i++) - munmap(pCTX->v4l2_dec.mfc_src_bufs[i], pCTX->v4l2_dec.mfc_src_bufs_len); - pCTX->inter_buff_status &= ~(MFC_USE_STRM_BUFF); - } - - if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); - } - pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); - } - - close(pCTX->hMFC); - free(pCTX); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) -{ - int packedPB = 0; - _MFCLIB *pCTX; - int ret; - unsigned int i, j; - - struct v4l2_requestbuffers reqbuf; - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - struct v4l2_format fmt; - struct v4l2_pix_format_mplane pix_mp; - struct v4l2_control ctrl; - struct v4l2_crop crop; - enum v4l2_buf_type type; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - pCTX->codecType = codec_type; - - if ((pCTX->codecType == MPEG4_DEC) || (pCTX->codecType == XVID_DEC) || - (pCTX->codecType == FIMV1_DEC) || (pCTX->codecType == FIMV2_DEC) || - (pCTX->codecType == FIMV3_DEC) || (pCTX->codecType == FIMV4_DEC)) - packedPB = isPBPacked(pCTX, Frameleng); - - memset(&fmt, 0, sizeof(fmt)); - - switch (pCTX->codecType) { - case H264_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; - break; - case MPEG4_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; - break; - case H263_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; - break; - case XVID_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_XVID; - break; - case MPEG2_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG12; - break; - case FIMV1_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV1; - fmt.fmt.pix_mp.width = pCTX->fimv1_res.width; - fmt.fmt.pix_mp.height = pCTX->fimv1_res.height; - break; - case FIMV2_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV2; - break; - case FIMV3_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV3; - break; - case FIMV4_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV4; - break; - case VC1_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1; - break; - case VC1RCV_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1_RCV; - break; - default: - LOGE("[%s] Does NOT support the standard (%d)",__func__,pCTX->codecType); - ret = MFC_RET_INVALID_PARAM; - goto error_case1; - } - - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - memset(&qbuf, 0, sizeof(qbuf)); - - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_dec.beingUsedIndex; - qbuf.m.planes = planes; - qbuf.length = 1; - qbuf.m.planes[0].bytesused = Frameleng; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - // Processing the header requires running streamon - // on OUTPUT queue - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_FMT failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pix_mp = fmt.fmt.pix_mp; - pCTX->decOutInfo.buf_width = pix_mp.plane_fmt[0].bytesperline; - pCTX->decOutInfo.buf_height = - pix_mp.plane_fmt[0].sizeimage / pix_mp.plane_fmt[0].bytesperline; - - pCTX->decOutInfo.img_width = pix_mp.width; - pCTX->decOutInfo.img_height = pix_mp.height; - - memset(&crop, 0, sizeof(crop)); - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CROP, &crop); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CROP failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->decOutInfo.crop_left_offset = crop.c.left; - pCTX->decOutInfo.crop_top_offset = crop.c.top; - pCTX->decOutInfo.crop_right_offset = - pix_mp.width - crop.c.width - crop.c.left; - pCTX->decOutInfo.crop_bottom_offset = - pix_mp.height - crop.c.height - crop.c.top; - - memset(&ctrl, 0, sizeof(ctrl)); - ctrl.id = V4L2_CID_CODEC_REQ_NUM_BUFS; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl.value + pCTX->dec_numextradpb; - - /* Cacheable buffer */ - ctrl.id = V4L2_CID_CACHEABLE; - if(pCTX->cacheablebuffer == NO_CACHE) - ctrl.value = 0; - else - ctrl.value = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - memset(&reqbuf, 0, sizeof(reqbuf)); - reqbuf.count = pCTX->v4l2_dec.mfc_num_dst_bufs; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_REQBUFS failed (destination buffers)",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->v4l2_dec.mfc_num_dst_bufs = reqbuf.count; - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = i; - qbuf.m.planes = planes; - qbuf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYBUF failed (destination buffers)",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->v4l2_dec.mfc_dst_bufs_len[0] = qbuf.m.planes[0].length; - pCTX->v4l2_dec.mfc_dst_bufs_len[1] = qbuf.m.planes[1].length; - - pCTX->v4l2_dec.mfc_dst_phys[i][0] = qbuf.m.planes[0].cookie; - pCTX->v4l2_dec.mfc_dst_phys[i][1] = qbuf.m.planes[1].cookie; - - pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, qbuf.m.planes[0].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.m.planes[0].m.mem_offset); - - if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) { - LOGE("[%s] mmap failed (destination buffers (Y))",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_dec.mfc_dst_bufs[i][1] = mmap(NULL, qbuf.m.planes[1].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.m.planes[1].m.mem_offset); - if (pCTX->v4l2_dec.mfc_dst_bufs[i][1] == MAP_FAILED) { - LOGE("[%s] mmap failed (destination buffers (UV))",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } - } - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if(ret != 0) { - LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - return MFC_RET_OK; - -error_case2: - for (j = 0; j < i; j++) { - munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); - munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); - } -error_case1: - SsbSipMfcDecClose(openHandle); - return ret; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) -{ - _MFCLIB *pCTX; - int ret; - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - struct pollfd poll_events; - int poll_state; - -#ifdef CONFIG_MFC_FPS - framecount++; -#endif - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); - return MFC_RET_INVALID_PARAM; - } - -#ifdef CONFIG_MFC_FPS - gettimeofday(&mDec1, NULL); -#endif - pCTX = (_MFCLIB *) openHandle; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLOUT | POLLERR; - poll_events.revents = 0; - - if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { - /* Queue the stream frame */ - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_dec.beingUsedIndex; - qbuf.m.planes = planes; - qbuf.length = 1; - qbuf.m.planes[0].bytesused = lengthBufFill; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = 1; - - /* wait for decoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLOUT) { /* POLLOUT */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret == 0) { - if (qbuf.flags & V4L2_BUF_FLAG_ERROR) - return MFC_RET_DEC_EXE_ERR; - break; - } - } else if (poll_events.revents & POLLERR) { /* POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - return MFC_RET_DEC_EXE_ERR; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - return MFC_RET_DEC_EXE_ERR; - } - } else if (0 > poll_state) { - return MFC_RET_DEC_EXE_ERR; - } - } while (0 == poll_state); - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - - if (ret != 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return MFC_RET_OK; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - - if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - - } else if(pCTX->v4l2_dec.bBeingFinalized == 0) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - - /* Queue the stream frame */ - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_dec.beingUsedIndex; - qbuf.m.planes = planes; - qbuf.length = 1; - qbuf.m.planes[0].bytesused = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - - pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - /* FIXME - wait for decoding */ - do { - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - } while (ret != 0); - - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - } else { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - - if (qbuf.m.planes[0].bytesused == 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return MFC_RET_OK; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - } - - pCTX->decOutInfo.disp_pic_frame_type = (qbuf.flags & (0x7 << 3)); - - switch (pCTX->decOutInfo.disp_pic_frame_type) { - case V4L2_BUF_FLAG_KEYFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 1; - break; - case V4L2_BUF_FLAG_PFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 2; - break; - case V4L2_BUF_FLAG_BFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 3; - break; - default: - pCTX->decOutInfo.disp_pic_frame_type = 0; - break; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - -#ifdef CONFIG_MFC_FPS - gettimeofday(&mDec2, NULL); - if (mDec2.tv_usec-mDec1.tv_usec > 30000) over30ms++; -#endif - return MFC_RET_OK; -} - -#if 0 -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill) -{ - _MFCLIB *pCTX; - int ret; - - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - -#ifdef CONFIG_MFC_FPS - framecount++; -#endif - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { - /* Queue the stream frame */ - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_dec.beingUsedIndex; - qbuf.m.planes = planes; - qbuf.length = 1; - qbuf.m.planes[0].bytesused = lengthBufFill; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - } else if(pCTX->v4l2_dec.bBeingFinalized == 0) { - /* Queue the stream frame */ - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_dec.beingUsedIndex; - qbuf.m.planes = planes; - qbuf.length = 1; - qbuf.m.planes[0].bytesused = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - } - - if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0)) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; - - return MFC_RET_OK; -} - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - int ret; - - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - struct pollfd poll_events; - int poll_state; - - pCTX = (_MFCLIB *) openHandle; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLOUT | POLLERR; - poll_events.revents = 0; - - if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = 1; - - /* wait for decoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLOUT) { /* POLLOUT */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret == 0) { - if (qbuf.flags & V4L2_BUF_FLAG_ERROR) - return MFC_GETOUTBUF_STATUS_NULL; - break; - } - } else if (poll_events.revents & POLLERR) { /* POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - return MFC_GETOUTBUF_STATUS_NULL; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - return MFC_GETOUTBUF_STATUS_NULL; - } - } else if (0 > poll_state) { - return MFC_GETOUTBUF_STATUS_NULL; - } - } while (0 == poll_state); - - pCTX->v4l2_dec.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - - if (ret != 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return SsbSipMfcDecGetOutBuf(pCTX, output_info);; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - - if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - - pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - - /* wait for decoding */ - do { - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - } while (ret != 0); - - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - } else { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = MFC_DEC_NUM_PLANES; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - - if (qbuf.m.planes[0].bytesused == 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return SsbSipMfcDecGetOutBuf(pCTX, output_info);; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1]; - } - - pCTX->decOutInfo.disp_pic_frame_type = (qbuf.flags & (0x7 << 3)); - - switch (pCTX->decOutInfo.disp_pic_frame_type) { - case V4L2_BUF_FLAG_KEYFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 1; - break; - case V4L2_BUF_FLAG_PFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 2; - break; - case V4L2_BUF_FLAG_BFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 3; - break; - default: - pCTX->decOutInfo.disp_pic_frame_type = 0; - break; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - - return SsbSipMfcDecGetOutBuf(pCTX, output_info); -} -#endif - -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) -{ - _MFCLIB *pCTX; - int i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return NULL; - } - - if ((inputBufferSize < 0) || (inputBufferSize > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] inputBufferSize = %d is invalid",__func__, inputBufferSize); - return NULL; - } - - pCTX = (_MFCLIB *) openHandle; - - for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) - if (BUF_DEQUEUED == pCTX->v4l2_dec.mfc_src_buf_flags[i]) - break; - - if (i == MFC_DEC_NUM_SRC_BUFS) { - LOGV("[%s] No buffer is available.",__func__); - return NULL; - } else { - pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_dec.mfc_src_bufs[i]; - /* Set the buffer flag as Enqueued for NB_mode_process*/ - /* FIXME: Check this assignment in case of using New API ExeNb() */ - pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - - return (void *)pCTX->virStrmBuf; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) -{ - _MFCLIB *pCTX; - int i; - - LOGV("[%s] Enter",__func__); - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - for (i = 0; iv4l2_dec.mfc_src_bufs[i] == virInBuf) - break; - - if (i == MFC_DEC_NUM_SRC_BUFS) { - LOGE("[%s] Can not use the buffer",__func__); - return MFC_RET_INVALID_PARAM; - } else { - pCTX->virStrmBuf = (unsigned int)virInBuf; - pCTX->v4l2_dec.beingUsedIndex = i; - pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - LOGV("[%s] Exit idx %d",__func__,pCTX->v4l2_dec.beingUsedIndex); - return MFC_RET_OK; -} - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) -{ - int ret; - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_GETOUTBUF_DISPLAY_END; - } - - pCTX = (_MFCLIB *) openHandle; - - output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; - output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; - - output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; - output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; - - output_info->img_width = pCTX->decOutInfo.img_width; - output_info->img_height= pCTX->decOutInfo.img_height; - - output_info->buf_width = pCTX->decOutInfo.buf_width; - output_info->buf_height= pCTX->decOutInfo.buf_height; - - output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - - output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; - - switch (pCTX->displayStatus) { - case MFC_GETOUTBUF_DISPLAY_ONLY: - case MFC_GETOUTBUF_DISPLAY_DECODING: - case MFC_GETOUTBUF_DISPLAY_END: -#ifdef SSB_UMP - ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.YVirAddr, &output_info->y_cookie); - if (ret) { - LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \ - output_info->y_cookie, pCTX->decOutInfo.YVirAddr); - } - - ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.CVirAddr, &output_info->c_cookie); - if (ret) { - LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \ - output_info->c_cookie, pCTX->decOutInfo.CVirAddr); - } - break; -#endif - case MFC_GETOUTBUF_DECODING_ONLY: - case MFC_GETOUTBUF_CHANGE_RESOL: - break; - default: - return MFC_GETOUTBUF_DISPLAY_END; - } - - return pCTX->displayStatus; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - int ret, i; - - _MFCLIB *pCTX; - struct mfc_dec_fimv1_info *fimv1_res; - - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - struct v4l2_control ctrl; - - enum v4l2_buf_type type; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((value == NULL) && (MFC_DEC_SETCONF_IS_LAST_FRAME !=conf_type)) { - LOGE("[%s] value is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - /* First, process non-ioctl calling settings */ - switch (conf_type) { - case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: - pCTX->dec_numextradpb = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: /* be set before calling SsbSipMfcDecInit */ - fimv1_res = (struct mfc_dec_fimv1_info *)value; - LOGI("fimv1->width = %d\n", fimv1_res->width); - LOGI("fimv1->height = %d\n", fimv1_res->height); - pCTX->fimv1_res.width = (int)(fimv1_res->width); - pCTX->fimv1_res.height = (int)(fimv1_res->height); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_IS_LAST_FRAME: - if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; - return MFC_RET_OK; - } else { - return MFC_RET_FAIL; - } - - case MFC_DEC_SETCONF_DPB_FLUSH: - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { - memset(&qbuf, 0, sizeof(qbuf)); - - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = i; - qbuf.m.planes = planes; - qbuf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - } - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - return MFC_RET_OK; - default: - /* Others will be processed next */ - break; - } - - /* Process ioctl calling settings */ - memset(&ctrl, 0, sizeof(ctrl)); - switch (conf_type) { - case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */ - ctrl.id = V4L2_CID_CODEC_DISPLAY_DELAY; - ctrl.value = *((unsigned int *) value); - break; - - case MFC_DEC_SETCONF_CRC_ENABLE: - ctrl.id = V4L2_CID_CODEC_CRC_ENABLE; - ctrl.value = 1; - break; - - case MFC_DEC_SETCONF_SLICE_ENABLE: - ctrl.id = V4L2_CID_CODEC_SLICE_INTERFACE; - ctrl.value = 1; - break; - - case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */ - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = *((unsigned int*)value); - break; - - case MFC_DEC_SETCONF_POST_ENABLE: - ctrl.id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE; - ctrl.value = *((unsigned int*)value); - break; - - default: - LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); - return MFC_RET_DEC_SET_CONF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - - SSBSIP_MFC_IMG_RESOLUTION *img_resolution; - int ret; - SSBSIP_MFC_CRC_DATA *crc_data; - SSBSIP_MFC_CROP_INFORMATION *crop_information; - struct v4l2_control ctrl; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - switch (conf_type) { - case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: - img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; - img_resolution->width = pCTX->decOutInfo.img_width; - img_resolution->height = pCTX->decOutInfo.img_height; - img_resolution->buf_width = pCTX->decOutInfo.buf_width; - img_resolution->buf_height = pCTX->decOutInfo.buf_height; - break; - - case MFC_DEC_GETCONF_CRC_DATA: - crc_data = (SSBSIP_MFC_CRC_DATA *) value; - - ctrl.id = V4L2_CID_CODEC_CRC_DATA_LUMA; - ctrl.value = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - crc_data->luma0 = ctrl.value; - - ctrl.id = V4L2_CID_CODEC_CRC_DATA_CHROMA; - ctrl.value = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - crc_data->chroma0 = ctrl.value; - - LOGI("[%s] crc_data->luma0=%d",__func__,ctrl.value); - LOGI("[%s] crc_data->chroma0=%d",__func__,ctrl.value); - break; - - case MFC_DEC_GETCONF_FRAME_TAG: - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - printf("Error to do g_ctrl.\n"); - } - *((unsigned int *)value) = ctrl.value; - break; - - case MFC_DEC_GETCONF_CROP_INFO: - crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; - crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - break; - - default: - LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c deleted file mode 100644 index 45888c6..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c +++ /dev/null @@ -1,1206 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include "videodev2.h" - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" - -/* #define LOG_NDEBUG 0 */ -#define LOG_TAG "MFC_ENC_APP" -#include - -#define POLL_ENC_WAIT_TIMEOUT 25 - -#ifndef true -#define true (1) -#endif - -#ifndef false -#define false (0) -#endif - -#define MAX_STREAM_SIZE (2*1024*1024) - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; -static int mfc_dev_node = 7; - -static void getMFCName(char *devicename, int size) -{ - snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); -} - -void SsbSipMfcEncSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcEncOpen(void) -{ - int hMFCOpen; - _MFCLIB *pCTX; - - char mfc_dev_name[64]; - - int ret; - struct v4l2_capability cap; - - getMFCName(mfc_dev_name, 64); - LOGI("[%s] dev name is %s\n",__func__,mfc_dev_name); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("[%s] MFC device node not exists",__func__); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NONBLOCK, 0); - if (hMFCOpen < 0) { - LOGE("[%s] Failed to open MFC device",__func__); - return NULL; - } - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("[%s] malloc failed.",__func__); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - pCTX->hMFC = hMFCOpen; - - memset(&cap, 0, sizeof(cap)); - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - LOGE("[%s] Device does not support capture",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { - LOGE("[%s] Device does not support output",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_STREAMING)) { - LOGE("[%s] Device does not support streaming",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - pCTX->v4l2_enc.bRunning = 0; - /* physical address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 1; - - pCTX->cacheablebuffer = NO_CACHE; - - return (void *)pCTX; -} - -void *SsbSipMfcEncOpenExt(void *value) -{ - _MFCLIB *pCTX; - - pCTX = SsbSipMfcEncOpen(); - if (pCTX == NULL) - return NULL; - - if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { - pCTX->cacheablebuffer = NO_CACHE; - /* physical address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 1; - LOGI("[%s] non cacheable buffer",__func__); - } - else { - pCTX->cacheablebuffer = CACHE; - /* vitual address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 0; - LOGI("[%s] cacheable buffer",__func__); - } - - return (void *)pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) -{ - _MFCLIB *pCTX; - int i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (!pCTX->v4l2_enc.bInputPhyVir) { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); - } - } - - for (i = 0; i < pCTX->v4l2_enc.mfc_num_dst_bufs; i++) - munmap(pCTX->v4l2_enc.mfc_dst_bufs[i], pCTX->v4l2_enc.mfc_dst_bufs_len); - - pCTX->inter_buff_status = MFC_USE_NONE; - - close(pCTX->hMFC); - - free(pCTX); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) -{ - int ret, i, j,index; - _MFCLIB *pCTX; - - enum v4l2_buf_type type; - struct v4l2_format fmt; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - - struct v4l2_buffer buf; - struct v4l2_requestbuffers reqbuf; - - struct v4l2_control ctrl; - - struct pollfd poll_events; - int poll_state; - - struct v4l2_ext_control ext_ctrl_mpeg4[27]; - struct v4l2_ext_control ext_ctrl_h263[19]; - struct v4l2_ext_control ext_ctrl[44]; - struct v4l2_ext_controls ext_ctrls; - - SSBSIP_MFC_ENC_H264_PARAM *h264_arg; - SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; - SSBSIP_MFC_ENC_H263_PARAM *h263_arg; - - if (openHandle == NULL) { - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; - if (mpeg4_arg->codecType == MPEG4_ENC) { - pCTX->codecType= MPEG4_ENC; - pCTX->width = mpeg4_arg->SourceWidth; - pCTX->height = mpeg4_arg->SourceHeight; - pCTX->framemap = mpeg4_arg->FrameMap; - } else { - h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; - if (h263_arg->codecType == H263_ENC) { - pCTX->codecType = H263_ENC; - pCTX->width = h263_arg->SourceWidth; - pCTX->height = h263_arg->SourceHeight; - pCTX->framemap = h263_arg->FrameMap; - } else { - h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; - if (h264_arg->codecType == H264_ENC) { - pCTX->codecType = H264_ENC; - pCTX->width = h264_arg->SourceWidth; - pCTX->height = h264_arg->SourceHeight; - pCTX->framemap = h264_arg->FrameMap; - } else { - LOGE("[%s] Undefined codec type \n",__func__); - ret = MFC_RET_INVALID_PARAM; - goto error_case1; - } - } - } - - switch (pCTX->codecType) { - case MPEG4_ENC: - ext_ctrl_mpeg4[0].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE; - ext_ctrl_mpeg4[0].value = mpeg4_arg->ProfileIDC; - ext_ctrl_mpeg4[1].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL; - ext_ctrl_mpeg4[1].value = mpeg4_arg->LevelIDC; - ext_ctrl_mpeg4[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl_mpeg4[2].value = mpeg4_arg->IDRPeriod; - ext_ctrl_mpeg4[3].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL; - ext_ctrl_mpeg4[3].value = mpeg4_arg->DisableQpelME; - - ext_ctrl_mpeg4[4].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl_mpeg4[4].value = mpeg4_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ - if (mpeg4_arg->SliceMode == 0) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = 1; /* default */ - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 1900; /* default */ - } else if (mpeg4_arg->SliceMode == 1) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = mpeg4_arg->SliceArgument; - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 1900; /* default */ - } else if (mpeg4_arg->SliceMode == 3) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = 1; /* default */ - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = mpeg4_arg->SliceArgument; - } - /* - It should be set using mpeg4_arg->NumberBFrames after being handled by appl. - */ - ext_ctrl_mpeg4[7].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES; - ext_ctrl_mpeg4[7].value = mpeg4_arg->NumberBFrames; - ext_ctrl_mpeg4[8].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl_mpeg4[8].value = mpeg4_arg->RandomIntraMBRefresh; - - ext_ctrl_mpeg4[9].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl_mpeg4[9].value = mpeg4_arg->PadControlOn; - ext_ctrl_mpeg4[10].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl_mpeg4[10].value = mpeg4_arg->LumaPadVal; - ext_ctrl_mpeg4[11].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl_mpeg4[11].value = mpeg4_arg->CbPadVal; - ext_ctrl_mpeg4[12].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl_mpeg4[12].value = mpeg4_arg->CrPadVal; - - ext_ctrl_mpeg4[13].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl_mpeg4[13].value = mpeg4_arg->EnableFRMRateControl; - ext_ctrl_mpeg4[14].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES; - ext_ctrl_mpeg4[14].value = mpeg4_arg->TimeIncreamentRes; - ext_ctrl_mpeg4[15].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA; - ext_ctrl_mpeg4[15].value = mpeg4_arg->VopTimeIncreament; - ext_ctrl_mpeg4[16].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - ext_ctrl_mpeg4[16].value = mpeg4_arg->Bitrate; - - ext_ctrl_mpeg4[17].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP; - ext_ctrl_mpeg4[17].value = mpeg4_arg->FrameQp; - ext_ctrl_mpeg4[18].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP; - ext_ctrl_mpeg4[18].value = mpeg4_arg->FrameQp_P; - ext_ctrl_mpeg4[19].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP; - ext_ctrl_mpeg4[19].value = mpeg4_arg->FrameQp_B; - - ext_ctrl_mpeg4[20].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP; - ext_ctrl_mpeg4[20].value = mpeg4_arg->QSCodeMax; - ext_ctrl_mpeg4[21].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP; - ext_ctrl_mpeg4[21].value = mpeg4_arg->QSCodeMin; - ext_ctrl_mpeg4[22].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl_mpeg4[22].value = mpeg4_arg->CBRPeriodRf; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl_mpeg4[24].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl_mpeg4[24].value = 0; - - ext_ctrl_mpeg4[25].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl_mpeg4[25].value = 0; - - ext_ctrl_mpeg4[26].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; - ext_ctrl_mpeg4[26].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - break; - - case H263_ENC: - ext_ctrl_h263[0].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl_h263[0].value = h263_arg->IDRPeriod; - - ext_ctrl_h263[1].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl_h263[1].value = h263_arg->SliceMode; /* 0: one, Check is needed if h264 support multi-slice */ - - ext_ctrl_h263[2].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl_h263[2].value = h263_arg->RandomIntraMBRefresh; - - ext_ctrl_h263[3].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl_h263[3].value = h263_arg->PadControlOn; - ext_ctrl_h263[4].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl_h263[4].value = h263_arg->LumaPadVal; - ext_ctrl_h263[5].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl_h263[5].value = h263_arg->CbPadVal; - ext_ctrl_h263[6].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl_h263[6].value = h263_arg->CrPadVal; - - ext_ctrl_h263[7].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl_h263[7].value = h263_arg->EnableFRMRateControl; - - ext_ctrl_h263[8].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE; - ext_ctrl_h263[8].value = h263_arg->FrameRate; - - ext_ctrl_h263[9].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - ext_ctrl_h263[9].value = h263_arg->Bitrate; - - ext_ctrl_h263[10].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP; - ext_ctrl_h263[10].value = h263_arg->FrameQp; - ext_ctrl_h263[11].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP; - ext_ctrl_h263[11].value = h263_arg->FrameQp_P; - - ext_ctrl_h263[12].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP; - ext_ctrl_h263[12].value = h263_arg->QSCodeMax; - ext_ctrl_h263[13].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP; - ext_ctrl_h263[13].value = h263_arg->QSCodeMin; - ext_ctrl_h263[14].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl_h263[14].value = h263_arg->CBRPeriodRf; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE== pCTX->enc_frameskip) { - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl_h263[16].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl_h263[16].value = 0; - - ext_ctrl_h263[17].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl_h263[17].value = 0; - - ext_ctrl_h263[18].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; - ext_ctrl_h263[18].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - break; - - case H264_ENC: - ext_ctrl[0].id = V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE; - ext_ctrl[0].value = h264_arg->ProfileIDC; - ext_ctrl[1].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL; - ext_ctrl[1].value = h264_arg->LevelIDC; - ext_ctrl[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl[2].value = h264_arg->IDRPeriod; - ext_ctrl[3].id = V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC; - ext_ctrl[3].value = h264_arg->NumberReferenceFrames; - ext_ctrl[4].id = V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P; - ext_ctrl[4].value = h264_arg->NumberRefForPframes; - ext_ctrl[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl[5].value = h264_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ - if (h264_arg->SliceMode == 0) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = 1; /* default */ - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 1900; /* default */ - } else if (h264_arg->SliceMode == 1) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = h264_arg->SliceArgument; - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 1900; /* default */ - } else if (h264_arg->SliceMode == 3) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = 1; /* default */ - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = h264_arg->SliceArgument; - } - /* - It should be set using h264_arg->NumberBFrames after being handled by appl. - */ - ext_ctrl[8].id = V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES; - ext_ctrl[8].value = h264_arg->NumberBFrames; - ext_ctrl[9].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE; - ext_ctrl[9].value = h264_arg->LoopFilterDisable; - ext_ctrl[10].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA; - ext_ctrl[10].value = h264_arg->LoopFilterAlphaC0Offset; - ext_ctrl[11].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA; - ext_ctrl[11].value = h264_arg->LoopFilterBetaOffset; - ext_ctrl[12].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE; - ext_ctrl[12].value = h264_arg->SymbolMode; - ext_ctrl[13].id = V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE; - ext_ctrl[13].value = h264_arg->PictureInterlace; - ext_ctrl[14].id = V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM; - ext_ctrl[14].value = h264_arg->Transform8x8Mode; - ext_ctrl[15].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl[15].value = h264_arg->RandomIntraMBRefresh; - ext_ctrl[16].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl[16].value = h264_arg->PadControlOn; - ext_ctrl[17].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl[17].value = h264_arg->LumaPadVal; - ext_ctrl[18].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl[18].value = h264_arg->CbPadVal; - ext_ctrl[19].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl[19].value = h264_arg->CrPadVal; - ext_ctrl[20].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl[20].value = h264_arg->EnableFRMRateControl; - ext_ctrl[21].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE; - ext_ctrl[21].value = h264_arg->EnableMBRateControl; - ext_ctrl[22].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE; - ext_ctrl[22].value = h264_arg->FrameRate; - ext_ctrl[23].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - /* FIXME temporary fix */ - if (h264_arg->Bitrate) - ext_ctrl[23].value = h264_arg->Bitrate; - else - ext_ctrl[23].value = 1; /* just for testing Movi studio */ - ext_ctrl[24].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP; - ext_ctrl[24].value = h264_arg->FrameQp; - ext_ctrl[25].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP; - ext_ctrl[25].value = h264_arg->FrameQp_P; - ext_ctrl[26].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP; - ext_ctrl[26].value = h264_arg->FrameQp_B; - ext_ctrl[27].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP; - ext_ctrl[27].value = h264_arg->QSCodeMax; - ext_ctrl[28].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP; - ext_ctrl[28].value = h264_arg->QSCodeMin; - ext_ctrl[29].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl[29].value = h264_arg->CBRPeriodRf; - ext_ctrl[30].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK; - ext_ctrl[30].value = h264_arg->DarkDisable; - ext_ctrl[31].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH; - ext_ctrl[31].value = h264_arg->SmoothDisable; - ext_ctrl[32].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC; - ext_ctrl[32].value = h264_arg->StaticDisable; - ext_ctrl[33].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY; - ext_ctrl[33].value = h264_arg->ActivityDisable; - - /* doesn't have to be set */ - ext_ctrl[34].id = V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP; - ext_ctrl[34].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[35].id = V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD; - ext_ctrl[35].value = 10; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if(V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE== pCTX->enc_frameskip) { - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl[37].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl[37].value = 0; - - ext_ctrl[38].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl[38].value = 0; /* 0: seperated header - 1: header + first frame */ - - ext_ctrl[39].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; - ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - - ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE; - ext_ctrl[40].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC; - ext_ctrl[41].value = 0; - ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH; - ext_ctrl[42].value = 0; - ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT; - ext_ctrl[43].value = 0; - - break; - - default: - LOGE("[%s] Undefined codec type",__func__); - ret = MFC_RET_INVALID_PARAM; - goto error_case1; - } - - ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC; - if (pCTX->codecType == MPEG4_ENC) { - ext_ctrls.count = 27; - ext_ctrls.controls = ext_ctrl_mpeg4; - } else if (pCTX->codecType == H264_ENC) { - ext_ctrls.count = 44; - ext_ctrls.controls = ext_ctrl; - } else if (pCTX->codecType == H263_ENC) { - ext_ctrls.count = 19; - ext_ctrls.controls = ext_ctrl_h263; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_S_EXT_CTRLS, &ext_ctrls); - if (ret != 0) { - LOGE("[%s] Failed to set extended controls",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - fmt.fmt.pix_mp.width = pCTX->width; - fmt.fmt.pix_mp.height = pCTX->height; - fmt.fmt.pix_mp.num_planes = 2; - fmt.fmt.pix_mp.plane_fmt[0].bytesperline = Align(fmt.fmt.pix_mp.width, 128); - fmt.fmt.pix_mp.plane_fmt[1].bytesperline = Align(fmt.fmt.pix_mp.width, 128); - - if (NV12_TILE == pCTX->framemap) { - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 64x32 Tiles */ - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = - Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height, 32), 8192); /* tiled mode */ - fmt.fmt.pix_mp.plane_fmt[1].sizeimage = - Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height >> 1, 32), 8192); /* tiled mode */ - } else { /* NV12_LINEAR (default) */ - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = - Align((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height), 2048); /* linear mode, 2K align */ - fmt.fmt.pix_mp.plane_fmt[1].sizeimage = - Align((fmt.fmt.pix_mp.width * (fmt.fmt.pix_mp.height >> 1)), 2048); /* linear mode, 2K align */ - } - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed on MFC output stream",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* capture (dst) */ - memset(&fmt, 0, sizeof(fmt)); - - switch (pCTX->codecType) { - case H264_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; - break; - case MPEG4_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; - break; - case H263_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; - break; - default: - LOGE("[%s] Codec has not been recognised",__func__); - return MFC_RET_ENC_INIT_FAIL; - } - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed on MFC output stream",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* cacheable buffer */ - ctrl.id = V4L2_CID_CACHEABLE; - if (pCTX->cacheablebuffer == NO_CACHE) - ctrl.value = 0; - else - ctrl.value = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* Initialize streams for input */ - memset(&reqbuf, 0, sizeof(reqbuf)); - reqbuf.count = MFC_ENC_NUM_SRC_BUFS; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - if (pCTX->v4l2_enc.bInputPhyVir) - reqbuf.memory = V4L2_MEMORY_USERPTR; - else - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] Reqbufs src ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - pCTX->v4l2_enc.mfc_num_src_bufs = reqbuf.count; - - if (!pCTX->v4l2_enc.bInputPhyVir) { - /* Then the buffers have to be queried and mmaped */ - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; ++i) { - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - buf.m.planes = planes; - buf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); - if (ret != 0) { - LOGE("[%s] Querybuf src ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_src_bufs_len[0] = buf.m.planes[0].length; - pCTX->v4l2_enc.mfc_src_bufs_len[1] = buf.m.planes[1].length; - - pCTX->v4l2_enc.mfc_src_phys[i][0] = buf.m.planes[0].cookie; - pCTX->v4l2_enc.mfc_src_phys[i][1] = buf.m.planes[1].cookie; - - pCTX->v4l2_enc.mfc_src_bufs[i][0] = - mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == MAP_FAILED) { - LOGE("[%s] Mmap on src buffer (0) failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_src_bufs[i][1] = - mmap(NULL, buf.m.planes[1].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); - if (pCTX->v4l2_enc.mfc_src_bufs[i][1] == MAP_FAILED) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - LOGE("[%s] Mmap on src buffer (1) failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - } - } else - LOGV("[%s] Camera Phys src buf %d",__func__,reqbuf.count); - - for (i = 0; iv4l2_enc.mfc_num_src_bufs; i++) - pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_DEQUEUED; - - pCTX->v4l2_enc.beingUsedIndex = 0; - - pCTX->sizeFrmBuf.luma = (unsigned int)(pCTX->width * pCTX->height); - pCTX->sizeFrmBuf.chroma = (unsigned int)((pCTX->width * pCTX->height) >> 1); - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - /* Initialize stream for output */ - memset(&reqbuf, 0, sizeof(reqbuf)); - reqbuf.count = MFC_ENC_MAX_DST_BUFS; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] Reqbufs dst ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_num_dst_bufs = reqbuf.count; - - for (i = 0; ihMFC, VIDIOC_QUERYBUF, &buf); - if (ret != 0) { - LOGE("[%s] Querybuf dst ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - pCTX->v4l2_enc.mfc_dst_bufs_len = buf.m.planes[0].length; - pCTX->v4l2_enc.mfc_dst_bufs[i] = - mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_enc.mfc_dst_bufs[i] == MAP_FAILED) { - LOGE("[%s] Mmap on dst buffer failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } - - pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, VIDIOC_STREAMON failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.m.planes = planes; - buf.length = 1; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLIN | POLLERR; - poll_events.revents = 0; - - /* wait for header encoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLIN) { /* POLLIN */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &buf); - if (ret == 0) - break; - } else if(poll_events.revents & POLLERR) { /*POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } else if(0 > poll_state) { - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } while (0 == poll_state); - - pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused; - pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[buf.index]; - - /* stream dequeued index */ - index = buf.index; - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = index; - buf.m.planes = planes; - buf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - LOGV("[%s] Strm out idx %d",__func__,index); - - return MFC_RET_OK; -error_case3: - for (j = 0; j < i; j++) - munmap(pCTX->v4l2_enc.mfc_dst_bufs[j], pCTX->v4l2_enc.mfc_dst_bufs_len); - - i = pCTX->v4l2_enc.mfc_num_src_bufs; -error_case2: - if (!pCTX->v4l2_enc.bInputPhyVir) { - for (j = 0; j < i; j++) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[j][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - munmap(pCTX->v4l2_enc.mfc_src_bufs[j][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); - } - } -error_case1: - return ret; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - _MFCLIB *pCTX; - int i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->v4l2_enc.bInputPhyVir) { - input_info->YPhyAddr = (void*)0; - input_info->CPhyAddr = (void*)0; - input_info->YVirAddr = (void*)0; - input_info->CVirAddr = (void*)0; - - if (NV12_TILE == pCTX->framemap) { - /* 4:2:0, 2 Planes, 64x32 Tiles */ - input_info->YSize = Align(Align(pCTX->width, 128) * Align(pCTX->height, 32), 8192); /* tiled mode */ - input_info->CSize = Align(Align(pCTX->width, 128) * Align(pCTX->height >> 1, 32), 8192); /* tiled mode */ - } else { /* NV12_LINEAR (default) */ - /* 4:2:0, 2 Planes, linear */ - input_info->YSize = Align(Align(pCTX->width, 16) * Align(pCTX->height, 16), 2048); /* width = 16B, height = 16B align */ - input_info->CSize = Align(Align(pCTX->width, 16) * Align(pCTX->height >> 1, 8), 2048); /* width = 16B, height = 8B align */ - } - } else { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) - if (BUF_DEQUEUED == pCTX->v4l2_enc.mfc_src_buf_flags[i]) - break; - - if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { - LOGV("[%s] No buffer is available.",__func__); - return MFC_RET_ENC_GET_INBUF_FAIL; - } else { - /* FIXME check this for correct physical address */ - input_info->YPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][0]; - input_info->CPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][1]; - input_info->YVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][0]; - input_info->CVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][1]; - input_info->YSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[0]; - input_info->CSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[1]; - - pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - } - LOGV("[%s] Input Buffer idx %d",__func__,i); - return MFC_RET_OK; -} - - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - _MFCLIB *pCTX; - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - int ret,i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - memset(&qbuf, 0, sizeof(qbuf)); - if (pCTX->v4l2_enc.bInputPhyVir) { - qbuf.memory = V4L2_MEMORY_USERPTR; - qbuf.index = pCTX->v4l2_enc.beingUsedIndex; - planes[0].m.userptr = (unsigned long)input_info->YPhyAddr; - planes[0].length = input_info->YSize; - planes[0].bytesused = input_info->YSize; - planes[1].m.userptr = (unsigned long)input_info->CPhyAddr; - planes[1].length = input_info->CSize; - planes[1].bytesused = input_info->CSize; - - /* FIXME, this is only for case of not using B frame, - Camera side should know which buffer is queued() refering to index of - MFC dqbuf() */ - pCTX->v4l2_enc.beingUsedIndex++; - pCTX->v4l2_enc.beingUsedIndex %= MFC_ENC_NUM_SRC_BUFS; - LOGV("[%s] Phy Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); - } else { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) - if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == input_info->YVirAddr) - break; - - if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { - LOGE("[%s] Can not use the buffer",__func__); - return MFC_RET_INVALID_PARAM; - } else { - pCTX->v4l2_enc.beingUsedIndex = i; - //pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_enc.beingUsedIndex; - planes[0].bytesused = pCTX->width * pCTX->height; - planes[1].bytesused = (pCTX->width * pCTX->height) >> 1; - LOGV("[%s] Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); - } - - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.m.planes = planes; - qbuf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_SET_INBUF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->v4l2_enc.bRunning == 0) { - pCTX->encodedHeaderSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; - output_info->dataSize = 0; - } else { - output_info->dataSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; - } - - output_info->headerSize = pCTX->encodedHeaderSize; - output_info->frameType = pCTX->encodedframeType; - output_info->StrmPhyAddr = (void *)0; - output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; - output_info->encodedYPhyAddr = (void*)0; - output_info->encodedCPhyAddr = (void*)0; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) -{ - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_ENC_SET_OUTBUF_FAIL; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) -{ - int ret; - int dequeued_index; - int loopcnt = 0; - _MFCLIB *pCTX; - - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - enum v4l2_buf_type type; - - struct v4l2_control ctrl; - - struct pollfd poll_events; - int poll_state; - - LOGV("[%s] Enter \n",__func__); - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = pCTX->inframetag; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - if (pCTX->v4l2_enc.bRunning == 0) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - pCTX->v4l2_enc.bRunning = 1; - } - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = 1; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLIN | POLLERR; - poll_events.revents = 0; - - /* wait for encoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLIN) { /* POLLIN */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret == 0) - break; - } else if (poll_events.revents & POLLERR) { /* POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - return MFC_RET_ENC_EXE_ERR; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - return MFC_RET_ENC_EXE_ERR; - } - } else if (0 > poll_state) { - LOGE("[%s] poll() Encoder POLL Timeout 0x%x\n",__func__, poll_events.revents); - return MFC_RET_ENC_EXE_ERR; - } - loopcnt++; - } while ((0 == poll_state) && (loopcnt < 5)); - - if (pCTX->v4l2_enc.bRunning != 0) { - pCTX->encodedframeType = (qbuf.flags & 0x18) >> 3; /* encoded frame type */ - - LOGV("[%s] encoded frame type = %d\n",__func__, pCTX->encodedframeType); - switch (pCTX->encodedframeType) { - case 1: - pCTX->encodedframeType = MFC_FRAME_TYPE_I_FRAME; - break; - case 2: - pCTX->encodedframeType = MFC_FRAME_TYPE_P_FRAME; - break; - case 4: - pCTX->encodedframeType = MFC_FRAME_TYPE_B_FRAME; - break; - default: - LOGE("[%s] VIDIOC_DQBUF failed, encoded frame type is wrong",__func__); - } - } - - dequeued_index = qbuf.index; - - if (qbuf.m.planes[0].bytesused > 0) { /* FIXME later */ - pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = qbuf.m.planes[0].bytesused; - } - - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - pCTX->outframetagtop = ctrl.value; - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = dequeued_index; - qbuf.m.planes = planes; - qbuf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - if (pCTX->v4l2_enc.bRunning != 0) { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - if (pCTX->v4l2_enc.bInputPhyVir) - qbuf.memory = V4L2_MEMORY_USERPTR; - else - qbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - } - pCTX->v4l2_enc.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; - - /* Update context stream buffer address */ - pCTX->virStrmBuf = pCTX->v4l2_enc.mfc_dst_bufs[dequeued_index]; - LOGV("[%s] Strm out idx %d",__func__,dequeued_index); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - switch (conf_type) { - case MFC_ENC_SETCONF_FRAME_TAG: - pCTX->inframetag = *((unsigned int *)value); - return MFC_RET_OK; - - case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: - pCTX->enc_frameskip = *((int *)value); - return MFC_RET_OK; -#if 0 - case MFC_ENC_SETCONF_VUI_INFO: - vui_info = *((struct mfc_enc_vui_info *) value); - EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); - EncArg.args.set_config.in_config_value[1] = 0; - break; - - case MFC_ENC_SETCONF_HIER_P: - hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); - EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp); - EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp); - EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp); - break; - - case MFC_ENC_SETCONF_I_PERIOD: -#endif - default: - LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - - pCTX = (_MFCLIB *) openHandle; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - switch (conf_type) { - case MFC_ENC_GETCONF_FRAME_TAG: - *((unsigned int *)value) = pCTX->outframetagtop; - break; - - default: - LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} - diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h deleted file mode 100644 index b85256b..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SSBSIP_MFC_API_H_ -#define _SSBSIP_MFC_API_H_ - -/*--------------------------------------------------------------------------------*/ -/* Definition */ -/*--------------------------------------------------------------------------------*/ -#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) -#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) - -#define SUPPORT_1080P 1 - -#if SUPPORT_1080P -#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ -#else -#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) -#endif - -#define SAMSUNG_MFC_DEV_NAME "/dev/video" - -#define SSBSIP_MFC_OK (1) -#define SSBSIP_MFC_FAIL (0) - -/*--------------------------------------------------------------------------------*/ -/* Structure and Type */ -/*--------------------------------------------------------------------------------*/ -typedef enum { - H264_DEC, - VC1_DEC, /* VC1 advaced Profile decoding */ - MPEG4_DEC, - XVID_DEC, - MPEG1_DEC, - MPEG2_DEC, - H263_DEC, - VC1RCV_DEC, /* VC1 simple/main profile decoding */ - FIMV1_DEC, - FIMV2_DEC, - FIMV3_DEC, - FIMV4_DEC, - H264_ENC, - MPEG4_ENC, - H263_ENC, - UNKNOWN_TYPE -} SSBSIP_MFC_CODEC_TYPE; - -typedef enum { - DONT_CARE = 0, - I_FRAME = 1, - NOT_CODED = 2 -} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; - -typedef enum { - NV12_LINEAR = 0, - NV12_TILE, - NV21_LINEAR -} SSBSIP_MFC_INSTRM_MODE_TYPE; - -typedef enum { - NO_CACHE = 0, - CACHE = 1 -} SSBIP_MFC_BUFFER_TYPE; - -typedef enum { - MFC_DEC_SETCONF_POST_ENABLE = 1, - MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, - MFC_DEC_SETCONF_DISPLAY_DELAY, - MFC_DEC_SETCONF_IS_LAST_FRAME, - MFC_DEC_SETCONF_SLICE_ENABLE, - MFC_DEC_SETCONF_CRC_ENABLE, - MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, - MFC_DEC_SETCONF_FRAME_TAG, - MFC_DEC_GETCONF_CRC_DATA, - MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, - MFC_DEC_GETCONF_CROP_INFO, - MFC_DEC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, - MFC_DEC_SETCONF_DPB_FLUSH, - MFC_DEC_SETCONF_PIXEL_CACHE, - MFC_DEC_GETCONF_WIDTH_HEIGHT -} SSBSIP_MFC_DEC_CONF; - -typedef enum { - MFC_ENC_SETCONF_FRAME_TYPE = 100, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - MFC_ENC_SETCONF_FRAME_TAG, - MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, - MFC_ENC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_ENC_SETCONF_VUI_INFO, - MFC_ENC_SETCONF_I_PERIOD, - MFC_ENC_SETCONF_HIER_P -} SSBSIP_MFC_ENC_CONF; - -typedef enum { - MFC_GETOUTBUF_STATUS_NULL = 0, - MFC_GETOUTBUF_DECODING_ONLY = 1, - MFC_GETOUTBUF_DISPLAY_DECODING, - MFC_GETOUTBUF_DISPLAY_ONLY, - MFC_GETOUTBUF_DISPLAY_END, - MFC_GETOUTBUF_CHANGE_RESOL -} SSBSIP_MFC_DEC_OUTBUF_STATUS; - -typedef enum { - MFC_FRAME_TYPE_NOT_CODED, - MFC_FRAME_TYPE_I_FRAME, - MFC_FRAME_TYPE_P_FRAME, - MFC_FRAME_TYPE_B_FRAME, - MFC_FRAME_TYPE_OTHERS -} SSBSIP_MFC_FRAME_TYPE; - -typedef enum { - MFC_RET_OK = 1, - MFC_RET_FAIL = -1000, - MFC_RET_OPEN_FAIL = -1001, - MFC_RET_CLOSE_FAIL = -1002, - - MFC_RET_DEC_INIT_FAIL = -2000, - MFC_RET_DEC_EXE_TIME_OUT = -2001, - MFC_RET_DEC_EXE_ERR = -2002, - MFC_RET_DEC_GET_INBUF_FAIL = -2003, - MFC_RET_DEC_SET_INBUF_FAIL = -2004, - MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, - MFC_RET_DEC_GET_CONF_FAIL = -2006, - MFC_RET_DEC_SET_CONF_FAIL = -2007, - - MFC_RET_ENC_INIT_FAIL = -3000, - MFC_RET_ENC_EXE_TIME_OUT = -3001, - MFC_RET_ENC_EXE_ERR = -3002, - MFC_RET_ENC_GET_INBUF_FAIL = -3003, - MFC_RET_ENC_SET_INBUF_FAIL = -3004, - MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, - MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, - MFC_RET_ENC_GET_CONF_FAIL = -3007, - MFC_RET_ENC_SET_CONF_FAIL = -3008, - - MFC_RET_INVALID_PARAM = -4000 -} SSBSIP_MFC_ERROR_CODE; - -typedef struct { - void *YPhyAddr; /* [OUT] physical address of Y */ - void *CPhyAddr; /* [OUT] physical address of CbCr */ - void *YVirAddr; /* [OUT] virtual address of Y */ - void *CVirAddr; /* [OUT] virtual address of CbCr */ - - int img_width; /* [OUT] width of real image */ - int img_height; /* [OUT] height of real image */ - int buf_width; /* [OUT] width aligned to 16 */ - int buf_height; /* [OUT] height alighed to 16 */ - - int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ - int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ - int consumedByte; /* [OUT] the number of byte consumed during decoding */ - int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ - int crop_top_offset; /* [OUT] crop information, top_offset */ - int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ - int crop_left_offset; /* [OUT] crop information, left_offset */ - int crop_right_offset; /* [OUT] crop information, right_offset */ - int disp_pic_frame_type; /* [OUT] display picture frame type information */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_DEC_OUTPUT_INFO; - -typedef struct { - void *YPhyAddr; /* [IN/OUT] physical address of Y */ - void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ - void *YVirAddr; /* [IN/OUT] virtual address of Y */ - void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ - int YSize; /* [IN/OUT] input size of Y data */ - int CSize; /* [IN/OUT] input size of CbCr data */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_INPUT_INFO; - -typedef struct { - unsigned int dataSize; /* [OUT] encoded data size(without header) */ - unsigned int headerSize; /* [OUT] encoded header size */ - unsigned int frameType; /* [OUT] frame type of encoded stream */ - void *StrmPhyAddr; /* [OUT] physical address of Y */ - void *StrmVirAddr; /* [OUT] virtual address of Y */ - void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ - void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ - - /* C210 UMP feature */ - unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ - unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ - unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_OUTPUT_INFO; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - - /* H.264 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int NumberReferenceFrames; /* [IN] The number of reference pictures used */ - int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ - int LoopFilterDisable; /* [IN] disable the loop filter */ - int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ - int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ - int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ - int PictureInterlace; /* [IN] Enables the interlace mode */ - int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ - int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ - int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ - int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ - int StaticDisable; /* [IN] Disable adaptive rate control on static region */ - int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ -} SSBSIP_MFC_ENC_H264_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - - /* MPEG4 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int TimeIncreamentRes; /* [IN] frame rate */ - int VopTimeIncreament; /* [IN] frame rate */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ -} SSBSIP_MFC_ENC_MPEG4_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - - /* H.263 specific parameters */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ -} SSBSIP_MFC_ENC_H263_PARAM; - -typedef struct { - int width; - int height; - int buf_width; - int buf_height; -} SSBSIP_MFC_IMG_RESOLUTION; - -typedef struct { - int crop_top_offset; - int crop_bottom_offset; - int crop_left_offset; - int crop_right_offset; -} SSBSIP_MFC_CROP_INFORMATION; - -#ifdef __cplusplus -extern "C" { -#endif - -/*--------------------------------------------------------------------------------*/ -/* Decoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcDecOpen(void); -void *SsbSipMfcDecOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); -//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); -//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); - -#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); -#else -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); -#endif - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); - -/*--------------------------------------------------------------------------------*/ -/* Encoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcEncOpen(void); -void *SsbSipMfcEncOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h deleted file mode 100644 index b8e96ab..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_ERRNO_H -#define __MFC_ERRNO_H __FILE__ - -enum mfc_ret_code { - MFC_OK = 1, - MFC_FAIL = -1000, - MFC_OPEN_FAIL = -1001, - MFC_CLOSE_FAIL = -1002, - - MFC_DEC_INIT_FAIL = -2000, - MFC_DEC_EXE_TIME_OUT = -2001, - MFC_DEC_EXE_ERR = -2002, - MFC_DEC_GET_INBUF_FAIL = 2003, - MFC_DEC_SET_INBUF_FAIL = 2004, - MFC_DEC_GET_OUTBUF_FAIL = -2005, - MFC_DEC_GET_CONF_FAIL = -2006, - MFC_DEC_SET_CONF_FAIL = -2007, - - MFC_ENC_INIT_FAIL = -3000, - MFC_ENC_EXE_TIME_OUT = -3001, - MFC_ENC_EXE_ERR = -3002, - MFC_ENC_GET_INBUF_FAIL = -3003, - MFC_ENC_SET_INBUF_FAIL = -3004, - MFC_ENC_GET_OUTBUF_FAIL = -3005, - MFC_ENC_SET_OUTBUF_FAIL = -3006, - MFC_ENC_GET_CONF_FAIL = -3007, - MFC_ENC_SET_CONF_FAIL = -3008, - - MFC_STATE_INVALID = -4000, - MFC_DEC_HEADER_FAIL = -4001, - MFC_DEC_INIT_BUF_FAIL = -4002, - MFC_ENC_HEADER_FAIL = -5000, - MFC_ENC_PARAM_FAIL = -5001, - MFC_FRM_BUF_SIZE_FAIL = -6000, - MFC_FW_LOAD_FAIL = -6001, - MFC_FW_INIT_FAIL = -6002, - MFC_INST_NUM_EXCEEDED_FAIL = -6003, - MFC_MEM_ALLOC_FAIL = -6004, - MFC_MEM_INVALID_ADDR_FAIL = -6005, - MFC_MEM_MAPPING_FAIL = -6006, - MFC_GET_CONF_FAIL = -6007, - MFC_SET_CONF_FAIL = -6008, - MFC_INVALID_PARAM_FAIL = -6009, - MFC_API_FAIL = -9000, - - MFC_CMD_FAIL = -1003, - MFC_SLEEP_FAIL = -1010, - MFC_WAKEUP_FAIL = -1020, - - MFC_CLK_ON_FAIL = -1030, - MFC_CLK_OFF_FAIL = -1030, - MFC_PWR_ON_FAIL = -1040, - MFC_PWR_OFF_FAIL = -1041, -}; - -#endif /* __MFC_ERRNO_H */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h deleted file mode 100644 index b7289c4..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_INTERFACE_H -#define __MFC_INTERFACE_H - -#include "mfc_errno.h" -#include "SsbSipMfcApi.h" - -#define IOCTL_MFC_DEC_INIT (0x00800001) -#define IOCTL_MFC_ENC_INIT (0x00800002) -#define IOCTL_MFC_DEC_EXE (0x00800003) -#define IOCTL_MFC_ENC_EXE (0x00800004) - -#define IOCTL_MFC_GET_IN_BUF (0x00800010) -#define IOCTL_MFC_FREE_BUF (0x00800011) -#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) -#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) -#define IOCTL_MFC_SET_IN_BUF (0x00800018) - -#define IOCTL_MFC_SET_CONFIG (0x00800101) -#define IOCTL_MFC_GET_CONFIG (0x00800102) - -#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) - -/* MFC H/W support maximum 32 extra DPB. */ -#define MFC_MAX_EXTRA_DPB 5 -#define MFC_MAX_DISP_DELAY 0xF - -#define MFC_LIB_VER_MAJOR 1 -#define MFC_LIB_VER_MINOR 00 - -#define BUF_L_UNIT (1024) -#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) - -#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ -#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */ -#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */ - -#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ -#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */ -#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */ - -enum inst_type { - DECODER = 0x1, - ENCODER = 0x2, -}; - -typedef enum { - MFC_UNPACKED_PB = 0, - MFC_PACKED_PB = 1 -} mfc_packed_mode; - -typedef enum { - SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0, - SSBSIP_MFC_LAST_FRAME_RECEIVED = 1, - SSBSIP_MFC_LAST_FRAME_PROCESSED = 2 -} SSBSIP_MFC_LAST_FRAME_STATUS; - -typedef enum { - MFC_USE_NONE = 0x0000, - MFC_USE_YUV_BUFF = 0x0001, - MFC_USE_STRM_BUFF = 0x0010, - MFC_USE_SRC_STREAMON = 0x0100, - MFC_USE_DST_STREAMON = 0x1000, -} s3c_mfc_interbuff_status; - -typedef struct { - int luma0; /* per frame (or top field) */ - int chroma0; /* per frame (or top field) */ - int luma1; /* per frame (or bottom field) */ - int chroma1; /* per frame (or bottom field) */ -} SSBSIP_MFC_CRC_DATA; - -struct mfc_strm_ref_buf_arg { - unsigned int strm_ref_y; - unsigned int mv_ref_yc; -}; - -struct mfc_frame_buf_arg { - unsigned int luma; - unsigned int chroma; -}; - -struct mfc_enc_init_common_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - - int in_width; /* [IN] width of YUV420 frame to be encoded */ - int in_height; /* [IN] height of YUV420 frame to be encoded */ - - int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ - int in_vop_quant; /* [IN] VOP quant */ - int in_vop_quant_p; /* [IN] VOP quant for P frame */ - - /* [IN] RC enable */ - /* [IN] RC enable (0:disable, 1:frame level RC) */ - int in_rc_fr_en; - int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ - - int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ - int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ - int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ - - /* [IN] Multi-slice mode (0:single, 1:multiple) */ - int in_ms_mode; - /* [IN] Multi-slice size (in num. of mb or byte) */ - int in_ms_arg; - - int in_mb_refresh; /* [IN] Macroblock refresh */ - - /* [IN] Enable (1) / Disable (0) padding with the specified values */ - int in_pad_ctrl_on; - - /* [IN] pad value if pad_ctrl_on is Enable */ - int in_y_pad_val; - int in_cb_pad_val; - int in_cr_pad_val; - - /* linear or tiled */ - int in_frame_map; - - unsigned int in_pixelcache; - - unsigned int in_mapped_addr; - struct mfc_strm_ref_buf_arg out_u_addr; - struct mfc_strm_ref_buf_arg out_p_addr; - struct mfc_strm_ref_buf_arg out_buf_size; - unsigned int out_header_size; -}; - -struct mfc_enc_init_h263_arg { - int in_rc_framerate; /* [IN] RC parameter (framerate) */ -}; - -struct mfc_enc_init_mpeg4_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ - int in_quart_pixel; - - int in_TimeIncreamentRes; /* [IN] VOP time resolution */ - int in_VopTimeIncreament; /* [IN] Frame delta */ -}; - -struct mfc_enc_init_h264_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] interlace mode(0:progressive, 1:interlace) */ - int in_interlace_mode; - - /* [IN] reference number */ - int in_reference_num; - /* [IN] reference number of P frame */ - int in_ref_num_p; - - int in_rc_framerate; /* [IN] RC parameter (framerate) */ - int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ - /* [IN] MB level rate control dark region adaptive feature */ - int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control smooth region adaptive feature */ - int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control static region adaptive feature */ - int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control activity region adaptive feature */ - int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ - - /* [IN] disable deblocking filter idc */ - int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ - /* [IN] slice alpha c0 offset of deblocking filter */ - int in_deblock_alpha_c0; - /* [IN] slice beta offset of deblocking filter */ - int in_deblock_beta; - - /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ - int in_symbolmode; - /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ - int in_transform8x8_mode; - - /* [IN] Inter weighted parameter for mode decision */ - int in_md_interweight_pps; - /* [IN] Intra weighted parameter for mode decision */ - int in_md_intraweight_pps; -}; - -struct mfc_enc_init_arg { - struct mfc_enc_init_common_arg cmn; - union { - struct mfc_enc_init_h264_arg h264; - struct mfc_enc_init_mpeg4_arg mpeg4; - struct mfc_enc_init_h263_arg h263; - } codec; -}; - -struct mfc_enc_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ - unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ - unsigned int in_frametag; /* [IN] unique frame ID */ - - unsigned int out_frame_type; /* [OUT] frame type */ - int out_encoded_size; /* [OUT] Length of Encoded video stream */ - unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */ - unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */ - unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */ - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif -}; - -struct mfc_dec_init_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] address of stream buffer */ - int in_strm_size; /* [IN] filled size in stream buffer */ - int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ - - unsigned int in_crc; /* [IN] */ - unsigned int in_pixelcache; /* [IN] */ - unsigned int in_slice; /* [IN] */ - unsigned int in_numextradpb; /* [IN] */ - - unsigned int in_mapped_addr; - - int out_frm_width; /* [OUT] width of YUV420 frame */ - int out_frm_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ - - int out_crop_right_offset; /* [OUT] crop information for h264 */ - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; -}; - -struct mfc_dec_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] the physical address of STRM_BUF */ - /* [IN] Size of video stream filled in STRM_BUF */ - int in_strm_size; - /* [IN] the address of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_buf; - /* [IN] size of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_size; - /* [IN] Unique frame ID eg. application specific timestamp */ - unsigned int in_frametag; - /* [IN] immdiate Display for seek,thumbnail and one frame */ - int in_immediately_disp; - /* [OUT] the physical address of display buf */ - int out_display_Y_addr; - /* [OUT] the physical address of display buf */ - int out_display_C_addr; - int out_display_status; - /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_top; - /* [OUT] unique frame ID of bottom field */ - unsigned int out_frametag_bottom; - int out_pic_time_top; - int out_pic_time_bottom; - int out_consumed_byte; - - int out_crop_right_offset; - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; - - /* in new driver, each buffer offset must be return to the user */ - int out_y_offset; - int out_c_offset; - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif - int out_img_width; /* [OUT] width of YUV420 frame */ - int out_img_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ -}; - -struct mfc_get_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to get for the configurable parameter. */ - /* Maximum four integer values can be obtained; */ - int out_config_value[4]; -}; - -struct mfc_set_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to be set for the configurable parameter. */ - /* Maximum four integer values can be set. */ - int in_config_value[4]; -}; - -struct mfc_get_real_addr_arg { - unsigned int key; - unsigned int addr; -}; - -struct mfc_buf_alloc_arg { - enum inst_type type; - int size; - /* - unsigned int mapped; - */ - unsigned int align; - - unsigned int addr; - /* - unsigned int phys; - */ -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - /* FIMXE: invalid secure id == -1 */ - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_buf_free_arg { - unsigned int addr; -}; - -/* RMVME */ -struct mfc_mem_alloc_arg { - enum inst_type type; - int buff_size; - SSBIP_MFC_BUFFER_TYPE buf_cache_type; - unsigned int mapped_addr; -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_mem_free_arg { - unsigned int key; -}; -/* RMVME */ - -union mfc_args { - /* - struct mfc_enc_init_arg enc_init; - - struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; - struct mfc_enc_init_mpeg4_arg enc_init_h263; - struct mfc_enc_init_h264_arg enc_init_h264; - */ - struct mfc_enc_init_arg enc_init; - struct mfc_enc_exe_arg enc_exe; - - struct mfc_dec_init_arg dec_init; - struct mfc_dec_exe_arg dec_exe; - - struct mfc_get_config_arg get_config; - struct mfc_set_config_arg set_config; - - struct mfc_buf_alloc_arg buf_alloc; - struct mfc_buf_free_arg buf_free; - struct mfc_get_real_addr_arg real_addr; - - /* RMVME */ - struct mfc_mem_alloc_arg mem_alloc; - struct mfc_mem_free_arg mem_free; - /* RMVME */ -}; - -struct mfc_common_args { - enum mfc_ret_code ret_code; /* [OUT] error code */ - union mfc_args args; -}; - -struct mfc_enc_vui_info { - int aspect_ratio_idc; -}; - -struct mfc_dec_fimv1_info { - int width; - int height; -}; - -struct mfc_enc_hier_p_qp { - int t0_frame_qp; - int t2_frame_qp; - int t3_frame_qp; -}; - -enum BUF_STATUS { - BUF_ENQUEUED, - BUF_DEQUEUED -}; - -struct mfc_dec_v4l2 { - char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */ - char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */ - char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */ - - unsigned int mfc_src_bufs_len; /* needed for munmap */ - unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */ - - unsigned int mfc_num_src_bufs; /* the number of source buffers */ - unsigned int mfc_num_dst_bufs; /* the number of destination buffers */ - - char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS]; - int bBeingFinalized; - int allocIndex; - int beingUsedIndex; -}; - -struct mfc_enc_v4l2 { - char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; - char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; - char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS]; - - unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES]; - unsigned int mfc_dst_bufs_len; - - unsigned int mfc_num_src_bufs; - unsigned int mfc_num_dst_bufs; - - unsigned int mfc_dst_bufs_bytes_used_len; - char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS]; - int bRunning; - int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */ - int beingUsedIndex; -}; - -typedef struct { - int magic; - int hMFC; - int hVMEM; - int width; - int height; - int sizeStrmBuf; - struct mfc_frame_buf_arg sizeFrmBuf; - int displayStatus; - int inter_buff_status; - unsigned int virFreeStrmAddr; - unsigned int phyStrmBuf; - unsigned int virStrmBuf; - unsigned int virMvRefYC; - struct mfc_frame_buf_arg phyFrmBuf; - struct mfc_frame_buf_arg virFrmBuf; - unsigned int mapped_addr; - unsigned int mapped_size; - struct mfc_common_args MfcArg; - SSBSIP_MFC_CODEC_TYPE codecType; - SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; - unsigned int inframetag; - unsigned int outframetagtop; - unsigned int outframetagbottom; - unsigned int immediatelydisp; - unsigned int encodedHeaderSize; - int encodedDataSize; - unsigned int encodedframeType; - struct mfc_frame_buf_arg encodedphyFrmBuf; - - unsigned int dec_crc; - unsigned int dec_pixelcache; - unsigned int dec_slice; - unsigned int dec_numextradpb; - - int input_cookie; - int input_secure_id; - int input_size; - - /* to support non-blocking mode */ - unsigned int encode_cnt; - - struct mfc_dec_v4l2 v4l2_dec; - struct mfc_enc_v4l2 v4l2_enc; - - int enc_frameskip; - int cacheablebuffer; - struct mfc_dec_fimv1_info fimv1_res; - SSBSIP_MFC_LAST_FRAME_STATUS lastframe; - SSBSIP_MFC_INSTRM_MODE_TYPE framemap; -} _MFCLIB; - -#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) -#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) - -#define SSBSIP_MFC_FAIL (0) - -#endif /* __MFC_INTERFACE_H */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk deleted file mode 100644 index 949c637..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk +++ /dev/null @@ -1,7 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_VIDEO_PATH :=$(LOCAL_PATH) - -include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk deleted file mode 100644 index 89f3e84..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - include/mfc_errno.h \ - include/mfc_interface.h \ - include/SsbSipMfcApi.h - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - dec/src/SsbSipMfcDecAPI.c \ - enc/src/SsbSipMfcEncAPI.c - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - $(BOARD_HAL_PATH)/include - -LOCAL_MODULE := libsecmfcapi - -LOCAL_PRELINK_MODULE := false - -ifeq ($(BOARD_USE_S3D_SUPPORT), true) -LOCAL_CFLAGS += -DS3D_SUPPORT -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := liblog - -#ifeq ($(BOARD_USE_V4L2_ION),true) -#LOCAL_CFLAGS += -DUSE_ION -#LOCAL_SHARED_LIBRARIES += libion -#endif - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c deleted file mode 100644 index fb04587..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c +++ /dev/null @@ -1,1740 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include "videodev2.h" - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" -#ifdef USE_ION -#include "ion.h" -#endif - -/* #define LOG_NDEBUG 0 */ -#define LOG_TAG "MFC_DEC_APP" -#include - -/*#define CRC_ENABLE -#define SLICE_MODE_ENABLE */ -#define POLL_DEC_WAIT_TIMEOUT 25 - -#define USR_DATA_START_CODE (0x000001B2) -#define VOP_START_CODE (0x000001B6) -#define MP4_START_CODE (0x000001) - -#define DEFAULT_NUMBER_OF_EXTRA_DPB 5 -#define CLEAR(x) memset (&(x), 0, sizeof(x)) -#ifdef S3D_SUPPORT -#define OPERATE_BIT(x, mask, shift) ((x & (mask << shift)) >> shift) -#define FRAME_PACK_SEI_INFO_NUM 4 -#endif - -enum { - NV12MT_FMT = 0, - NV12M_FMT, - NV21M_FMT, -}; - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; -static int mfc_dev_node = 6; - -int read_header_data(void *openHandle); -int init_mfc_output_stream(void *openHandle); -int isBreak_loop(void *openHandle); - -int v4l2_mfc_querycap(int fd) -{ - struct v4l2_capability cap; - int ret; - - CLEAR(cap); - - ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYCAP failed", __func__); - return ret; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - LOGE("[%s] Device does not support capture", __func__); - return -1; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { - LOGE("[%s] Device does not support output", __func__); - return -1; - } - - if (!(cap.capabilities & V4L2_CAP_STREAMING)) { - LOGE("[%s] Device does not support streaming", __func__); - return -1; - } - - return 0; -} - -int v4l2_mfc_s_fmt(int fd, enum v4l2_buf_type type, - int pixelformat, unsigned int sizeimage, int width, int height) -{ - int ret; - struct v4l2_format fmt; - - CLEAR(fmt); - - fmt.type = type; - - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - switch (pixelformat) { - case H264_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; - break; - case MPEG4_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; - break; - case H263_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; - break; - case XVID_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_XVID; - break; - case MPEG2_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG12; - break; - case FIMV1_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV1; - fmt.fmt.pix_mp.width = width; - fmt.fmt.pix_mp.height = height; - break; - case FIMV2_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV2; - break; - case FIMV3_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV3; - break; - case FIMV4_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV4; - break; - case VC1_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1; - break; - case VC1RCV_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1_RCV; - break; -#if defined (MFC6x_VERSION) - case VP8_DEC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VP8; - break; -#endif - default: - LOGE("[%s] Does NOT support the codec type (%d)", __func__, pixelformat); - return -1; - } - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage; - } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - switch (pixelformat) { - case NV12MT_FMT: -#if defined (MFC6x_VERSION) - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; -#else - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; -#endif - break; - case NV12M_FMT: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; - break; - case NV21M_FMT: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV21M; - break; - default: - LOGE("[%s] Does NOT support the pixel format (%d)", __func__, pixelformat); - return -1; - } - } else { - LOGE("[%s] Wrong buffer type", __func__); - return -1; - } - - ret = ioctl(fd, VIDIOC_S_FMT, &fmt); - - return ret; -} - -int v4l2_mfc_reqbufs(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_cnt) -{ - struct v4l2_requestbuffers reqbuf; - int ret; - - CLEAR(reqbuf); - - reqbuf.type = type; - reqbuf.memory = memory; - reqbuf.count = *buf_cnt; - - ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf); - *buf_cnt = reqbuf.count; - - return ret; -} - -int v4l2_mfc_querybuf(int fd, struct v4l2_buffer *buf, enum v4l2_buf_type type, - enum v4l2_memory memory, int index, struct v4l2_plane *planes) -{ - int length = -1, ret; - - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - length = 1; - else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - length = 2; - - CLEAR(*buf); - buf->type = type; - buf->memory = memory; - buf->index = index; - buf->m.planes = planes; - buf->length = length; - - ret = ioctl(fd, VIDIOC_QUERYBUF, buf); - - return ret; -} - -int v4l2_mfc_streamon(int fd, enum v4l2_buf_type type) -{ - int ret; - - ret = ioctl(fd, VIDIOC_STREAMON, &type); - - return ret; -} - -int v4l2_mfc_streamoff(int fd, enum v4l2_buf_type type) -{ - int ret; - - ret = ioctl(fd, VIDIOC_STREAMOFF, &type); - - return ret; -} - -int v4l2_mfc_s_ctrl(int fd, int id, int value) -{ - struct v4l2_control ctrl; - int ret; - - CLEAR(ctrl); - ctrl.id = id; - ctrl.value = value; - - ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); - - return ret; -} - -int v4l2_mfc_g_ctrl(int fd, int id, int *value) -{ - struct v4l2_control ctrl; - int ret; - - CLEAR(ctrl); - ctrl.id = id; - - ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); - *value = ctrl.value; - - return ret; -} - -#ifdef S3D_SUPPORT -int v4l2_mfc_ext_g_ctrl(int fd, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM]; - struct v4l2_ext_controls ext_ctrls; - struct mfc_frame_pack_sei_info *sei_info; - int ret, i; - - ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC; - - switch (conf_type) { - case MFC_DEC_GETCONF_FRAME_PACKING: - sei_info = (struct mfc_frame_pack_sei_info *)value; - for (i=0; isei_avail = ext_ctrl[0].value; - sei_info->arrgment_id = ext_ctrl[1].value; - sei_info->sei_info = ext_ctrl[2].value; - sei_info->grid_pos = ext_ctrl[3].value; - break; - } - - return ret; -} -#endif - -int v4l2_mfc_qbuf(int fd, struct v4l2_buffer *qbuf, enum v4l2_buf_type type, - enum v4l2_memory memory, int index, - struct v4l2_plane *planes, int frame_length) -{ - int ret, length = 0; - - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - CLEAR(*qbuf); - length = 1; - } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - length = 2; - } - - qbuf->type = type; - qbuf->memory = memory; - qbuf->index = index; - qbuf->m.planes = planes; - qbuf->length = length; - qbuf->m.planes[0].bytesused = frame_length; - - ret = ioctl(fd, VIDIOC_QBUF, qbuf); - - return ret; -} - -int v4l2_mfc_dqbuf(int fd, struct v4l2_buffer *dqbuf, enum v4l2_buf_type type, - enum v4l2_memory memory) -{ - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - int ret, length = 0; - - CLEAR(*dqbuf); - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - length = 1; - else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - length = 2; - - dqbuf->type = type; - dqbuf->memory = memory; - dqbuf->m.planes = planes; - dqbuf->length = length; - - ret = ioctl(fd, VIDIOC_DQBUF, dqbuf); - - return ret; -} - -int v4l2_mfc_g_fmt(int fd, struct v4l2_format *fmt, enum v4l2_buf_type type) -{ - int ret; - - CLEAR(*fmt); - fmt->type = type; - ret = ioctl(fd, VIDIOC_G_FMT, fmt); - - return ret; -} - -int v4l2_mfc_g_crop(int fd, struct v4l2_crop *crop, enum v4l2_buf_type type) -{ - int ret; - - CLEAR(*crop); - crop->type = type; - ret = ioctl(fd, VIDIOC_G_CROP, crop); - - return ret; -} - -int v4l2_mfc_poll(int fd, int *revents, int timeout) -{ - struct pollfd poll_events; - int ret; - - poll_events.fd = fd; - poll_events.events = POLLOUT | POLLERR; - poll_events.revents = 0; - - ret = poll((struct pollfd*)&poll_events, 1, timeout); - *revents = poll_events.revents; - - return ret; -} - -static void getAByte(char *buff, int *code) -{ - int byte; - - *code = (*code << 8); - byte = (int)*buff; - byte &= 0xFF; - *code |= byte; -} - -static int isPBPacked(_MFCLIB *pCtx, int Frameleng) -{ - char *strmBuffer = NULL; - int startCode = 0xFFFFFFFF; - int leng_idx = 1; - - strmBuffer = (char*)pCtx->virStrmBuf; - - while (1) { - while (startCode != USR_DATA_START_CODE) { - if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) { - LOGI("[%s] VOP START Found !!.....return",__func__); - LOGW("[%s] Non Packed PB",__func__); - return 0; - } - getAByte(strmBuffer, &startCode); - LOGV(">> StartCode = 0x%08x <<\n", startCode); - strmBuffer++; - leng_idx++; - } - LOGI("[%s] User Data Found !!",__func__); - - do { - if (*strmBuffer == 'p') { - LOGW("[%s] Packed PB",__func__); - return 1; - } - getAByte(strmBuffer, &startCode); - strmBuffer++; leng_idx++; - } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE)); - - if (leng_idx > Frameleng) - break; - } - - LOGW("[%s] Non Packed PB",__func__); - - return 0; -} - -static void getMFCName(char *devicename, int size) -{ - snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); -} - -void SsbSipMfcDecSetMFCNode(int devicenode) -{ - mfc_dev_node = devicenode; -} - -void SsbSipMfcDecSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcDecOpen(void) -{ - int hMFCOpen; - _MFCLIB *pCTX; - char mfc_dev_name[64]; - - int ret; - int req_count; - unsigned int i, j; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("[%s] malloc failed.",__func__); - return NULL; - } - - memset(pCTX, 0, sizeof(_MFCLIB)); - - getMFCName(mfc_dev_name, 64); - LOGI("[%s] dev name is %s",__func__,mfc_dev_name); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("[%s] MFC device node not exists",__func__); - goto error_case1; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR|O_NONBLOCK, 0); - if (hMFCOpen < 0) { - LOGE("[%s] Failed to open MFC device",__func__); - goto error_case1; - } - - pCTX->hMFC = hMFCOpen; - - ret = v4l2_mfc_querycap(pCTX->hMFC); - if (ret != 0) { - LOGE("[%s] QUERYCAP failed", __func__); - goto error_case2; - } - - pCTX->inter_buff_status = MFC_USE_NONE; - ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - H264_DEC, MAX_DECODER_INPUT_BUFFER_SIZE, 0, 0); - if (ret != 0) { - LOGE("[%s] S_FMT failed",__func__); - goto error_case2; - } - - pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE; - - req_count = MFC_DEC_NUM_SRC_BUFS; - ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, &req_count); - if (ret != 0) { - LOGE("[%s] VIDIOC_REQBUFS failed",__func__); - goto error_case2; - } - - pCTX->v4l2_dec.mfc_num_src_bufs = req_count; - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; ++i) { - ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, i, planes); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYBUF failed",__func__); - goto error_case3; - } - - pCTX->v4l2_dec.mfc_src_bufs[i] = mmap(NULL, buf.m.planes[0].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_dec.mfc_src_bufs[i] == MAP_FAILED) { - LOGE("[%s] mmap failed (%d)",__func__,i); - goto error_case3; - } - } - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - /* set extra DPB size to 5 as default for optimal performce (heuristic method) */ - pCTX->dec_numextradpb = DEFAULT_NUMBER_OF_EXTRA_DPB; - - pCTX->v4l2_dec.bBeingFinalized = 0; - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED; - - pCTX->cacheablebuffer = NO_CACHE; - - for (i = 0; iv4l2_dec.mfc_src_buf_flags[i] = BUF_DEQUEUED; - - pCTX->v4l2_dec.beingUsedIndex = 0; - - return (void *) pCTX; - -error_case3: - for (j = 0; j < i; j++) - munmap(pCTX->v4l2_dec.mfc_src_bufs[j], pCTX->v4l2_dec.mfc_src_bufs_len); -error_case2: - close(pCTX->hMFC); -error_case1: - free(pCTX); - - return NULL; -} - -void *SsbSipMfcDecOpenExt(void *value) -{ - _MFCLIB *pCTX; - - pCTX = SsbSipMfcDecOpen(); - - if (pCTX == NULL) - return NULL; - - if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { - pCTX->cacheablebuffer = NO_CACHE; - LOGI("[%s] non cacheable buffer",__func__); - } else { - pCTX->cacheablebuffer = CACHE; - LOGI("[%s] cacheable buffer",__func__); - } - - return (void *)pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) -{ - int ret, i; - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { - ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - } - - if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { - ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); - } - - if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { - for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; i++) - munmap(pCTX->v4l2_dec.mfc_src_bufs[i], pCTX->v4l2_dec.mfc_src_bufs_len); - pCTX->inter_buff_status &= ~(MFC_USE_STRM_BUFF); - } - - if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); - } - pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); - } - -#ifdef USE_ION - ion_client_destroy(pCTX->ion_fd); -#endif - close(pCTX->hMFC); - free(pCTX); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) -{ - int packedPB = 0; - _MFCLIB *pCTX; - int ret; - - int width, height; - int ctrl_value; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - int poll_state, poll_revents; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - pCTX->codecType = codec_type; - - if ((pCTX->codecType == MPEG4_DEC) || (pCTX->codecType == XVID_DEC) || - (pCTX->codecType == FIMV1_DEC) || (pCTX->codecType == FIMV2_DEC) || - (pCTX->codecType == FIMV3_DEC) || (pCTX->codecType == FIMV4_DEC)) - packedPB = isPBPacked(pCTX, Frameleng); - - if (pCTX->codecType == FIMV1_DEC) { - width = pCTX->fimv1_res.width; - height = pCTX->fimv1_res.height; - } else { - width = 0; - height = 0; - } - ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, pCTX->codecType, - MAX_DECODER_INPUT_BUFFER_SIZE, width, height); - if (ret != 0) { - LOGE("[%s] S_FMT failed", __func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - /* Set default destination format as NV12MT */ - ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, NV12MT_FMT, - 0, width, height); - if (ret != 0) { - LOGE("[%s] S_FMT failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - /* PackedPB should be set after VIDIOC_S_FMT */ - if (packedPB) { - ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CODEC_PACKED_PB, 1); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed of PACKED_PB\n", __func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - } - - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, Frameleng); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - /* Processing the header requires running streamon - on OUTPUT queue */ - ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; - - ret = read_header_data(pCTX); - if (ret != 0) - goto error_case1; - - /* cacheable buffer */ - if (pCTX->cacheablebuffer == NO_CACHE) - ctrl_value = 0; - else - ctrl_value = 1; - - ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CACHEABLE, ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE", __func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - -#ifdef USE_ION - pCTX->ion_fd = ion_client_create(); - if (pCTX->ion_fd < 3) { - LOGE("[%s] Failed to get ion_fd : %d", __func__, pCTX->ion_fd); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } -#endif - - ret = init_mfc_output_stream(pCTX); - if (ret != 0) - goto error_case1; - - ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)", __func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - - do { - poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); - if (poll_state > 0) { - if (poll_revents & POLLOUT) { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); - if (ret == 0) - break; - } else if (poll_revents & POLLERR) { - LOGE("[%s] POLLERR\n", __func__); - return MFC_GETOUTBUF_STATUS_NULL; - } else { - LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); - return MFC_GETOUTBUF_STATUS_NULL; - } - } else if (poll_state < 0) { - return MFC_GETOUTBUF_STATUS_NULL; - } - } while (poll_state == 0); - - return MFC_RET_OK; - -error_case1: - SsbSipMfcDecClose(openHandle); - return ret; -} - -int read_header_data(void *openHandle) -{ - struct v4l2_format fmt; - struct v4l2_crop crop; - struct v4l2_pix_format_mplane pix_mp; - int ctrl_value; - int ret; - - _MFCLIB *pCTX; - pCTX = (_MFCLIB *) openHandle; - - ret = v4l2_mfc_g_fmt(pCTX->hMFC, &fmt, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_FMT failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case; - } - - pix_mp = fmt.fmt.pix_mp; - pCTX->decOutInfo.buf_width = pix_mp.plane_fmt[0].bytesperline; - pCTX->decOutInfo.buf_height = - pix_mp.plane_fmt[0].sizeimage / pix_mp.plane_fmt[0].bytesperline; - - pCTX->decOutInfo.img_width = pix_mp.width; - pCTX->decOutInfo.img_height = pix_mp.height; - - ret = v4l2_mfc_g_crop(pCTX->hMFC, &crop, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CROP failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case; - } - - pCTX->decOutInfo.crop_left_offset = crop.c.left; - pCTX->decOutInfo.crop_top_offset = crop.c.top; - pCTX->decOutInfo.crop_right_offset = - pix_mp.width - crop.c.width - crop.c.left; - pCTX->decOutInfo.crop_bottom_offset = - pix_mp.height - crop.c.height - crop.c.top; - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_REQ_NUM_BUFS, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case; - } - - pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl_value + pCTX->dec_numextradpb; - - LOGV("[%s] Num of allocated buffers: %d\n",__func__, pCTX->v4l2_dec.mfc_num_dst_bufs); - - return 0; - -error_case: - return ret; - } - -/* Initialize output stream of MFC */ -int init_mfc_output_stream(void *openHandle) -{ - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - int ret; - int i, j; - _MFCLIB *pCTX; - pCTX = (_MFCLIB *) openHandle; - - ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_MEMORY_MMAP, (int *)&pCTX->v4l2_dec.mfc_num_dst_bufs); - if (ret != 0) { - LOGE("[%s] VIDIOC_REQBUFS failed (destination buffers)",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { - ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_MEMORY_MMAP, i, planes); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYBUF failed (destination buffers)",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case1; - } - - pCTX->v4l2_dec.mfc_dst_bufs_len[0] = buf.m.planes[0].length; - pCTX->v4l2_dec.mfc_dst_bufs_len[1] = buf.m.planes[1].length; - - pCTX->v4l2_dec.mfc_dst_phys[i][0] = buf.m.planes[0].cookie; - pCTX->v4l2_dec.mfc_dst_phys[i][1] = buf.m.planes[1].cookie; - -#ifdef USE_ION - pCTX->dst_ion_fd[i][0] = (int)buf.m.planes[0].share; - pCTX->dst_ion_fd[i][1] = (int)buf.m.planes[1].share; - - pCTX->v4l2_dec.mfc_dst_bufs[i][0] = - ion_map(pCTX->dst_ion_fd[i][0],pCTX->v4l2_dec.mfc_dst_bufs_len[0],0); - pCTX->v4l2_dec.mfc_dst_bufs[i][1] = - ion_map(pCTX->dst_ion_fd[i][1],pCTX->v4l2_dec.mfc_dst_bufs_len[1],0); - if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED || - pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) - goto error_case2; -#else - pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, buf.m.planes[0].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) { - LOGE("[%s] mmap failed (destination buffers (Y))",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_dec.mfc_dst_bufs[i][1] = mmap(NULL, buf.m.planes[1].length, - PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); - if (pCTX->v4l2_dec.mfc_dst_bufs[i][1] == MAP_FAILED) { - LOGE("[%s] mmap failed (destination buffers (UV))",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } -#endif - - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_MEMORY_MMAP, i, planes, 0); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_DEC_INIT_FAIL; - goto error_case2; - } - } - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - return 0; - -error_case2: - for (j = 0; j < i; j++) { - munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); - munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); - } -error_case1: - return ret; -} - -int resolution_change(void *openHandle) -{ - int i, ret; - int req_count; - _MFCLIB *pCTX; - pCTX = (_MFCLIB *) openHandle; - - ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) - goto error_case; - - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) { - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]); - munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]); - } - pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF); - - req_count = 0; - ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_MEMORY_MMAP, &req_count); - if (ret != 0) - goto error_case; - - read_header_data(pCTX); - init_mfc_output_stream(pCTX); - - ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) - goto error_case; - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - - return 0; - -error_case: - return ret; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) -{ - _MFCLIB *pCTX; - int ret; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - int loop_count, ctrl_value; - - int poll_state; - int poll_revents; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) { - if (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY) { - /* Queue the stream frame */ - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.m.planes = planes; - buf.length = 1; - - /* wait for decoding */ - do { - poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); - if (poll_state > 0) { - if (poll_revents & POLLOUT) { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); - if (ret == 0) { - if (buf.flags & V4L2_BUF_FLAG_ERROR) - return MFC_RET_DEC_EXE_ERR; - pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED; - break; - } - } else if (poll_revents & POLLERR) { - LOGE("[%s] POLLERR\n",__func__); - return MFC_RET_DEC_EXE_ERR; - } else { - LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); - return MFC_RET_DEC_EXE_ERR; - } - } else if (poll_state < 0) { - return MFC_RET_DEC_EXE_ERR; - } - - if (isBreak_loop(pCTX)) - break; - - } while(0 == poll_state); - } - - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return MFC_RET_OK; - } else { - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed", __func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - - switch (ctrl_value) { - case 0: - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - break; - case 1: - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; - break; - case 2: - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - break; - case 3: - pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL; - break; - } - } - - if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) { - resolution_change(pCTX); - } else { - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } - - if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - - } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ - - /* Queue the stream frame */ - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - - /* wait for decoding */ - loop_count = 0; - do { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) - usleep(1000); - loop_count++; - if (loop_count >= 1000) { - LOGE("[%s] Error in do-while loop",__func__); - break; - } - } while (ret != 0); - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed", __func__); - return MFC_RET_DEC_EXE_ERR; - } - if (ctrl_value == 3) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return MFC_RET_OK; - } - - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } else { - loop_count = 0; - do { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) - usleep(1000); - loop_count++; - if (loop_count >= 1000) { - LOGE("[%s] Error in do-while loop",__func__); - break; - } - } while (ret != 0); - - if (buf.m.planes[0].bytesused == 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return MFC_RET_OK; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } - - pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3)); - - switch (pCTX->decOutInfo.disp_pic_frame_type) { - case V4L2_BUF_FLAG_KEYFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 1; - break; - case V4L2_BUF_FLAG_PFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 2; - break; - case V4L2_BUF_FLAG_BFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 3; - break; - default: - pCTX->decOutInfo.disp_pic_frame_type = 0; - break; - } - - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, - buf.index, planes, 0); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill) -{ - _MFCLIB *pCTX; - int ret; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) - && (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY)) { - /* Queue the stream frame */ - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { - /* Queue the stream frame */ - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_DEC_EXE_ERR; - } - } - - if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0)) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; - - return MFC_RET_OK; -} - -int isBreak_loop(void *openHandle) -{ - _MFCLIB *pCTX; - pCTX = (_MFCLIB *) openHandle; - int ctrl_value; - int ret = 0; - - if (pCTX->displayStatus == MFC_GETOUTBUF_DISPLAY_ONLY) - return 1; - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CHECK_STATE, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed", __func__); - return 0; - } - - if (ctrl_value == MFCSTATE_DEC_RES_DETECT) { - LOGV("[%s] Resolution Change detect",__func__); - return 1; - } else if (ctrl_value == MFCSTATE_DEC_TERMINATING) { - LOGV("[%s] Decoding Finish!!!",__func__); - return 1; - } - - return 0; -} - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - int ret; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - int loop_count, ctrl_value; - - int poll_state; - int poll_revents; - - pCTX = (_MFCLIB *) openHandle; - - if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { - if (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY) { - /* wait for decoding */ - do { - poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT); - if (poll_state > 0) { - if (poll_revents & POLLOUT) { - buf.m.planes = planes; - buf.length = 1; - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); - if (ret == 0) { - if (buf.flags & V4L2_BUF_FLAG_ERROR) - return MFC_GETOUTBUF_STATUS_NULL; - pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED; - break; - } - } else if (poll_revents & POLLERR) { - LOGE("[%s] POLLERR\n",__func__); - return MFC_GETOUTBUF_STATUS_NULL; - } else { - LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents); - return MFC_GETOUTBUF_STATUS_NULL; - } - } else if (poll_state < 0) { - return MFC_GETOUTBUF_STATUS_NULL; - } - - if (isBreak_loop(pCTX)) - break; - - } while (0 == poll_state); - } - - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return SsbSipMfcDecGetOutBuf(pCTX, output_info);; - } else { - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed", __func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - - switch (ctrl_value) { - case 0: - pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY; - break; - case 1: - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING; - break; - case 2: - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - break; - case 3: - pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL; - break; - } - } - - if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) { - resolution_change(pCTX); - } else { - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } - - if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe) - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - } else if (pCTX->v4l2_dec.bBeingFinalized == 0) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED; - pCTX->v4l2_dec.bBeingFinalized = 1; /* true */ - - /* wait for decoding */ - loop_count = 0; - do { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) - usleep(1000); - loop_count++; - if (loop_count >= 1000) { - LOGE("[%s] Error in do-while loop",__func__); - break; - } - } while (ret != 0); - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed", __func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - if (ctrl_value == 3) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return SsbSipMfcDecGetOutBuf(pCTX, output_info);; - } - - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } else { - loop_count = 0; - do { - ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); - if (ret != 0) - usleep(1000); - loop_count++; - if (loop_count >= 1000) { - LOGE("[%s] Error in do-while loop",__func__); - break; - } - } while (ret != 0); - - if (buf.m.planes[0].bytesused == 0) { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END; - pCTX->decOutInfo.disp_pic_frame_type = -1; - return SsbSipMfcDecGetOutBuf(pCTX, output_info);; - } else { - pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY; - } - - pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0]; - pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1]; - - pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0]; - pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1]; - } - - pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3)); - - switch (pCTX->decOutInfo.disp_pic_frame_type) { - case V4L2_BUF_FLAG_KEYFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 1; - break; - case V4L2_BUF_FLAG_PFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 2; - break; - case V4L2_BUF_FLAG_BFRAME: - pCTX->decOutInfo.disp_pic_frame_type = 3; - break; - default: - pCTX->decOutInfo.disp_pic_frame_type = 0; - break; - } - - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, - buf.index, planes, 0); - - return SsbSipMfcDecGetOutBuf(pCTX, output_info); -} - -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) -{ - _MFCLIB *pCTX; - int i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return NULL; - } - - if ((inputBufferSize < 0) || (inputBufferSize > MAX_DECODER_INPUT_BUFFER_SIZE)) { - LOGE("[%s] inputBufferSize = %d is invalid",__func__, inputBufferSize); - return NULL; - } - - pCTX = (_MFCLIB *) openHandle; - - for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) - if (BUF_DEQUEUED == pCTX->v4l2_dec.mfc_src_buf_flags[i]) - break; - - if (i == MFC_DEC_NUM_SRC_BUFS) { - LOGV("[%s] No buffer is available.",__func__); - return NULL; - } else { - pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_dec.mfc_src_bufs[i]; - pCTX->v4l2_dec.beingUsedIndex = i; - /* Set the buffer flag as Enqueued for NB_mode_process*/ - /* FIXME: Check this assignment in case of using New API ExeNb() */ - pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - - return (void *)pCTX->virStrmBuf; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size) -{ - _MFCLIB *pCTX; - int i; - - LOGV("[%s] Enter",__func__); - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) { - if (pCTX->v4l2_dec.mfc_src_bufs[i] == virInBuf) - break; - } - - if (i == MFC_DEC_NUM_SRC_BUFS) { - LOGE("[%s] Can not use the buffer",__func__); - return MFC_RET_INVALID_PARAM; - } else { - pCTX->virStrmBuf = (unsigned int)virInBuf; - pCTX->v4l2_dec.beingUsedIndex = i; - pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - LOGV("[%s] Exit idx %d",__func__,pCTX->v4l2_dec.beingUsedIndex); - return MFC_RET_OK; -} - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_GETOUTBUF_DISPLAY_END; - } - - pCTX = (_MFCLIB *) openHandle; - - output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; - output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; - - output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; - output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; - - output_info->img_width = pCTX->decOutInfo.img_width; - output_info->img_height= pCTX->decOutInfo.img_height; - - output_info->buf_width = pCTX->decOutInfo.buf_width; - output_info->buf_height= pCTX->decOutInfo.buf_height; - - output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - - output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type; - - switch (pCTX->displayStatus) { - case MFC_GETOUTBUF_DISPLAY_ONLY: - case MFC_GETOUTBUF_DISPLAY_DECODING: - case MFC_GETOUTBUF_DISPLAY_END: - case MFC_GETOUTBUF_DECODING_ONLY: - case MFC_GETOUTBUF_CHANGE_RESOL: - break; - default: - return MFC_GETOUTBUF_DISPLAY_END; - } - - return pCTX->displayStatus; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - int ret, i; - - _MFCLIB *pCTX; - struct mfc_dec_fimv1_info *fimv1_res; - - struct v4l2_buffer buf; - struct v4l2_plane planes[MFC_DEC_NUM_PLANES]; - - int id, ctrl_value; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if ((value == NULL) && (MFC_DEC_SETCONF_IS_LAST_FRAME !=conf_type)) { - LOGE("[%s] value is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - /* First, process non-ioctl calling settings */ - switch (conf_type) { - case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: - pCTX->dec_numextradpb = *((unsigned int *) value); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: /* be set before calling SsbSipMfcDecInit */ - fimv1_res = (struct mfc_dec_fimv1_info *)value; - LOGI("fimv1->width = %d\n", fimv1_res->width); - LOGI("fimv1->height = %d\n", fimv1_res->height); - pCTX->fimv1_res.width = (int)(fimv1_res->width); - pCTX->fimv1_res.height = (int)(fimv1_res->height); - return MFC_RET_OK; - - case MFC_DEC_SETCONF_IS_LAST_FRAME: - if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) { - pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED; - return MFC_RET_OK; - } else { - return MFC_RET_FAIL; - } - - case MFC_DEC_SETCONF_DPB_FLUSH: - ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - - for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) { - ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - V4L2_MEMORY_MMAP, i, planes, 0); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - } - - ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__); - return MFC_RET_DEC_SET_CONF_FAIL; - } - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - return MFC_RET_OK; - default: - /* Others will be processed next */ - break; - } - - /* Process ioctl calling settings */ - switch (conf_type) { - case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */ - id = V4L2_CID_CODEC_DISPLAY_DELAY; - ctrl_value = *((unsigned int *) value); - break; - - case MFC_DEC_SETCONF_CRC_ENABLE: - id = V4L2_CID_CODEC_CRC_ENABLE; - ctrl_value = 1; - break; - - case MFC_DEC_SETCONF_SLICE_ENABLE: - id = V4L2_CID_CODEC_SLICE_INTERFACE; - ctrl_value = 1; - break; - - case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */ - id = V4L2_CID_CODEC_FRAME_TAG; - ctrl_value = *((unsigned int*)value); - break; - - case MFC_DEC_SETCONF_POST_ENABLE: - id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE; - ctrl_value = *((unsigned int*)value); - break; -#ifdef S3D_SUPPORT - case MFC_DEC_SETCONF_SEI_PARSE: - id = V4L2_CID_CODEC_FRAME_PACK_SEI_PARSE; - ctrl_value = 1; - break; -#endif - default: - LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - ret = v4l2_mfc_s_ctrl(pCTX->hMFC, id, ctrl_value); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); - return MFC_RET_DEC_SET_CONF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - - SSBSIP_MFC_IMG_RESOLUTION *img_resolution; - int ret; - SSBSIP_MFC_CRC_DATA *crc_data; -#ifdef S3D_SUPPORT - SSBSIP_MFC_FRAME_PACKING *frame_packing; - struct mfc_frame_pack_sei_info sei_info; -#endif - SSBSIP_MFC_CROP_INFORMATION *crop_information; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - switch (conf_type) { - case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: - img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; - img_resolution->width = pCTX->decOutInfo.img_width; - img_resolution->height = pCTX->decOutInfo.img_height; - img_resolution->buf_width = pCTX->decOutInfo.buf_width; - img_resolution->buf_height = pCTX->decOutInfo.buf_height; - break; - - case MFC_DEC_GETCONF_FRAME_TAG: - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_FRAME_TAG, (int*)value); - if (ret != 0) - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG", __func__); - break; - - case MFC_DEC_GETCONF_CRC_DATA: - crc_data = (SSBSIP_MFC_CRC_DATA *) value; - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_LUMA, &crc_data->luma0); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - - ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_CHROMA, &crc_data->chroma0); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__); - return MFC_RET_DEC_GET_CONF_FAIL; - } - LOGI("[%s] crc_data->luma0=0x%x\n", __func__, crc_data->luma0); - LOGI("[%s] crc_data->chroma0=0x%x\n", __func__, crc_data->chroma0); - break; -#ifdef S3D_SUPPORT - case MFC_DEC_GETCONF_FRAME_PACKING: - frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value; - - ret = v4l2_mfc_ext_g_ctrl(pCTX->hMFC, conf_type, &sei_info); - if (ret != 0) { - printf("Error to do ext_g_ctrl.\n"); - } - frame_packing->available = sei_info.sei_avail; - frame_packing->arrangement_id = sei_info.arrgment_id; - - frame_packing->arrangement_cancel_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 0); - frame_packing->arrangement_type = OPERATE_BIT(sei_info.sei_info, 0x3f, 1); - frame_packing->quincunx_sampling_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 8); - frame_packing->content_interpretation_type = OPERATE_BIT(sei_info.sei_info, 0x3f, 9); - frame_packing->spatial_flipping_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 15); - frame_packing->frame0_flipped_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 16); - frame_packing->field_views_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 17); - frame_packing->current_frame_is_frame0_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 18); - - frame_packing->frame0_grid_pos_x = OPERATE_BIT(sei_info.sei_info, 0xf, 0); - frame_packing->frame0_grid_pos_y = OPERATE_BIT(sei_info.sei_info, 0xf, 4); - frame_packing->frame1_grid_pos_x = OPERATE_BIT(sei_info.sei_info, 0xf, 8); - frame_packing->frame1_grid_pos_y = OPERATE_BIT(sei_info.sei_info, 0xf, 12); - break; -#endif - case MFC_DEC_GETCONF_CROP_INFO: - crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value; - crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; - crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset; - crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; - crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset; - break; - - default: - LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c deleted file mode 100644 index 2333b6c..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c +++ /dev/null @@ -1,1506 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include "videodev2.h" - -#include "mfc_interface.h" -#include "SsbSipMfcApi.h" - -/* #define LOG_NDEBUG 0 */ -#define LOG_TAG "MFC_ENC_APP" -#include - -#define POLL_ENC_WAIT_TIMEOUT 25 - -#ifndef true -#define true (1) -#endif - -#ifndef false -#define false (0) -#endif - -#define MAX_STREAM_SIZE (2*1024*1024) - -static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME; -static int mfc_dev_node = 7; - -#if defined (MFC5x_VERSION) -#define H263_CTRL_NUM 19 -#define MPEG4_CTRL_NUM 27 -#define H264_CTRL_NUM 50 -#elif defined (MFC6x_VERSION) -#define H263_CTRL_NUM 20 -#define MPEG4_CTRL_NUM 28 -#define H264_CTRL_NUM 67 -#endif - - -static void getMFCName(char *devicename, int size) -{ - snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node); -} - -void SsbSipMfcEncSetMFCName(char *devicename) -{ - mfc_dev_name = devicename; -} - -void *SsbSipMfcEncOpen(void) -{ - int hMFCOpen; - _MFCLIB *pCTX; - - char mfc_dev_name[64]; - - int ret; - struct v4l2_capability cap; - - LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR); - getMFCName(mfc_dev_name, 64); - LOGI("[%s] dev name is %s\n",__func__,mfc_dev_name); - - if (access(mfc_dev_name, F_OK) != 0) { - LOGE("[%s] MFC device node not exists",__func__); - return NULL; - } - - hMFCOpen = open(mfc_dev_name, O_RDWR | O_NONBLOCK, 0); - if (hMFCOpen < 0) { - LOGE("[%s] Failed to open MFC device",__func__); - return NULL; - } - - pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); - if (pCTX == NULL) { - LOGE("[%s] malloc failed.",__func__); - return NULL; - } - memset(pCTX, 0, sizeof(_MFCLIB)); - - pCTX->hMFC = hMFCOpen; - - memset(&cap, 0, sizeof(cap)); - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap); - if (ret != 0) { - LOGE("[%s] VIDIOC_QUERYCAP failed",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - LOGE("[%s] Device does not support capture",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { - LOGE("[%s] Device does not support output",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - if (!(cap.capabilities & V4L2_CAP_STREAMING)) { - LOGE("[%s] Device does not support streaming",__func__); - close(pCTX->hMFC); - free(pCTX); - return NULL; - } - - pCTX->v4l2_enc.bRunning = 0; - /* physical address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 1; - - pCTX->cacheablebuffer = NO_CACHE; - - return (void *)pCTX; -} - -void *SsbSipMfcEncOpenExt(void *value) -{ - _MFCLIB *pCTX; - - pCTX = SsbSipMfcEncOpen(); - if (pCTX == NULL) - return NULL; - - if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) { - pCTX->cacheablebuffer = NO_CACHE; - /* physical address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 1; - LOGI("[%s] non cacheable buffer",__func__); - } - else { - pCTX->cacheablebuffer = CACHE; - /* vitual address is used for Input source */ - pCTX->v4l2_enc.bInputPhyVir = 0; - LOGI("[%s] cacheable buffer",__func__); - } - - return (void *)pCTX; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) -{ - _MFCLIB *pCTX; - int ret, i; - - enum v4l2_buf_type type; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON); - } - - if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__); - return MFC_RET_CLOSE_FAIL; - } - pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON); - } - - if (!pCTX->v4l2_enc.bInputPhyVir) { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); - } - } - - for (i = 0; i < pCTX->v4l2_enc.mfc_num_dst_bufs; i++) - munmap(pCTX->v4l2_enc.mfc_dst_bufs[i], pCTX->v4l2_enc.mfc_dst_bufs_len); - - pCTX->inter_buff_status = MFC_USE_NONE; - - close(pCTX->hMFC); - - free(pCTX); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) -{ - int ret, i, j,index; - _MFCLIB *pCTX; - - enum v4l2_buf_type type; - struct v4l2_format fmt; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - - struct v4l2_buffer buf; - struct v4l2_requestbuffers reqbuf; - - struct v4l2_control ctrl; - - struct pollfd poll_events; - int poll_state; - - struct v4l2_ext_control ext_ctrl_mpeg4[MPEG4_CTRL_NUM]; - struct v4l2_ext_control ext_ctrl_h263[H263_CTRL_NUM]; - struct v4l2_ext_control ext_ctrl[H264_CTRL_NUM]; - struct v4l2_ext_controls ext_ctrls; - - SSBSIP_MFC_ENC_H264_PARAM *h264_arg; - SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; - SSBSIP_MFC_ENC_H263_PARAM *h263_arg; - - if (openHandle == NULL) - return MFC_RET_INVALID_PARAM; - - pCTX = (_MFCLIB *) openHandle; - - mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; - if (mpeg4_arg->codecType == MPEG4_ENC) { - pCTX->codecType= MPEG4_ENC; - pCTX->width = mpeg4_arg->SourceWidth; - pCTX->height = mpeg4_arg->SourceHeight; - pCTX->framemap = mpeg4_arg->FrameMap; - } else { - h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param; - if (h263_arg->codecType == H263_ENC) { - pCTX->codecType = H263_ENC; - pCTX->width = h263_arg->SourceWidth; - pCTX->height = h263_arg->SourceHeight; - pCTX->framemap = h263_arg->FrameMap; - } else { - h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param; - if (h264_arg->codecType == H264_ENC) { - pCTX->codecType = H264_ENC; - pCTX->width = h264_arg->SourceWidth; - pCTX->height = h264_arg->SourceHeight; - pCTX->framemap = h264_arg->FrameMap; - } else { - LOGE("[%s] Undefined codec type \n",__func__); - ret = MFC_RET_INVALID_PARAM; - goto error_case1; - } - } - } - - switch (pCTX->codecType) { - case MPEG4_ENC: - ext_ctrl_mpeg4[0].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE; - ext_ctrl_mpeg4[0].value = mpeg4_arg->ProfileIDC; - ext_ctrl_mpeg4[1].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL; - ext_ctrl_mpeg4[1].value = mpeg4_arg->LevelIDC; - ext_ctrl_mpeg4[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl_mpeg4[2].value = mpeg4_arg->IDRPeriod; - ext_ctrl_mpeg4[3].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL; - ext_ctrl_mpeg4[3].value = mpeg4_arg->DisableQpelME; - - ext_ctrl_mpeg4[4].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl_mpeg4[4].value = mpeg4_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ - if (mpeg4_arg->SliceMode == 0) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = 1; /* default */ -#if defined (MFC5x_VERSION) - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 1900; /* default */ -#elif defined (MFC6x_VERSION) - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */ -#endif - } else if (mpeg4_arg->SliceMode == 1) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = mpeg4_arg->SliceArgument; -#if defined (MFC5x_VERSION) - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 1900; /* default */ -#elif defined (MFC6x_VERSION) - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */ -#endif - } else if (mpeg4_arg->SliceMode == 3) { - ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl_mpeg4[5].value = 1; /* default */ - ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl_mpeg4[6].value = mpeg4_arg->SliceArgument; - } - /* - * It should be set using mpeg4_arg->NumberBFrames after being handled by appl. - */ - ext_ctrl_mpeg4[7].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES; - ext_ctrl_mpeg4[7].value = mpeg4_arg->NumberBFrames; - ext_ctrl_mpeg4[8].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl_mpeg4[8].value = mpeg4_arg->RandomIntraMBRefresh; - - ext_ctrl_mpeg4[9].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl_mpeg4[9].value = mpeg4_arg->PadControlOn; - ext_ctrl_mpeg4[10].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl_mpeg4[10].value = mpeg4_arg->LumaPadVal; - ext_ctrl_mpeg4[11].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl_mpeg4[11].value = mpeg4_arg->CbPadVal; - ext_ctrl_mpeg4[12].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl_mpeg4[12].value = mpeg4_arg->CrPadVal; - - ext_ctrl_mpeg4[13].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl_mpeg4[13].value = mpeg4_arg->EnableFRMRateControl; - ext_ctrl_mpeg4[14].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES; - ext_ctrl_mpeg4[14].value = mpeg4_arg->TimeIncreamentRes; - ext_ctrl_mpeg4[15].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA; - ext_ctrl_mpeg4[15].value = mpeg4_arg->VopTimeIncreament; - ext_ctrl_mpeg4[16].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - ext_ctrl_mpeg4[16].value = mpeg4_arg->Bitrate; - - ext_ctrl_mpeg4[17].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP; - ext_ctrl_mpeg4[17].value = mpeg4_arg->FrameQp; - ext_ctrl_mpeg4[18].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP; - ext_ctrl_mpeg4[18].value = mpeg4_arg->FrameQp_P; - ext_ctrl_mpeg4[19].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP; - ext_ctrl_mpeg4[19].value = mpeg4_arg->FrameQp_B; - - ext_ctrl_mpeg4[20].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP; - ext_ctrl_mpeg4[20].value = mpeg4_arg->QSCodeMax; - ext_ctrl_mpeg4[21].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP; - ext_ctrl_mpeg4[21].value = mpeg4_arg->QSCodeMin; - ext_ctrl_mpeg4[22].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl_mpeg4[22].value = mpeg4_arg->CBRPeriodRf; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl_mpeg4[24].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl_mpeg4[24].value = 0; - - ext_ctrl_mpeg4[25].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl_mpeg4[25].value = 0; - - ext_ctrl_mpeg4[26].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; - ext_ctrl_mpeg4[26].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - -#if defined (MFC6x_VERSION) - ext_ctrl_mpeg4[27].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MB_ENABLE; /* MFC 6.x Only */ - ext_ctrl_mpeg4[27].value = mpeg4_arg->EnableMBRateControl; -#endif - break; - - case H263_ENC: - ext_ctrl_h263[0].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl_h263[0].value = h263_arg->IDRPeriod; - - ext_ctrl_h263[1].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl_h263[1].value = h263_arg->SliceMode; /* 0: one, Check is needed if h264 support multi-slice */ - - ext_ctrl_h263[2].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl_h263[2].value = h263_arg->RandomIntraMBRefresh; - - ext_ctrl_h263[3].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl_h263[3].value = h263_arg->PadControlOn; - ext_ctrl_h263[4].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl_h263[4].value = h263_arg->LumaPadVal; - ext_ctrl_h263[5].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl_h263[5].value = h263_arg->CbPadVal; - ext_ctrl_h263[6].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl_h263[6].value = h263_arg->CrPadVal; - - ext_ctrl_h263[7].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl_h263[7].value = h263_arg->EnableFRMRateControl; - - ext_ctrl_h263[8].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE; - ext_ctrl_h263[8].value = h263_arg->FrameRate; - - ext_ctrl_h263[9].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - ext_ctrl_h263[9].value = h263_arg->Bitrate; - - ext_ctrl_h263[10].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP; - ext_ctrl_h263[10].value = h263_arg->FrameQp; - ext_ctrl_h263[11].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP; - ext_ctrl_h263[11].value = h263_arg->FrameQp_P; - - ext_ctrl_h263[12].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP; - ext_ctrl_h263[12].value = h263_arg->QSCodeMax; - ext_ctrl_h263[13].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP; - ext_ctrl_h263[13].value = h263_arg->QSCodeMin; - ext_ctrl_h263[14].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl_h263[14].value = h263_arg->CBRPeriodRf; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl_h263[16].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl_h263[16].value = 0; - - ext_ctrl_h263[17].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl_h263[17].value = 0; - - ext_ctrl_h263[18].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; - ext_ctrl_h263[18].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - -#if defined (MFC6x_VERSION) - ext_ctrl_h263[19].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MB_ENABLE; /* MFC 6.x Only */ - ext_ctrl_h263[19].value = h263_arg->EnableMBRateControl; -#endif - break; - - case H264_ENC: - ext_ctrl[0].id = V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE; - ext_ctrl[0].value = h264_arg->ProfileIDC; - ext_ctrl[1].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL; - ext_ctrl[1].value = h264_arg->LevelIDC; - ext_ctrl[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE; - ext_ctrl[2].value = h264_arg->IDRPeriod; - ext_ctrl[3].id = V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC; - ext_ctrl[3].value = h264_arg->NumberReferenceFrames; - ext_ctrl[4].id = V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P; - ext_ctrl[4].value = h264_arg->NumberRefForPframes; - ext_ctrl[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE; - ext_ctrl[5].value = h264_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ - if (h264_arg->SliceMode == 0) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = 1; /* default */ -#if defined (MFC5x_VERSION) - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 1900; /* default */ -#elif defined (MFC6x_VERSION) - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 2800; /* based on MFC6.x */ -#endif - } else if (h264_arg->SliceMode == 1) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = h264_arg->SliceArgument; -#if defined (MFC5x_VERSION) - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 1900; /* default */ -#elif defined (MFC6x_VERSION) - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = 2800; /* based on MFC6.x */ -#endif - } else if (h264_arg->SliceMode == 3) { - ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB; - ext_ctrl[6].value = 1; /* default */ - ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT; - ext_ctrl[7].value = h264_arg->SliceArgument; - } - /* - * It should be set using h264_arg->NumberBFrames after being handled by appl. - */ - ext_ctrl[8].id = V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES; - ext_ctrl[8].value = h264_arg->NumberBFrames; - ext_ctrl[9].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE; - ext_ctrl[9].value = h264_arg->LoopFilterDisable; - ext_ctrl[10].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA; - ext_ctrl[10].value = h264_arg->LoopFilterAlphaC0Offset; - ext_ctrl[11].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA; - ext_ctrl[11].value = h264_arg->LoopFilterBetaOffset; - ext_ctrl[12].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE; - ext_ctrl[12].value = h264_arg->SymbolMode; - ext_ctrl[13].id = V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE; - ext_ctrl[13].value = h264_arg->PictureInterlace; - ext_ctrl[14].id = V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM; - ext_ctrl[14].value = h264_arg->Transform8x8Mode; - ext_ctrl[15].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB; - ext_ctrl[15].value = h264_arg->RandomIntraMBRefresh; - ext_ctrl[16].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE; - ext_ctrl[16].value = h264_arg->PadControlOn; - ext_ctrl[17].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE; - ext_ctrl[17].value = h264_arg->LumaPadVal; - ext_ctrl[18].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE; - ext_ctrl[18].value = h264_arg->CbPadVal; - ext_ctrl[19].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE; - ext_ctrl[19].value = h264_arg->CrPadVal; - ext_ctrl[20].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE; - ext_ctrl[20].value = h264_arg->EnableFRMRateControl; - ext_ctrl[21].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE; - ext_ctrl[21].value = h264_arg->EnableMBRateControl; - ext_ctrl[22].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE; - ext_ctrl[22].value = h264_arg->FrameRate; - ext_ctrl[23].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE; - /* FIXME temporary fix */ - if (h264_arg->Bitrate) - ext_ctrl[23].value = h264_arg->Bitrate; - else - ext_ctrl[23].value = 1; /* just for testing Movi studio */ - ext_ctrl[24].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP; - ext_ctrl[24].value = h264_arg->FrameQp; - ext_ctrl[25].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP; - ext_ctrl[25].value = h264_arg->FrameQp_P; - ext_ctrl[26].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP; - ext_ctrl[26].value = h264_arg->FrameQp_B; - ext_ctrl[27].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP; - ext_ctrl[27].value = h264_arg->QSCodeMax; - ext_ctrl[28].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP; - ext_ctrl[28].value = h264_arg->QSCodeMin; - ext_ctrl[29].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF; - ext_ctrl[29].value = h264_arg->CBRPeriodRf; - ext_ctrl[30].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK; - ext_ctrl[30].value = h264_arg->DarkDisable; - ext_ctrl[31].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH; - ext_ctrl[31].value = h264_arg->SmoothDisable; - ext_ctrl[32].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC; - ext_ctrl[32].value = h264_arg->StaticDisable; - ext_ctrl[33].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY; - ext_ctrl[33].value = h264_arg->ActivityDisable; - - /* doesn't have to be set */ - ext_ctrl[34].id = V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP; - ext_ctrl[34].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[35].id = V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD; - ext_ctrl[35].value = 10; - - if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) { - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL; - } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) { - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE; - } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */ - ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE; - ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE; - } - - ext_ctrl[37].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE; - ext_ctrl[37].value = 0; - - ext_ctrl[38].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE; - ext_ctrl[38].value = 0; /* 0: seperated header, 1: header + first frame */ - - ext_ctrl[39].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE; - ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC; - ext_ctrl[40].value = 0; - ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH; - ext_ctrl[41].value = 0; - ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT; - ext_ctrl[42].value = 0; - - if (pCTX->hier_p_enable) { - ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE; - ext_ctrl[43].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP; - ext_ctrl[44].value = pCTX->hier_qp_value.t0_frame_qp; - ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP; - ext_ctrl[45].value = pCTX->hier_qp_value.t2_frame_qp; - ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP; - ext_ctrl[46].value = pCTX->hier_qp_value.t3_frame_qp; - } else { - ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE; - ext_ctrl[43].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP; - ext_ctrl[44].value = 0; - ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP; - ext_ctrl[45].value = 0; - ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP; - ext_ctrl[46].value = 0; - } -#ifdef S3D_SUPPORT - if (pCTX->sei_info.sei_gen_enable) { - ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG; - ext_ctrl[47].value = pCTX->sei_info.curr_frame_frm0_flag; - ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE; - ext_ctrl[48].value = pCTX->sei_info.frame_pack_arrgment_type; - } else { - ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG; - ext_ctrl[47].value = 0; - ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE; - ext_ctrl[48].value = 3; - } -#else - ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG; - ext_ctrl[47].value = 0; - ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE; - ext_ctrl[48].value = 3; -#endif -#if defined (MFC5x_VERSION) - ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; /* MFC5.x Only */ - ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; -#elif defined (MFC6x_VERSION) - if (pCTX->fmo_enable) { - ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_ENABLE; - ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - ext_ctrl[50].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_MAP_TYPE; - ext_ctrl[50].value = pCTX->fmo_value.slice_map_type; - ext_ctrl[51].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SLICE_NUM; - ext_ctrl[51].value = pCTX->fmo_value.slice_num_grp; - if (pCTX->fmo_value.slice_map_type == 0) { - ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1; - ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2; - ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3; - ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4; - for (i = 0; i < pCTX->fmo_value.slice_num_grp; i++) - ext_ctrl[52+i].value = pCTX->fmo_value.run_length[i]; - for (i = pCTX->fmo_value.slice_num_grp; i < 4; i++); - ext_ctrl[52+i].value = 1; - } else { - ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1; - ext_ctrl[52].value = 1; - ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2; - ext_ctrl[53].value = 1; - ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3; - ext_ctrl[54].value = 1; - ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4; - ext_ctrl[55].value = 1; - } - if (pCTX->fmo_value.slice_map_type == 4 || pCTX->fmo_value.slice_map_type == 5) { - ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR; - ext_ctrl[56].value = pCTX->fmo_value.sg_dir; - ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE; - ext_ctrl[57].value = pCTX->fmo_value.sg_rate; - } else { - ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR; - ext_ctrl[56].value = 0; - ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE; - ext_ctrl[57].value = 1; - } - } else { - ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_ENABLE; - ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[50].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_MAP_TYPE; - ext_ctrl[50].value = 0; - ext_ctrl[51].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SLICE_NUM; - ext_ctrl[51].value = 1; - ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1; - ext_ctrl[52].value = 1; - ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2; - ext_ctrl[53].value = 1; - ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3; - ext_ctrl[54].value = 1; - ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4; - ext_ctrl[55].value = 1; - ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR; - ext_ctrl[56].value = 0; - ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE; - ext_ctrl[57].value = 1; - } - if (pCTX->aso_enable) { - ext_ctrl[58].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_ENABLE; - ext_ctrl[58].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE; - ext_ctrl[59].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_0; - ext_ctrl[59].value = pCTX->aso_sl_order[0]; - ext_ctrl[60].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_1; - ext_ctrl[60].value = pCTX->aso_sl_order[1]; - ext_ctrl[61].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_2; - ext_ctrl[61].value = pCTX->aso_sl_order[2]; - ext_ctrl[62].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_3; - ext_ctrl[62].value = pCTX->aso_sl_order[3]; - ext_ctrl[63].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_4; - ext_ctrl[63].value = pCTX->aso_sl_order[4]; - ext_ctrl[64].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_5; - ext_ctrl[64].value = pCTX->aso_sl_order[5]; - ext_ctrl[65].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_6; - ext_ctrl[65].value = pCTX->aso_sl_order[6]; - ext_ctrl[66].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_7; - ext_ctrl[66].value = pCTX->aso_sl_order[7]; - } else { - ext_ctrl[58].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_ENABLE; - ext_ctrl[58].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE; - ext_ctrl[59].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_0; - ext_ctrl[59].value = 0; - ext_ctrl[60].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_1; - ext_ctrl[60].value = 0; - ext_ctrl[61].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_2; - ext_ctrl[61].value = 0; - ext_ctrl[62].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_3; - ext_ctrl[62].value = 0; - ext_ctrl[63].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_4; - ext_ctrl[63].value = 0; - ext_ctrl[64].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_5; - ext_ctrl[64].value = 0; - ext_ctrl[65].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_6; - ext_ctrl[65].value = 0; - ext_ctrl[66].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_7; - ext_ctrl[66].value = 0; - } -#endif - break; - - default: - LOGE("[%s] Undefined codec type",__func__); - ret = MFC_RET_INVALID_PARAM; - goto error_case1; - } - - ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC; - if (pCTX->codecType == MPEG4_ENC) { - ext_ctrls.count = MPEG4_CTRL_NUM; - ext_ctrls.controls = ext_ctrl_mpeg4; - } else if (pCTX->codecType == H264_ENC) { - ext_ctrls.count = H264_CTRL_NUM; - ext_ctrls.controls = ext_ctrl; - } else if (pCTX->codecType == H263_ENC) { - ext_ctrls.count = H263_CTRL_NUM; - ext_ctrls.controls = ext_ctrl_h263; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_S_EXT_CTRLS, &ext_ctrls); - if (ret != 0) { - LOGE("[%s] Failed to set extended controls",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - fmt.fmt.pix_mp.width = pCTX->width; - fmt.fmt.pix_mp.height = pCTX->height; - fmt.fmt.pix_mp.num_planes = 2; -#if 0 - fmt.fmt.pix_mp.plane_fmt[0].bytesperline = Align(fmt.fmt.pix_mp.width, 128); - fmt.fmt.pix_mp.plane_fmt[1].bytesperline = Align(fmt.fmt.pix_mp.width, 128); - - if (NV12_TILE == pCTX->framemap) { - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 64x32 Tiles */ - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = - Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height, 32), 8192); /* tiled mode */ - fmt.fmt.pix_mp.plane_fmt[1].sizeimage = - Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height >> 1, 32), 8192); /* tiled mode */ - } else { /* NV12_LINEAR (default) */ - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = - Align((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height), 2048); /* linear mode, 2K align */ - fmt.fmt.pix_mp.plane_fmt[1].sizeimage = - Align((fmt.fmt.pix_mp.width * (fmt.fmt.pix_mp.height >> 1)), 2048); /* linear mode, 2K align */ - } -#else /* FIXME: */ - if (NV12_TILE == pCTX->framemap) { - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; /* 4:2:0, 2 Planes, 16x16 Tiles */ - } else { /* NV12_LINEAR (default) */ - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */ - } -#endif - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed on MFC output stream",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* capture (dst) */ - memset(&fmt, 0, sizeof(fmt)); - - switch (pCTX->codecType) { - case H264_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; - break; - case MPEG4_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4; - break; - case H263_ENC: - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263; - break; - default: - LOGE("[%s] Codec has not been recognised",__func__); - return MFC_RET_ENC_INIT_FAIL; - } - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt); - if (ret != 0) { - LOGE("[%s] S_FMT failed on MFC output stream",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* cacheable buffer */ - ctrl.id = V4L2_CID_CACHEABLE; - if (pCTX->cacheablebuffer == NO_CACHE) - ctrl.value = 0; - else - ctrl.value = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - - /* Initialize streams for input */ - memset(&reqbuf, 0, sizeof(reqbuf)); - reqbuf.count = MFC_ENC_NUM_SRC_BUFS; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - if (pCTX->v4l2_enc.bInputPhyVir) - reqbuf.memory = V4L2_MEMORY_USERPTR; - else - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] Reqbufs src ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case1; - } - pCTX->v4l2_enc.mfc_num_src_bufs = reqbuf.count; - - if (!pCTX->v4l2_enc.bInputPhyVir) { - /* Then the buffers have to be queried and mmaped */ - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; ++i) { - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - buf.m.planes = planes; - buf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); - if (ret != 0) { - LOGE("[%s] Querybuf src ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_src_bufs_len[0] = buf.m.planes[0].length; - pCTX->v4l2_enc.mfc_src_bufs_len[1] = buf.m.planes[1].length; - - pCTX->v4l2_enc.mfc_src_phys[i][0] = buf.m.planes[0].cookie; - pCTX->v4l2_enc.mfc_src_phys[i][1] = buf.m.planes[1].cookie; - - pCTX->v4l2_enc.mfc_src_bufs[i][0] = - mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == MAP_FAILED) { - LOGE("[%s] Mmap on src buffer (0) failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_src_bufs[i][1] = - mmap(NULL, buf.m.planes[1].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset); - if (pCTX->v4l2_enc.mfc_src_bufs[i][1] == MAP_FAILED) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - LOGE("[%s] Mmap on src buffer (1) failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - } - } else - LOGV("[%s] Camera Phys src buf %d",__func__,reqbuf.count); - - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) - pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_DEQUEUED; - - pCTX->v4l2_enc.beingUsedIndex = 0; - - pCTX->sizeFrmBuf.luma = (unsigned int)(pCTX->width * pCTX->height); - pCTX->sizeFrmBuf.chroma = (unsigned int)((pCTX->width * pCTX->height) >> 1); - pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; - - /* Initialize stream for output */ - memset(&reqbuf, 0, sizeof(reqbuf)); - reqbuf.count = MFC_ENC_MAX_DST_BUFS; - reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - reqbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf); - if (ret != 0) { - LOGE("[%s] Reqbufs dst ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case2; - } - - pCTX->v4l2_enc.mfc_num_dst_bufs = reqbuf.count; - - for (i = 0; i < MFC_ENC_MAX_DST_BUFS; ++i) { - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - buf.m.planes = planes; - buf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf); - if (ret != 0) { - LOGE("[%s] Querybuf dst ioctl failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - pCTX->v4l2_enc.mfc_dst_bufs_len = buf.m.planes[0].length; - pCTX->v4l2_enc.mfc_dst_bufs[i] = - mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, - MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset); - if (pCTX->v4l2_enc.mfc_dst_bufs[i] == MAP_FAILED) { - LOGE("[%s] Mmap on dst buffer failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } - - pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; - pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, VIDIOC_STREAMON failed",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - - pCTX->inter_buff_status |= MFC_USE_DST_STREAMON; - - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.m.planes = planes; - buf.length = 1; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLIN | POLLERR; - poll_events.revents = 0; - - /* wait for header encoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLIN) { /* POLLIN */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &buf); - if (ret == 0) - break; - } else if (poll_events.revents & POLLERR) { /*POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } else if (0 > poll_state) { - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - } while (1 == poll_state); - - pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused; - pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_enc.mfc_dst_bufs[buf.index]; - - /* stream dequeued index */ - index = buf.index; - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = index; - buf.m.planes = planes; - buf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - ret = MFC_RET_ENC_INIT_FAIL; - goto error_case3; - } - LOGV("[%s] Strm out idx %d",__func__,index); - - return MFC_RET_OK; - -error_case3: - for (j = 0; j < i; j++) - munmap(pCTX->v4l2_enc.mfc_dst_bufs[j], pCTX->v4l2_enc.mfc_dst_bufs_len); - - i = pCTX->v4l2_enc.mfc_num_src_bufs; -error_case2: - if (!pCTX->v4l2_enc.bInputPhyVir) { - for (j = 0; j < i; j++) { - munmap(pCTX->v4l2_enc.mfc_src_bufs[j][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]); - munmap(pCTX->v4l2_enc.mfc_src_bufs[j][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]); - } - } -error_case1: - return ret; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - _MFCLIB *pCTX; - int i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - /* FIXME check this if GetInBuf() is not called for UserPtr */ - if (pCTX->v4l2_enc.bInputPhyVir) { - input_info->YPhyAddr = (void*)0; - input_info->CPhyAddr = (void*)0; - input_info->YVirAddr = (void*)0; - input_info->CVirAddr = (void*)0; - - /* FIXME check whether Y & C sizes should be set or not*/ - if (NV12_TILE == pCTX->framemap) { - /* 4:2:0, 2 Planes, 64x32 Tiles */ - input_info->YSize = Align(Align(pCTX->width, 128) * Align(pCTX->height, 32), 8192); /* tiled mode */ - input_info->CSize = Align(Align(pCTX->width, 128) * Align(pCTX->height >> 1, 32), 8192); /* tiled mode */ - } else { /* NV12_LINEAR (default) */ - /* 4:2:0, 2 Planes, linear */ - input_info->YSize = Align(Align(pCTX->width, 16) * Align(pCTX->height, 16), 2048); /* width = 16B, height = 16B align */ - input_info->CSize = Align(Align(pCTX->width, 16) * Align(pCTX->height >> 1, 8), 2048); /* width = 16B, height = 8B align */ - } - } else { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) - if (BUF_DEQUEUED == pCTX->v4l2_enc.mfc_src_buf_flags[i]) - break; - - if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { - LOGV("[%s] No buffer is available.",__func__); - return MFC_RET_ENC_GET_INBUF_FAIL; - } else { - input_info->YPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][0]; - input_info->CPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][1]; - input_info->YVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][0]; - input_info->CVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][1]; - input_info->YSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[0]; - input_info->CSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[1]; - - pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - } - LOGV("[%s] Input Buffer idx %d",__func__,i); - return MFC_RET_OK; -} - - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) -{ - _MFCLIB *pCTX; - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - int ret,i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - memset(&qbuf, 0, sizeof(qbuf)); - if (pCTX->v4l2_enc.bInputPhyVir) { - qbuf.memory = V4L2_MEMORY_USERPTR; - qbuf.index = pCTX->v4l2_enc.beingUsedIndex; - planes[0].m.userptr = (unsigned long)input_info->YPhyAddr; - planes[0].length = input_info->YSize; - planes[0].bytesused = input_info->YSize; - planes[1].m.userptr = (unsigned long)input_info->CPhyAddr; - planes[1].length = input_info->CSize; - planes[1].bytesused = input_info->CSize; - - /* FIXME, this is only for case of not using B frame, - Camera side should know which buffer is queued() refering to index of - MFC dqbuf() */ - pCTX->v4l2_enc.beingUsedIndex++; - pCTX->v4l2_enc.beingUsedIndex %= MFC_ENC_NUM_SRC_BUFS; - LOGV("[%s] Phy Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); - } else { - for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) - if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == input_info->YVirAddr) - break; - - if (i == pCTX->v4l2_enc.mfc_num_src_bufs) { - LOGE("[%s] Can not use the buffer",__func__); - return MFC_RET_INVALID_PARAM; - } else { - pCTX->v4l2_enc.beingUsedIndex = i; - //pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED; - } - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = pCTX->v4l2_enc.beingUsedIndex; - planes[0].bytesused = pCTX->width * pCTX->height; - planes[1].bytesused = (pCTX->width * pCTX->height) >> 1; - LOGV("[%s] Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex); - } - - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - qbuf.m.planes = planes; - qbuf.length = 2; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_SET_INBUF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) -{ - _MFCLIB *pCTX; - struct v4l2_control ctrl; - unsigned int encoded_y_addr, encoded_c_addr; - int ret; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - if (pCTX->v4l2_enc.bRunning == 0) { - pCTX->encodedHeaderSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; - output_info->dataSize = 0; - } else { - output_info->dataSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len; - } - - ctrl.id = V4L2_CID_CODEC_ENCODED_LUMA_ADDR; - ctrl.value = 0; - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) - LOGE("[%s] Error to do g_ctrl",__func__); - encoded_y_addr = (unsigned int)ctrl.value; - - ctrl.id = V4L2_CID_CODEC_ENCODED_CHROMA_ADDR; - ctrl.value = 0; - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) - LOGE("[%s] Error to do g_ctrl",__func__); - encoded_c_addr = (unsigned int)ctrl.value; - - output_info->headerSize = pCTX->encodedHeaderSize; - output_info->frameType = pCTX->encodedframeType; - output_info->StrmPhyAddr = (void *)0; - output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; - output_info->encodedYPhyAddr = (void*)encoded_y_addr; - output_info->encodedCPhyAddr = (void*)encoded_c_addr; - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) -{ - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_ENC_SET_OUTBUF_FAIL; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) -{ - int ret; - int dequeued_index; - int loopcnt = 0; - _MFCLIB *pCTX; - - struct v4l2_buffer qbuf; - struct v4l2_plane planes[MFC_ENC_NUM_PLANES]; - enum v4l2_buf_type type; - - struct v4l2_control ctrl; - - struct pollfd poll_events; - int poll_state; - - LOGV("[%s] Enter \n",__func__); - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = pCTX->inframetag; - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - if (pCTX->v4l2_enc.bRunning == 0) { - type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type); - if (ret != 0) { - LOGE("[%s] VIDIOC_STREAMON failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - pCTX->v4l2_enc.bRunning = 1; - } - - pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON; - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.m.planes = planes; - qbuf.length = 1; - - /* note: #define POLLOUT 0x0004 */ - poll_events.fd = pCTX->hMFC; - poll_events.events = POLLIN | POLLERR; - poll_events.revents = 0; - - /* wait for encoding */ - do { - poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT); - if (0 < poll_state) { - if (poll_events.revents & POLLIN) { /* POLLIN */ - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret == 0) - break; - } else if (poll_events.revents & POLLERR) { /* POLLERR */ - LOGE("[%s] POLLERR\n",__func__); - return MFC_RET_ENC_EXE_ERR; - } else { - LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents); - return MFC_RET_ENC_EXE_ERR; - } - } else if (0 > poll_state) { - LOGE("[%s] poll() Encoder POLL Timeout 0x%x\n",__func__, poll_events.revents); - return MFC_RET_ENC_EXE_ERR; - } else { /* in the case of B frame encoding */ - ctrl.id = V4L2_CID_CODEC_CHECK_STATE; - ctrl.value = 0; - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - LOGV("[%s] ctx state = %d\n",__func__, ctrl.value); - if (ctrl.value == MFCSTATE_ENC_NO_OUTPUT) - return MFC_RET_OK; - } - loopcnt++; - } while ((0 == poll_state) && (loopcnt < 5)); - - if (pCTX->v4l2_enc.bRunning != 0) { - pCTX->encodedframeType = (qbuf.flags & 0x38) >> 3; /* encoded frame type */ - LOGV("[%s] encoded frame type = %d\n", __func__, pCTX->encodedframeType); - - switch (pCTX->encodedframeType) { - case 1: - pCTX->encodedframeType = MFC_FRAME_TYPE_I_FRAME; - break; - case 2: - pCTX->encodedframeType = MFC_FRAME_TYPE_P_FRAME; - break; - case 4: - pCTX->encodedframeType = MFC_FRAME_TYPE_B_FRAME; - break; - default: - LOGE("[%s] VIDIOC_DQBUF failed, encoded frame type is wrong",__func__); - } - } - - dequeued_index = qbuf.index; - - if (qbuf.m.planes[0].bytesused > 0) { /* FIXME later */ - pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = qbuf.m.planes[0].bytesused; - } - - ctrl.id = V4L2_CID_CODEC_FRAME_TAG; - ctrl.value = 0; - - ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - pCTX->outframetagtop = ctrl.value; - - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - qbuf.memory = V4L2_MEMORY_MMAP; - qbuf.index = dequeued_index; - qbuf.m.planes = planes; - qbuf.length = 1; - - ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - - if (pCTX->v4l2_enc.bRunning != 0) { - memset(&qbuf, 0, sizeof(qbuf)); - qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - if (pCTX->v4l2_enc.bInputPhyVir) - qbuf.memory = V4L2_MEMORY_USERPTR; - else - qbuf.memory = V4L2_MEMORY_MMAP; - - ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf); - if (ret != 0) { - LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__); - return MFC_RET_ENC_EXE_ERR; - } - } - pCTX->v4l2_enc.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED; - - /* Update context stream buffer address */ - pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_enc.mfc_dst_bufs[dequeued_index]; - LOGV("[%s] Strm out idx %d",__func__,dequeued_index); - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - struct v4l2_control ctrl; - struct mfc_enc_hier_p_qp hier_p_qp; -#ifdef S3D_SUPPORT - SSBSIP_MFC_FRAME_PACKING *frame_packing; -#endif - struct mfc_enc_fmo fmo_param; - int *aso_param; - int ret, i; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - pCTX = (_MFCLIB *) openHandle; - - switch (conf_type) { - case MFC_ENC_SETCONF_FRAME_TAG: - pCTX->inframetag = *((unsigned int *)value); - return MFC_RET_OK; - - case MFC_ENC_SETCONF_FRAME_TYPE: - ctrl.id = V4L2_CID_CODEC_FRAME_INSERTION; - ctrl.value = *((unsigned int*)value); - break; - - case MFC_ENC_SETCONF_I_PERIOD: - ctrl.id = V4L2_CID_CODEC_ENCODED_I_PERIOD_CH; - ctrl.value = *((unsigned int*)value); - break; - - case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: - ctrl.id = V4L2_CID_CODEC_ENCODED_FRAME_RATE_CH; - ctrl.value = *((unsigned int*)value); - break; - - case MFC_ENC_SETCONF_CHANGE_BIT_RATE: - ctrl.id = V4L2_CID_CODEC_ENCODED_BIT_RATE_CH; - ctrl.value = *((unsigned int*)value); - break; -#ifdef S3D_SUPPORT - case MFC_ENC_SETCONF_SEI_GEN: - ctrl.id = V4L2_CID_CODEC_FRAME_PACK_SEI_GEN; - ctrl.value = *((unsigned int*)value); - pCTX->sei_info.sei_gen_enable = 1; - break; -#endif - case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: - pCTX->enc_frameskip = *((int *)value); - return MFC_RET_OK; -#if 0 - case MFC_ENC_SETCONF_VUI_INFO: - vui_info = *((struct mfc_enc_vui_info *) value); - EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc); - EncArg.args.set_config.in_config_value[1] = 0; - break; -#endif - case MFC_ENC_SETCONF_HIER_P: - hier_p_qp = *((struct mfc_enc_hier_p_qp *) value); - pCTX->hier_p_enable = 1; - pCTX->hier_qp_value.t0_frame_qp = (int)(hier_p_qp.t0_frame_qp); - pCTX->hier_qp_value.t2_frame_qp = (int)(hier_p_qp.t2_frame_qp); - pCTX->hier_qp_value.t3_frame_qp = (int)(hier_p_qp.t3_frame_qp); - return MFC_RET_OK; -#ifdef S3D_SUPPORT - case MFC_ENC_SETCONF_FRAME_PACKING: - frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value; - pCTX->sei_info.curr_frame_frm0_flag = (int)(frame_packing->current_frame_is_frame0_flag); - pCTX->sei_info.frame_pack_arrgment_type = (int)(frame_packing->arrangement_type); - return MFC_RET_OK; -#endif - case MFC_ENC_SETCONF_FMO: - fmo_param = *((struct mfc_enc_fmo *) value); - pCTX->fmo_enable = 1; - pCTX->fmo_value.slice_map_type = (int)(fmo_param.slice_map_type); - pCTX->fmo_value.slice_num_grp = (int)(fmo_param.slice_num_grp); - pCTX->fmo_value.run_length[0] = (int)(fmo_param.run_length[0]); - pCTX->fmo_value.run_length[1] = (int)(fmo_param.run_length[1]); - pCTX->fmo_value.run_length[2] = (int)(fmo_param.run_length[2]); - pCTX->fmo_value.run_length[3] = (int)(fmo_param.run_length[3]); - pCTX->fmo_value.sg_dir = (int)(fmo_param.sg_dir); - pCTX->fmo_value.sg_rate = (int)(fmo_param.sg_rate); - return MFC_RET_OK; - - case MFC_ENC_SETCONF_ASO: - aso_param = (int *) value; - pCTX->aso_enable = 1; - for (i = 0; i < 8; i++) - pCTX->aso_sl_order[i] = (int)aso_param[i]; - return MFC_RET_OK; - - default: - LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl); - if (ret != 0) { - LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type); - return MFC_RET_ENC_SET_CONF_FAIL; - } - - return MFC_RET_OK; -} - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) -{ - _MFCLIB *pCTX; - - pCTX = (_MFCLIB *) openHandle; - - if (openHandle == NULL) { - LOGE("[%s] openHandle is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - if (value == NULL) { - LOGE("[%s] value is NULL\n",__func__); - return MFC_RET_INVALID_PARAM; - } - - switch (conf_type) { - case MFC_ENC_GETCONF_FRAME_TAG: - *((unsigned int *)value) = pCTX->outframetagtop; - break; - - default: - LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type); - return MFC_RET_INVALID_PARAM; - } - - return MFC_RET_OK; -} - diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h deleted file mode 100644 index b386c72..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SSBSIP_MFC_API_H_ -#define _SSBSIP_MFC_API_H_ - -/*--------------------------------------------------------------------------------*/ -/* Definition */ -/*--------------------------------------------------------------------------------*/ -#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) -#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) - -#define MFC6x_VERSION - -#define SUPPORT_1080P 1 - -#if SUPPORT_1080P -#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/ -#else -#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024) -#endif - -#define SAMSUNG_MFC_DEV_NAME "/dev/video" - -#define SSBSIP_MFC_OK (1) -#define SSBSIP_MFC_FAIL (0) - -/*--------------------------------------------------------------------------------*/ -/* Structure and Type */ -/*--------------------------------------------------------------------------------*/ -typedef enum { - H264_DEC, - VC1_DEC, /* VC1 advaced Profile decoding */ - MPEG4_DEC, - XVID_DEC, - MPEG1_DEC, - MPEG2_DEC, - H263_DEC, - VC1RCV_DEC, /* VC1 simple/main profile decoding */ - FIMV1_DEC, - FIMV2_DEC, - FIMV3_DEC, - FIMV4_DEC, -#if defined (MFC6x_VERSION) - VP8_DEC, -#endif - H264_ENC, - MPEG4_ENC, - H263_ENC, - UNKNOWN_TYPE -} SSBSIP_MFC_CODEC_TYPE; - -typedef enum { - DONT_CARE = 0, - I_FRAME = 1, - NOT_CODED = 2 -} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; - -typedef enum { - NV12_LINEAR = 0, - NV12_TILE, - NV21_LINEAR -} SSBSIP_MFC_INSTRM_MODE_TYPE; - -typedef enum { - FRAME = 0, - SLICE, -} SSBSIP_MFC_OUTSTRM_MODE_TYPE; - -typedef enum { - NO_CACHE = 0, - CACHE = 1 -} SSBIP_MFC_BUFFER_TYPE; - -typedef enum { - MFC_DEC_SETCONF_POST_ENABLE = 1, - MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, - MFC_DEC_SETCONF_DISPLAY_DELAY, - MFC_DEC_SETCONF_IS_LAST_FRAME, - MFC_DEC_SETCONF_SLICE_ENABLE, - MFC_DEC_SETCONF_CRC_ENABLE, - MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, - MFC_DEC_SETCONF_FRAME_TAG, - MFC_DEC_GETCONF_CRC_DATA, - MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, - MFC_DEC_GETCONF_CROP_INFO, - MFC_DEC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY, - MFC_DEC_SETCONF_DPB_FLUSH, - MFC_DEC_SETCONF_PIXEL_CACHE, - MFC_DEC_GETCONF_WIDTH_HEIGHT, -#ifdef S3D_SUPPORT - /* S3D specific feature */ - MFC_DEC_SETCONF_SEI_PARSE, - MFC_DEC_GETCONF_FRAME_PACKING -#endif -} SSBSIP_MFC_DEC_CONF; - -typedef enum { - MFC_ENC_SETCONF_FRAME_TYPE = 100, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - MFC_ENC_SETCONF_FRAME_TAG, - MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, - MFC_ENC_GETCONF_FRAME_TAG, - - /* C210 specific feature */ - MFC_ENC_SETCONF_VUI_INFO, - MFC_ENC_SETCONF_I_PERIOD, - MFC_ENC_SETCONF_HIER_P, -#ifdef S3D_SUPPORT - /* S3D Specific feature */ - MFC_ENC_SETCONF_SEI_GEN, - MFC_ENC_SETCONF_FRAME_PACKING, -#endif - MFC_ENC_SETCONF_FMO, - MFC_ENC_SETCONF_ASO, -} SSBSIP_MFC_ENC_CONF; - -typedef enum { - MFC_GETOUTBUF_STATUS_NULL = 0, - MFC_GETOUTBUF_DECODING_ONLY = 1, - MFC_GETOUTBUF_DISPLAY_DECODING, - MFC_GETOUTBUF_DISPLAY_ONLY, - MFC_GETOUTBUF_DISPLAY_END, - MFC_GETOUTBUF_CHANGE_RESOL -} SSBSIP_MFC_DEC_OUTBUF_STATUS; - -typedef enum { - MFC_FRAME_TYPE_NOT_CODED, - MFC_FRAME_TYPE_I_FRAME, - MFC_FRAME_TYPE_P_FRAME, - MFC_FRAME_TYPE_B_FRAME, - MFC_FRAME_TYPE_OTHERS -} SSBSIP_MFC_FRAME_TYPE; - -typedef enum { - MFC_RET_OK = 1, - MFC_RET_FAIL = -1000, - MFC_RET_OPEN_FAIL = -1001, - MFC_RET_CLOSE_FAIL = -1002, - - MFC_RET_DEC_INIT_FAIL = -2000, - MFC_RET_DEC_EXE_TIME_OUT = -2001, - MFC_RET_DEC_EXE_ERR = -2002, - MFC_RET_DEC_GET_INBUF_FAIL = -2003, - MFC_RET_DEC_SET_INBUF_FAIL = -2004, - MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, - MFC_RET_DEC_GET_CONF_FAIL = -2006, - MFC_RET_DEC_SET_CONF_FAIL = -2007, - - MFC_RET_ENC_INIT_FAIL = -3000, - MFC_RET_ENC_EXE_TIME_OUT = -3001, - MFC_RET_ENC_EXE_ERR = -3002, - MFC_RET_ENC_GET_INBUF_FAIL = -3003, - MFC_RET_ENC_SET_INBUF_FAIL = -3004, - MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, - MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, - MFC_RET_ENC_GET_CONF_FAIL = -3007, - MFC_RET_ENC_SET_CONF_FAIL = -3008, - - MFC_RET_INVALID_PARAM = -4000 -} SSBSIP_MFC_ERROR_CODE; - -typedef struct { - void *YPhyAddr; /* [OUT] physical address of Y */ - void *CPhyAddr; /* [OUT] physical address of CbCr */ - void *YVirAddr; /* [OUT] virtual address of Y */ - void *CVirAddr; /* [OUT] virtual address of CbCr */ - - int img_width; /* [OUT] width of real image */ - int img_height; /* [OUT] height of real image */ - int buf_width; /* [OUT] width aligned to 16 */ - int buf_height; /* [OUT] height alighed to 16 */ - - int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */ - int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */ - int consumedByte; /* [OUT] the number of byte consumed during decoding */ - int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */ - int crop_top_offset; /* [OUT] crop information, top_offset */ - int crop_bottom_offset; /* [OUT] crop information, bottom_offset */ - int crop_left_offset; /* [OUT] crop information, left_offset */ - int crop_right_offset; /* [OUT] crop information, right_offset */ - int disp_pic_frame_type; /* [OUT] display picture frame type information */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_DEC_OUTPUT_INFO; - -typedef struct { - void *YPhyAddr; /* [IN/OUT] physical address of Y */ - void *CPhyAddr; /* [IN/OUT] physical address of CbCr */ - void *YVirAddr; /* [IN/OUT] virtual address of Y */ - void *CVirAddr; /* [IN/OUT] virtual address of CbCr */ - int YSize; /* [IN/OUT] input size of Y data */ - int CSize; /* [IN/OUT] input size of CbCr data */ - - /* C210 UMP feature */ - unsigned int y_cookie; /* [OUT] cookie for Y address */ - unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_INPUT_INFO; - -typedef struct { - unsigned int dataSize; /* [OUT] encoded data size(without header) */ - unsigned int headerSize; /* [OUT] encoded header size */ - unsigned int frameType; /* [OUT] frame type of encoded stream */ - void *StrmPhyAddr; /* [OUT] physical address of Y */ - void *StrmVirAddr; /* [OUT] virtual address of Y */ - void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */ - void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */ - - /* C210 UMP feature */ - unsigned int strm_cookie; /* [OUT] cooke for stream buffer */ - unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */ - unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */ -} SSBSIP_MFC_ENC_OUTPUT_INFO; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */ - - /* H.264 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int NumberReferenceFrames; /* [IN] The number of reference pictures used */ - int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */ - int LoopFilterDisable; /* [IN] disable the loop filter */ - int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */ - int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */ - int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ - int PictureInterlace; /* [IN] Enables the interlace mode */ - int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */ - int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ - int DarkDisable; /* [IN] Disable adaptive rate control on dark region */ - int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */ - int StaticDisable; /* [IN] Disable adaptive rate control on static region */ - int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */ -} SSBSIP_MFC_ENC_H264_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ - SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */ -#if defined (MFC6x_VERSION) - int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */ -#endif - - /* MPEG4 specific parameters */ - int ProfileIDC; /* [IN] profile */ - int LevelIDC; /* [IN] level */ - int FrameQp_B; /* [IN] The quantization parameter of the B frame */ - int TimeIncreamentRes; /* [IN] frame rate */ - int VopTimeIncreament; /* [IN] frame rate */ - int SliceArgument; /* [IN] MB number or byte number */ - int NumberBFrames; /* [IN] The number of consecutive B frame inserted */ - int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */ -} SSBSIP_MFC_ENC_MPEG4_PARAM; - -typedef struct { - /* common parameters */ - SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */ - int SourceWidth; /* [IN] width of video to be encoded */ - int SourceHeight; /* [IN] height of video to be encoded */ - int IDRPeriod; /* [IN] GOP number(interval of I-frame) */ - int SliceMode; /* [IN] Multi slice mode */ - int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */ - int EnableFRMRateControl; /* [IN] frame based rate control enable */ - int Bitrate; /* [IN] rate control parameter(bit rate) */ - int FrameQp; /* [IN] The quantization parameter of the frame */ - int FrameQp_P; /* [IN] The quantization parameter of the P frame */ - int QSCodeMax; /* [IN] Maximum Quantization value */ - int QSCodeMin; /* [IN] Minimum Quantization value */ - int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */ - int PadControlOn; /* [IN] Enable padding control */ - int LumaPadVal; /* [IN] Luma pel value used to fill padding area */ - int CbPadVal; /* [IN] CB pel value used to fill padding area */ - int CrPadVal; /* [IN] CR pel value used to fill padding area */ - int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */ -#if defined (MFC6x_VERSION) - int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */ -#endif - - /* H.263 specific parameters */ - int FrameRate; /* [IN] rate control parameter(frame rate) */ -} SSBSIP_MFC_ENC_H263_PARAM; - -typedef struct { - int width; - int height; - int buf_width; - int buf_height; -} SSBSIP_MFC_IMG_RESOLUTION; - -typedef struct { - int crop_top_offset; - int crop_bottom_offset; - int crop_left_offset; - int crop_right_offset; -} SSBSIP_MFC_CROP_INFORMATION; - -#ifdef S3D_SUPPORT -typedef struct { - int available; - unsigned int arrangement_id; - int arrangement_cancel_flag; - unsigned char arrangement_type; - int quincunx_sampling_flag; - unsigned char content_interpretation_type; - int spatial_flipping_flag; - int frame0_flipped_flag; - int field_views_flag; - int current_frame_is_frame0_flag; - unsigned char frame0_grid_pos_x; - unsigned char frame0_grid_pos_y; - unsigned char frame1_grid_pos_x; - unsigned char frame1_grid_pos_y; -} SSBSIP_MFC_FRAME_PACKING; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*--------------------------------------------------------------------------------*/ -/* Decoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcDecOpen(void); -void *SsbSipMfcDecOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); -//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); -void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); -//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); - -#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP)) -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size); -#else -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size); -#endif - -SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); - -/*--------------------------------------------------------------------------------*/ -/* Encoding APIs */ -/*--------------------------------------------------------------------------------*/ -void *SsbSipMfcEncOpen(void); -void *SsbSipMfcEncOpenExt(void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); - -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); -SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); - -#ifdef __cplusplus -} -#endif - -#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h deleted file mode 100644 index b8e96ab..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_ERRNO_H -#define __MFC_ERRNO_H __FILE__ - -enum mfc_ret_code { - MFC_OK = 1, - MFC_FAIL = -1000, - MFC_OPEN_FAIL = -1001, - MFC_CLOSE_FAIL = -1002, - - MFC_DEC_INIT_FAIL = -2000, - MFC_DEC_EXE_TIME_OUT = -2001, - MFC_DEC_EXE_ERR = -2002, - MFC_DEC_GET_INBUF_FAIL = 2003, - MFC_DEC_SET_INBUF_FAIL = 2004, - MFC_DEC_GET_OUTBUF_FAIL = -2005, - MFC_DEC_GET_CONF_FAIL = -2006, - MFC_DEC_SET_CONF_FAIL = -2007, - - MFC_ENC_INIT_FAIL = -3000, - MFC_ENC_EXE_TIME_OUT = -3001, - MFC_ENC_EXE_ERR = -3002, - MFC_ENC_GET_INBUF_FAIL = -3003, - MFC_ENC_SET_INBUF_FAIL = -3004, - MFC_ENC_GET_OUTBUF_FAIL = -3005, - MFC_ENC_SET_OUTBUF_FAIL = -3006, - MFC_ENC_GET_CONF_FAIL = -3007, - MFC_ENC_SET_CONF_FAIL = -3008, - - MFC_STATE_INVALID = -4000, - MFC_DEC_HEADER_FAIL = -4001, - MFC_DEC_INIT_BUF_FAIL = -4002, - MFC_ENC_HEADER_FAIL = -5000, - MFC_ENC_PARAM_FAIL = -5001, - MFC_FRM_BUF_SIZE_FAIL = -6000, - MFC_FW_LOAD_FAIL = -6001, - MFC_FW_INIT_FAIL = -6002, - MFC_INST_NUM_EXCEEDED_FAIL = -6003, - MFC_MEM_ALLOC_FAIL = -6004, - MFC_MEM_INVALID_ADDR_FAIL = -6005, - MFC_MEM_MAPPING_FAIL = -6006, - MFC_GET_CONF_FAIL = -6007, - MFC_SET_CONF_FAIL = -6008, - MFC_INVALID_PARAM_FAIL = -6009, - MFC_API_FAIL = -9000, - - MFC_CMD_FAIL = -1003, - MFC_SLEEP_FAIL = -1010, - MFC_WAKEUP_FAIL = -1020, - - MFC_CLK_ON_FAIL = -1030, - MFC_CLK_OFF_FAIL = -1030, - MFC_PWR_ON_FAIL = -1040, - MFC_PWR_OFF_FAIL = -1041, -}; - -#endif /* __MFC_ERRNO_H */ diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h deleted file mode 100644 index 9bcee9d..0000000 --- a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Global header for Samsung MFC (Multi Function Codec - FIMV) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MFC_INTERFACE_H -#define __MFC_INTERFACE_H - -#include "mfc_errno.h" -#include "SsbSipMfcApi.h" - -#define IOCTL_MFC_DEC_INIT (0x00800001) -#define IOCTL_MFC_ENC_INIT (0x00800002) -#define IOCTL_MFC_DEC_EXE (0x00800003) -#define IOCTL_MFC_ENC_EXE (0x00800004) - -#define IOCTL_MFC_GET_IN_BUF (0x00800010) -#define IOCTL_MFC_FREE_BUF (0x00800011) -#define IOCTL_MFC_GET_REAL_ADDR (0x00800012) -#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014) -#define IOCTL_MFC_SET_IN_BUF (0x00800018) - -#define IOCTL_MFC_SET_CONFIG (0x00800101) -#define IOCTL_MFC_GET_CONFIG (0x00800102) - -#define IOCTL_MFC_SET_BUF_CACHE (0x00800201) - -/* MFC H/W support maximum 32 extra DPB. */ -#define MFC_MAX_EXTRA_DPB 5 -#define MFC_MAX_DISP_DELAY 0xF - -#define MFC_LIB_VER_MAJOR 1 -#define MFC_LIB_VER_MINOR 00 - -#define BUF_L_UNIT (1024) -#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte)) - -#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ -#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */ -#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */ - -#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */ -#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */ -#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */ - -enum inst_type { - DECODER = 0x1, - ENCODER = 0x2, -}; - -enum mfc_check_state { - MFCSTATE_PROCESSING = 0, - MFCSTATE_DEC_RES_DETECT, - MFCSTATE_DEC_TERMINATING, - MFCSTATE_ENC_NO_OUTPUT, -}; - -typedef enum { - MFC_UNPACKED_PB = 0, - MFC_PACKED_PB = 1 -} mfc_packed_mode; - -typedef enum { - SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0, - SSBSIP_MFC_LAST_FRAME_RECEIVED = 1, - SSBSIP_MFC_LAST_FRAME_PROCESSED = 2 -} SSBSIP_MFC_LAST_FRAME_STATUS; - -typedef enum { - MFC_USE_NONE = 0x0000, - MFC_USE_YUV_BUFF = 0x0001, - MFC_USE_STRM_BUFF = 0x0010, - MFC_USE_SRC_STREAMON = 0x0100, - MFC_USE_DST_STREAMON = 0x1000, -} s3c_mfc_interbuff_status; - -typedef struct { - int luma0; /* per frame (or top field) */ - int chroma0; /* per frame (or top field) */ - int luma1; /* per frame (or bottom field) */ - int chroma1; /* per frame (or bottom field) */ -} SSBSIP_MFC_CRC_DATA; - -#ifdef S3D_SUPPORT -struct mfc_frame_pack_sei_info { - int sei_avail; - unsigned int arrgment_id; - int sei_info; - int grid_pos; -}; -#endif - -struct mfc_strm_ref_buf_arg { - unsigned int strm_ref_y; - unsigned int mv_ref_yc; -}; - -struct mfc_frame_buf_arg { - unsigned int luma; - unsigned int chroma; -}; - -struct mfc_enc_init_common_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - - int in_width; /* [IN] width of YUV420 frame to be encoded */ - int in_height; /* [IN] height of YUV420 frame to be encoded */ - - int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ - int in_vop_quant; /* [IN] VOP quant */ - int in_vop_quant_p; /* [IN] VOP quant for P frame */ - - /* [IN] RC enable */ - /* [IN] RC enable (0:disable, 1:frame level RC) */ - int in_rc_fr_en; - int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */ - - int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */ - int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */ - int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */ - - /* [IN] Multi-slice mode (0:single, 1:multiple) */ - int in_ms_mode; - /* [IN] Multi-slice size (in num. of mb or byte) */ - int in_ms_arg; - - int in_mb_refresh; /* [IN] Macroblock refresh */ - - /* [IN] Enable (1) / Disable (0) padding with the specified values */ - int in_pad_ctrl_on; - - /* [IN] pad value if pad_ctrl_on is Enable */ - int in_y_pad_val; - int in_cb_pad_val; - int in_cr_pad_val; - - /* linear or tiled */ - int in_frame_map; - - unsigned int in_pixelcache; - - unsigned int in_mapped_addr; - struct mfc_strm_ref_buf_arg out_u_addr; - struct mfc_strm_ref_buf_arg out_p_addr; - struct mfc_strm_ref_buf_arg out_buf_size; - unsigned int out_header_size; -}; - -struct mfc_enc_init_h263_arg { - int in_rc_framerate; /* [IN] RC parameter (framerate) */ -}; - -struct mfc_enc_init_mpeg4_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */ - int in_quart_pixel; - - int in_TimeIncreamentRes; /* [IN] VOP time resolution */ - int in_VopTimeIncreament; /* [IN] Frame delta */ -}; - -struct mfc_enc_init_h264_arg { - int in_profile; /* [IN] profile */ - int in_level; /* [IN] level */ - - int in_vop_quant_b; /* [IN] VOP quant for B frame */ - - /* [IN] B frame number */ - int in_bframenum; - - /* [IN] interlace mode(0:progressive, 1:interlace) */ - int in_interlace_mode; - - /* [IN] reference number */ - int in_reference_num; - /* [IN] reference number of P frame */ - int in_ref_num_p; - - int in_rc_framerate; /* [IN] RC parameter (framerate) */ - int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */ - /* [IN] MB level rate control dark region adaptive feature */ - int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control smooth region adaptive feature */ - int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control static region adaptive feature */ - int in_rc_mb_static_dis; /* (0:enable, 1:disable) */ - /* [IN] MB level rate control activity region adaptive feature */ - int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */ - - /* [IN] disable deblocking filter idc */ - int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */ - /* [IN] slice alpha c0 offset of deblocking filter */ - int in_deblock_alpha_c0; - /* [IN] slice beta offset of deblocking filter */ - int in_deblock_beta; - - /* [IN] ( 0 : CAVLC, 1 : CABAC ) */ - int in_symbolmode; - /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */ - int in_transform8x8_mode; - - /* [IN] Inter weighted parameter for mode decision */ - int in_md_interweight_pps; - /* [IN] Intra weighted parameter for mode decision */ - int in_md_intraweight_pps; -}; - -struct mfc_enc_init_arg { - struct mfc_enc_init_common_arg cmn; - union { - struct mfc_enc_init_h264_arg h264; - struct mfc_enc_init_mpeg4_arg mpeg4; - struct mfc_enc_init_h263_arg h263; - } codec; -}; - -struct mfc_enc_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ - unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ - unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ - unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ - unsigned int in_frametag; /* [IN] unique frame ID */ - - unsigned int out_frame_type; /* [OUT] frame type */ - int out_encoded_size; /* [OUT] Length of Encoded video stream */ - unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */ - unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */ - unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */ - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif -}; - -struct mfc_dec_init_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] address of stream buffer */ - int in_strm_size; /* [IN] filled size in stream buffer */ - int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ - - unsigned int in_crc; /* [IN] */ - unsigned int in_pixelcache; /* [IN] */ - unsigned int in_slice; /* [IN] */ - unsigned int in_numextradpb; /* [IN] */ - - unsigned int in_mapped_addr; - - int out_frm_width; /* [OUT] width of YUV420 frame */ - int out_frm_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */ - - int out_crop_right_offset; /* [OUT] crop information for h264 */ - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; -}; - -struct mfc_dec_exe_arg { - SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ - int in_strm_buf; /* [IN] the physical address of STRM_BUF */ - /* [IN] Size of video stream filled in STRM_BUF */ - int in_strm_size; - /* [IN] the address of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_buf; - /* [IN] size of dpb FRAME_BUF */ - struct mfc_frame_buf_arg in_frm_size; - /* [IN] Unique frame ID eg. application specific timestamp */ - unsigned int in_frametag; - /* [IN] immdiate Display for seek,thumbnail and one frame */ - int in_immediately_disp; - /* [OUT] the physical address of display buf */ - int out_display_Y_addr; - /* [OUT] the physical address of display buf */ - int out_display_C_addr; - int out_display_status; - /* [OUT] unique frame ID of an output frame or top field */ - unsigned int out_frametag_top; - /* [OUT] unique frame ID of bottom field */ - unsigned int out_frametag_bottom; - int out_pic_time_top; - int out_pic_time_bottom; - int out_consumed_byte; - - int out_crop_right_offset; - int out_crop_left_offset; - int out_crop_bottom_offset; - int out_crop_top_offset; - - /* in new driver, each buffer offset must be return to the user */ - int out_y_offset; - int out_c_offset; - -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int out_y_secure_id; - unsigned int out_c_secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int out_y_cookie; - unsigned int out_c_cookie; -#endif - int out_img_width; /* [OUT] width of YUV420 frame */ - int out_img_height; /* [OUT] height of YUV420 frame */ - int out_buf_width; /* [OUT] width of YUV420 frame */ - int out_buf_height; /* [OUT] height of YUV420 frame */ - - int out_disp_pic_frame_type; /* [OUT] display picture frame type information */ -}; - -struct mfc_get_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to get for the configurable parameter. */ - /* Maximum four integer values can be obtained; */ - int out_config_value[4]; -}; - -struct mfc_set_config_arg { - /* [IN] Configurable parameter type */ - int in_config_param; - - /* [IN] Values to be set for the configurable parameter. */ - /* Maximum four integer values can be set. */ - int in_config_value[4]; -}; - -struct mfc_get_real_addr_arg { - unsigned int key; - unsigned int addr; -}; - -struct mfc_buf_alloc_arg { - enum inst_type type; - int size; - /* - unsigned int mapped; - */ - unsigned int align; - - unsigned int addr; - /* - unsigned int phys; - */ -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - /* FIMXE: invalid secure id == -1 */ - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_buf_free_arg { - unsigned int addr; -}; - -/* RMVME */ -struct mfc_mem_alloc_arg { - enum inst_type type; - int buff_size; - SSBIP_MFC_BUFFER_TYPE buf_cache_type; - unsigned int mapped_addr; -#if defined(CONFIG_VIDEO_MFC_VCM_UMP) - unsigned int secure_id; -#elif defined(CONFIG_S5P_VMEM) - unsigned int cookie; -#else - unsigned int offset; -#endif -}; - -struct mfc_mem_free_arg { - unsigned int key; -}; -/* RMVME */ - -union mfc_args { - /* - struct mfc_enc_init_arg enc_init; - - struct mfc_enc_init_mpeg4_arg enc_init_mpeg4; - struct mfc_enc_init_mpeg4_arg enc_init_h263; - struct mfc_enc_init_h264_arg enc_init_h264; - */ - struct mfc_enc_init_arg enc_init; - struct mfc_enc_exe_arg enc_exe; - - struct mfc_dec_init_arg dec_init; - struct mfc_dec_exe_arg dec_exe; - - struct mfc_get_config_arg get_config; - struct mfc_set_config_arg set_config; - - struct mfc_buf_alloc_arg buf_alloc; - struct mfc_buf_free_arg buf_free; - struct mfc_get_real_addr_arg real_addr; - - /* RMVME */ - struct mfc_mem_alloc_arg mem_alloc; - struct mfc_mem_free_arg mem_free; - /* RMVME */ -}; - -struct mfc_common_args { - enum mfc_ret_code ret_code; /* [OUT] error code */ - union mfc_args args; -}; - -struct mfc_enc_vui_info { - int aspect_ratio_idc; -}; - -struct mfc_dec_fimv1_info { - int width; - int height; -}; - -struct mfc_enc_hier_p_qp { - int t0_frame_qp; - int t2_frame_qp; - int t3_frame_qp; -}; - -#ifdef S3D_SUPPORT -struct mfc_enc_sei_info { - int sei_gen_enable; - int curr_frame_frm0_flag; - int frame_pack_arrgment_type; -}; -#endif - -struct mfc_enc_fmo { - unsigned int slice_map_type; - unsigned int slice_num_grp; - unsigned int run_length[4]; - unsigned int sg_dir; - unsigned int sg_rate; -}; - -enum BUF_STATUS { - BUF_ENQUEUED, - BUF_DEQUEUED -}; - -struct mfc_dec_v4l2 { - char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */ - char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */ - char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */ - - unsigned int mfc_src_bufs_len; /* needed for munmap */ - unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */ - - unsigned int mfc_num_src_bufs; /* the number of source buffers */ - unsigned int mfc_num_dst_bufs; /* the number of destination buffers */ - - char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS]; - int bBeingFinalized; - int allocIndex; - int beingUsedIndex; -}; - -struct mfc_enc_v4l2 { - char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; - char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES]; - char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS]; - - unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES]; - unsigned int mfc_dst_bufs_len; - - unsigned int mfc_num_src_bufs; - unsigned int mfc_num_dst_bufs; - - unsigned int mfc_dst_bufs_bytes_used_len; - char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS]; - int bRunning; - int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */ - int beingUsedIndex; -}; - -typedef struct { - int magic; - int hMFC; - int hVMEM; - int width; - int height; - int sizeStrmBuf; - struct mfc_frame_buf_arg sizeFrmBuf; - int displayStatus; - int inter_buff_status; - unsigned int virFreeStrmAddr; - unsigned int phyStrmBuf; - unsigned int virStrmBuf; - unsigned int virMvRefYC; - struct mfc_frame_buf_arg phyFrmBuf; - struct mfc_frame_buf_arg virFrmBuf; - unsigned int mapped_addr; - unsigned int mapped_size; - struct mfc_common_args MfcArg; - SSBSIP_MFC_CODEC_TYPE codecType; - SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; - unsigned int inframetag; - unsigned int outframetagtop; - unsigned int outframetagbottom; - unsigned int immediatelydisp; - unsigned int encodedHeaderSize; - int encodedDataSize; - unsigned int encodedframeType; - struct mfc_frame_buf_arg encodedphyFrmBuf; - - unsigned int dec_crc; - unsigned int dec_pixelcache; - unsigned int dec_slice; - unsigned int dec_numextradpb; - - int input_cookie; - int input_secure_id; - int input_size; - - /* to support non-blocking mode */ - unsigned int encode_cnt; - - struct mfc_dec_v4l2 v4l2_dec; - struct mfc_enc_v4l2 v4l2_enc; - - int enc_frameskip; - int cacheablebuffer; - struct mfc_dec_fimv1_info fimv1_res; - SSBSIP_MFC_LAST_FRAME_STATUS lastframe; - SSBSIP_MFC_INSTRM_MODE_TYPE framemap; - - int hier_p_enable; - struct mfc_enc_hier_p_qp hier_qp_value; -#ifdef S3D_SUPPORT - struct mfc_enc_sei_info sei_info; -#endif - int fmo_enable; - struct mfc_enc_fmo fmo_value; - int aso_enable; - int aso_sl_order[8]; - - - /*ION related*/ - int ion_fd; - int dst_ion_fd[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; -} _MFCLIB; - -#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) -#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) - -#define SSBSIP_MFC_FAIL (0) - -#endif /* __MFC_INTERFACE_H */ diff --git a/exynos4/multimedia/libs/Android.mk b/exynos4/multimedia/libs/Android.mk deleted file mode 100644 index 55ca333..0000000 --- a/exynos4/multimedia/libs/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) \ No newline at end of file diff --git a/exynos4/multimedia/libs/libcsc/Android.mk b/exynos4/multimedia/libs/libcsc/Android.mk deleted file mode 100644 index 6f3f753..0000000 --- a/exynos4/multimedia/libs/libcsc/Android.mk +++ /dev/null @@ -1,64 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := libsecmm -LOCAL_COPY_HEADERS := \ - csc.h - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - csc.c - -ifeq ($(BOARD_USE_EXYNOS_OMX), true) -OMX_NAME := exynos -else -OMX_NAME := sec -endif - -LOCAL_C_INCLUDES := \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/$(OMX_NAME)_omx/include/khronos \ - $(TOP)/$(BOARD_HMM_PATH)/openmax/$(OMX_NAME)_omx/include/$(OMX_NAME) - -LOCAL_CFLAGS := - -LOCAL_MODULE := libcsc - -LOCAL_PRELINK_MODULE := false - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libswconverter -LOCAL_SHARED_LIBRARIES := liblog - -ifeq ($(BOARD_USE_SAMSUNG_COLORFORMAT), true) -LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT -endif - -ifeq ($(TARGET_BOARD_PLATFORM), exynos4) -LOCAL_SRC_FILES += hwconverter_wrapper.cpp -LOCAL_C_INCLUDES += $(TOP)/$(BOARD_HMM_PATH)/utils/csc/exynos4 \ - $(TOP)/$(BOARD_HAL_PATH)/include \ - $(TOP)/$(BOARD_HAL_PATH)/libhwconverter -LOCAL_CFLAGS += -DUSE_FIMC -LOCAL_SHARED_LIBRARIES += libfimc libhwconverter -endif - -ifeq ($(TARGET_BOARD_PLATFORM), exynos5) -LOCAL_C_INCLUDES += $(TOP)/$(BOARD_HMM_PATH)/utils/csc/exynos5 \ - $(TOP)/device/samsung/exynos5/include -LOCAL_CFLAGS += -DUSE_GSCALER -LOCAL_SHARED_LIBRARIES += libexynosgscaler -endif - -ifeq ($(BOARD_USE_V4L2_ION),true) -LOCAL_CFLAGS += -DUSE_ION -LOCAL_SHARED_LIBRARIES += libion -endif - -ifeq ($(BOARD_USE_EXYNOS_OMX), true) -LOCAL_CFLAGS += -DEXYNOS_OMX -endif - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/libs/libcsc/csc.c b/exynos4/multimedia/libs/libcsc/csc.c deleted file mode 100644 index 19bd203..0000000 --- a/exynos4/multimedia/libs/libcsc/csc.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * - * Copyright 2012 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file csc.c - * - * @brief color space convertion abstract source - * - * @author Pyoungjae Jung(pjet.jung@samsung.com) - * - * @version 1.0.0 - * - * @history - * 2012.1.11 : Create - */ -#define LOG_TAG "libcsc" -#include - -#include -#include -#include - -#include "csc.h" -#include "sec_format.h" -#include "sec_utils_v4l2.h" -#include "swconverter.h" - -#ifdef EXYNOS_OMX -#include "Exynos_OMX_Def.h" -#else -#include "SEC_OMX_Def.h" -#endif - -#ifdef USE_FIMC -#include "hwconverter_wrapper.h" -#endif - -#ifdef USE_GSCALER -#include "exynos_gscaler.h" -#endif - -#define GSCALER_IMG_ALIGN 16 -#define CSC_MAX_PLANES 3 -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) - -typedef enum _CSC_PLANE { - CSC_Y_PLANE = 0, - CSC_RGB_PLANE = 0, - CSC_U_PLANE = 1, - CSC_UV_PLANE = 1, - CSC_V_PLANE = 2 -} CSC_PLANE; - -typedef enum _CSC_HW_TYPE { - CSC_HW_TYPE_FIMC = 0, - CSC_HW_TYPE_GSCALER -} CSC_HW_TYPE; - -typedef struct _CSC_FORMAT { - unsigned int width; - unsigned int height; - unsigned int crop_left; - unsigned int crop_top; - unsigned int crop_width; - unsigned int crop_height; - unsigned int color_format; - unsigned int cacheable; -} CSC_FORMAT; - -typedef struct _CSC_BUFFER { - unsigned char *planes[CSC_MAX_PLANES]; - int ion_fd; -} CSC_BUFFER; - -typedef struct _CSC_HANDLE { - CSC_FORMAT dst_format; - CSC_FORMAT src_format; - CSC_BUFFER dst_buffer; - CSC_BUFFER src_buffer; - CSC_METHOD csc_method; - CSC_HW_TYPE csc_hw_type; - void *csc_hw_handle; -} CSC_HANDLE; - -OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( - unsigned int hal_format) -{ - OMX_COLOR_FORMATTYPE omx_format; - switch (hal_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_P: - omx_format = OMX_COLOR_FormatYUV420Planar; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - omx_format = OMX_COLOR_FormatYUV420SemiPlanar; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: - omx_format = OMX_SEC_COLOR_FormatNV12Tiled; - break; - case HAL_PIXEL_FORMAT_ARGB888: - omx_format = OMX_COLOR_Format32bitARGB8888; - break; - default: - omx_format = OMX_COLOR_FormatYUV420Planar; - break; - } - return omx_format; -} - -unsigned int omx_2_hal_pixel_format( - OMX_COLOR_FORMATTYPE omx_format) -{ - unsigned int hal_format; - switch (omx_format) { - case OMX_COLOR_FormatYUV420Planar: - hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; - break; - case OMX_COLOR_Format32bitARGB8888: - hal_format = HAL_PIXEL_FORMAT_ARGB888; - break; - default: - hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; - break; - } - return hal_format; -} - -/* source is RGB888 */ -static CSC_ERRORCODE conv_sw_src_argb888( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->dst_format.color_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_P: - csc_ARGB8888_to_YUV420P( - (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE], - handle->src_format.width, - handle->src_format.height); - ret = CSC_ErrorNone; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - csc_ARGB8888_to_YUV420SP( - (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE], - handle->src_format.width, - handle->src_format.height); - ret = CSC_ErrorNone; - break; - default: - ret = CSC_ErrorUnsupportFormat; - break; - } - - return ret; -} - -/* source is NV12T */ -static CSC_ERRORCODE conv_sw_src_nv12t( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->dst_format.color_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_P: - csc_tiled_to_linear_y_neon( - (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width, - handle->src_format.height); - csc_tiled_to_linear_uv_deinterleave_neon( - (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], - handle->src_format.width, - handle->src_format.height / 2); - ret = CSC_ErrorNone; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - csc_tiled_to_linear_y_neon( - (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width, - handle->src_format.height); - csc_tiled_to_linear_uv_neon( - (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], - handle->src_format.width, - handle->src_format.height / 2); - ret = CSC_ErrorNone; - break; - default: - ret = CSC_ErrorUnsupportFormat; - break; - } - - return ret; -} - -/* source is YUV420P */ -static CSC_ERRORCODE conv_sw_src_yuv420p( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->dst_format.color_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_P: /* bypass */ - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], - (handle->src_format.width * handle->src_format.height) >> 2); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], - (handle->src_format.width * handle->src_format.height) >> 2); - ret = CSC_ErrorNone; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - csc_interleave_memcpy_neon( - (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], - (handle->src_format.width * handle->src_format.height) >> 2); - ret = CSC_ErrorNone; - break; - default: - ret = CSC_ErrorUnsupportFormat; - break; - } - - return ret; -} - -/* source is YUV420SP */ -static CSC_ERRORCODE conv_sw_src_yuv420sp( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->dst_format.color_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_P: - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - csc_deinterleave_memcpy( - (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], - handle->src_format.width * handle->src_format.height >> 1); - ret = CSC_ErrorNone; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: /* bypass */ - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], - handle->src_format.width * handle->src_format.height >> 1); - ret = CSC_ErrorNone; - break; - default: - ret = CSC_ErrorUnsupportFormat; - break; - } - - return ret; -} - -static CSC_ERRORCODE conv_sw( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->src_format.color_format) { - case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: - ret = conv_sw_src_nv12t(handle); - break; - case HAL_PIXEL_FORMAT_YCbCr_420_P: - ret = conv_sw_src_yuv420p(handle); - break; - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - ret = conv_sw_src_yuv420sp(handle); - break; - case HAL_PIXEL_FORMAT_ARGB888: - ret = conv_sw_src_argb888(handle); - break; - default: - ret = CSC_ErrorUnsupportFormat; - break; - } - - return ret; -} - -static CSC_ERRORCODE conv_hw( - CSC_HANDLE *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - - switch (handle->csc_hw_type) { -#ifdef USE_FIMC - case CSC_HW_TYPE_FIMC: - { - void *src_addr[3]; - void *dst_addr[3]; - OMX_COLOR_FORMATTYPE omx_format; - src_addr[0] = handle->src_buffer.planes[CSC_Y_PLANE]; - src_addr[1] = handle->src_buffer.planes[CSC_UV_PLANE]; - dst_addr[0] = handle->dst_buffer.planes[CSC_Y_PLANE]; - dst_addr[1] = handle->dst_buffer.planes[CSC_U_PLANE]; - dst_addr[2] = handle->dst_buffer.planes[CSC_V_PLANE]; - omx_format = hal_2_omx_pixel_format(handle->dst_format.color_format); - csc_hwconverter_convert_nv12t( - handle->csc_hw_handle, - dst_addr, - src_addr, - handle->dst_format.width, - handle->dst_format.height, - omx_format); - break; - } -#endif -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_convert(handle->csc_hw_handle); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - - return CSC_ErrorNotImplemented; -} - -void *csc_init( - CSC_METHOD *method) -{ - CSC_HANDLE *csc_handle; - csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE)); - if (csc_handle == NULL) - return NULL; - - memset(csc_handle, 0, sizeof(CSC_HANDLE)); - - csc_handle->csc_method = *method; - - if (csc_handle->csc_method == CSC_METHOD_HW || - csc_handle->csc_method == CSC_METHOD_PREFER_HW) { -#ifdef USE_FIMC - csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC; -#endif -#ifdef USE_GSCALER - csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER; -#endif - switch (csc_handle->csc_hw_type) { -#ifdef USE_FIMC - case CSC_HW_TYPE_FIMC: - csc_handle->csc_hw_handle = csc_hwconverter_open(); - LOGD("%s:: CSC_HW_TYPE_FIMC", __func__); - break; -#endif -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - csc_handle->csc_hw_handle = exynos_gsc_create(); - LOGD("%s:: CSC_HW_TYPE_GSCALER", __func__); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); - csc_handle->csc_hw_handle == NULL; - break; - } - } - - if (csc_handle->csc_method == CSC_METHOD_PREFER_HW) { - if (csc_handle->csc_hw_handle == NULL) { - csc_handle->csc_method = CSC_METHOD_SW; - *method = CSC_METHOD_SW; - } else { - csc_handle->csc_method = CSC_METHOD_HW; - *method = CSC_METHOD_HW; - } - } - - if (csc_handle->csc_method == CSC_METHOD_HW) { - if (csc_handle->csc_hw_handle == NULL) { - LOGE("%s:: CSC_METHOD_HW can't open HW", __func__); - free(csc_handle); - csc_handle = NULL; - } - } - - LOGD("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method); - - return (void *)csc_handle; -} - -CSC_ERRORCODE csc_deinit( - void *handle) -{ - CSC_ERRORCODE ret = CSC_ErrorNone; - CSC_HANDLE *csc_handle; - - csc_handle = (CSC_HANDLE *)handle; - if (csc_handle->csc_method == CSC_METHOD_HW) { - switch (csc_handle->csc_hw_type) { -#ifdef USE_FIMC - case CSC_HW_TYPE_FIMC: - csc_hwconverter_close(csc_handle->csc_hw_handle); - break; -#endif -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_destroy(csc_handle->csc_hw_handle); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - } - - if (csc_handle != NULL) { - free(csc_handle); - ret = CSC_ErrorNone; - } - - return ret; -} - -CSC_ERRORCODE csc_get_method( - void *handle, - CSC_METHOD *method) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - *method = csc_handle->csc_method; - - return ret; -} - -CSC_ERRORCODE csc_get_src_format( - void *handle, - unsigned int *width, - unsigned int *height, - unsigned int *crop_left, - unsigned int *crop_top, - unsigned int *crop_width, - unsigned int *crop_height, - unsigned int *color_format, - unsigned int *cacheable) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - *width = csc_handle->src_format.width; - *height = csc_handle->src_format.height; - *crop_left = csc_handle->src_format.crop_left; - *crop_top = csc_handle->src_format.crop_top; - *crop_width = csc_handle->src_format.crop_width; - *crop_height = csc_handle->src_format.crop_height; - *color_format = csc_handle->src_format.color_format; - *cacheable = csc_handle->src_format.cacheable; - - return ret; -} - -CSC_ERRORCODE csc_set_src_format( - void *handle, - unsigned int width, - unsigned int height, - unsigned int crop_left, - unsigned int crop_top, - unsigned int crop_width, - unsigned int crop_height, - unsigned int color_format, - unsigned int cacheable) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - csc_handle->src_format.width = width; - csc_handle->src_format.height = height; - csc_handle->src_format.crop_left = crop_left; - csc_handle->src_format.crop_top = crop_top; - csc_handle->src_format.crop_width = crop_width; - csc_handle->src_format.crop_height = crop_height; - csc_handle->src_format.color_format = color_format; - csc_handle->src_format.cacheable = cacheable; - - if (csc_handle->csc_method == CSC_METHOD_HW) { - switch (csc_handle->csc_hw_type) { - case CSC_HW_TYPE_FIMC: - break; -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_src_format( - csc_handle->csc_hw_handle, - ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN), - csc_handle->src_format.crop_left, - csc_handle->src_format.crop_top, - ALIGN(csc_handle->src_format.crop_width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->src_format.crop_height, GSCALER_IMG_ALIGN), - HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), - csc_handle->src_format.cacheable); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - } - - return ret; -} - -CSC_ERRORCODE csc_get_dst_format( - void *handle, - unsigned int *width, - unsigned int *height, - unsigned int *crop_left, - unsigned int *crop_top, - unsigned int *crop_width, - unsigned int *crop_height, - unsigned int *color_format, - unsigned int *cacheable) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - *width = csc_handle->dst_format.width; - *height = csc_handle->dst_format.height; - *crop_left = csc_handle->dst_format.crop_left; - *crop_top = csc_handle->dst_format.crop_top; - *crop_width = csc_handle->dst_format.crop_width; - *crop_height = csc_handle->dst_format.crop_height; - *color_format = csc_handle->dst_format.color_format; - *cacheable = csc_handle->dst_format.cacheable; - - return ret; -} - -CSC_ERRORCODE csc_set_dst_format( - void *handle, - unsigned int width, - unsigned int height, - unsigned int crop_left, - unsigned int crop_top, - unsigned int crop_width, - unsigned int crop_height, - unsigned int color_format, - unsigned int cacheable) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - csc_handle->dst_format.width = width; - csc_handle->dst_format.height = height; - csc_handle->dst_format.crop_left = crop_left; - csc_handle->dst_format.crop_top = crop_top; - csc_handle->dst_format.crop_width = crop_width; - csc_handle->dst_format.crop_height = crop_height; - csc_handle->dst_format.color_format = color_format; - csc_handle->dst_format.cacheable = cacheable; - - if (csc_handle->csc_method == CSC_METHOD_HW) { - switch (csc_handle->csc_hw_type) { - case CSC_HW_TYPE_FIMC: - break; -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_dst_format( - csc_handle->csc_hw_handle, - ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN), - csc_handle->dst_format.crop_left, - csc_handle->dst_format.crop_top, - ALIGN(csc_handle->dst_format.crop_width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->dst_format.crop_height, GSCALER_IMG_ALIGN), - HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), - csc_handle->dst_format.cacheable); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - } - - return ret; -} - -CSC_ERRORCODE csc_set_src_buffer( - void *handle, - unsigned char *y, - unsigned char *u, - unsigned char *v, - int ion_fd) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - void *addr[3] = {NULL, }; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - csc_handle->src_buffer.planes[CSC_Y_PLANE] = y; - csc_handle->src_buffer.planes[CSC_U_PLANE] = u; - csc_handle->src_buffer.planes[CSC_V_PLANE] = v; - - if (csc_handle->csc_method == CSC_METHOD_HW) { - addr[0] = csc_handle->src_buffer.planes[CSC_Y_PLANE]; - addr[1] = csc_handle->src_buffer.planes[CSC_U_PLANE]; - addr[2] = csc_handle->src_buffer.planes[CSC_V_PLANE]; - - switch (csc_handle->csc_hw_type) { - case CSC_HW_TYPE_FIMC: - break; -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, addr); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - } - - return ret; -} - -CSC_ERRORCODE csc_set_dst_buffer( - void *handle, - unsigned char *y, - unsigned char *u, - unsigned char *v, - int ion_fd) -{ - CSC_HANDLE *csc_handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - void *addr[3] = {NULL, }; - - if (handle == NULL) - return CSC_ErrorNotInit; - - csc_handle = (CSC_HANDLE *)handle; - csc_handle->dst_buffer.planes[CSC_Y_PLANE] = y; - csc_handle->dst_buffer.planes[CSC_U_PLANE] = u; - csc_handle->dst_buffer.planes[CSC_V_PLANE] = v; - - if (csc_handle->csc_method == CSC_METHOD_HW) { - addr[0] = csc_handle->dst_buffer.planes[CSC_Y_PLANE]; - addr[1] = csc_handle->dst_buffer.planes[CSC_U_PLANE]; - addr[2] = csc_handle->dst_buffer.planes[CSC_V_PLANE]; - - switch (csc_handle->csc_hw_type) { - case CSC_HW_TYPE_FIMC: - break; -#ifdef USE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, addr); - break; -#endif - default: - LOGE("%s:: unsupported csc_hw_type", __func__); - break; - } - } - - return ret; -} - -CSC_ERRORCODE csc_convert( - void *handle) -{ - CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle; - CSC_ERRORCODE ret = CSC_ErrorNone; - - if (csc_handle == NULL) - return CSC_ErrorNotInit; - - if (csc_handle->csc_method == CSC_METHOD_HW) - ret = conv_hw(csc_handle); - else - ret = conv_sw(csc_handle); - - return ret; -} diff --git a/exynos4/multimedia/libs/libcsc/csc.h b/exynos4/multimedia/libs/libcsc/csc.h deleted file mode 100644 index 9069392..0000000 --- a/exynos4/multimedia/libs/libcsc/csc.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file csc.h - * - * @brief color space convertion abstract header - * - * @author Pyoungjae Jung (pjet.jung@samsung.com) - * - * @version 1.0 - * - * @history - * 2011.12.27 : Create - */ - -#ifndef CSC_H -#define CSC_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum _CSC_ERRORCODE { - CSC_ErrorNone = 0, - CSC_Error, - CSC_ErrorNotInit, - CSC_ErrorInvalidAddress, - CSC_ErrorUnsupportFormat, - CSC_ErrorNotImplemented -} CSC_ERRORCODE; - -typedef enum _CSC_METHOD { - CSC_METHOD_SW = 0, - CSC_METHOD_HW, - CSC_METHOD_PREFER_HW -} CSC_METHOD; - -/* - * change hal pixel format to omx pixel format - * - * @param hal_format - * hal pixel format[in] - * - * @return - * omx pixel format - */ -unsigned int hal_2_omx_pixel_format( - unsigned int hal_format); - -/* - * change omx pixel format to hal pixel format - * - * @param hal_format - * omx pixel format[in] - * - * @return - * hal pixel format - */ -unsigned int omx_2_hal_pixel_format( - unsigned int omx_format); - -/* - * Init CSC handle - * - * @return - * csc handle - */ -void *csc_init( - CSC_METHOD *method); - -/* - * Deinit CSC handle - * - * @param handle - * CSC handle[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_deinit( - void *handle); - -/* - * get color space converter method - * - * @param handle - * CSC handle[in] - * - * @param method - * CSC method[out] - * - * @return - * error code - */ -CSC_ERRORCODE csc_get_method( - void *handle, - CSC_METHOD *method); - -/* - * Get source format. - * - * @param handle - * CSC handle[in] - * - * @param width - * address of image width[out] - * - * @param height - * address of image height[out] - * - * @param crop_left - * address of image left crop size[out] - * - * @param crop_top - * address of image top crop size[out] - * - * @param crop_width - * address of cropped image width[out] - * - * @param crop_height - * address of cropped image height[out] - * - * @param color_format - * address of source color format(HAL format)[out] - * - * @return - * error code - */ -CSC_ERRORCODE csc_get_src_format( - void *handle, - unsigned int *width, - unsigned int *height, - unsigned int *crop_left, - unsigned int *crop_top, - unsigned int *crop_width, - unsigned int *crop_height, - unsigned int *color_format, - unsigned int *cacheable); - -/* - * Set source format. - * Don't call each converting time. - * Pls call this function as below. - * 1. first converting time - * 2. format is changed - * - * @param handle - * CSC handle[in] - * - * @param width - * image width[in] - * - * @param height - * image height[in] - * - * @param crop_left - * image left crop size[in] - * - * @param crop_top - * image top crop size[in] - * - * @param crop_width - * cropped image width[in] - * - * @param crop_height - * cropped image height[in] - * - * @param color_format - * source color format(HAL format)[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_set_src_format( - void *handle, - unsigned int width, - unsigned int height, - unsigned int crop_left, - unsigned int crop_top, - unsigned int crop_width, - unsigned int crop_height, - unsigned int color_format, - unsigned int cacheable); - -/* - * Get destination format. - * - * @param handle - * CSC handle[in] - * - * @param width - * address of image width[out] - * - * @param height - * address of image height[out] - * - * @param crop_left - * address of image left crop size[out] - * - * @param crop_top - * address of image top crop size[out] - * - * @param crop_width - * address of cropped image width[out] - * - * @param crop_height - * address of cropped image height[out] - * - * @param color_format - * address of color format(HAL format)[out] - * - * @return - * error code - */ -CSC_ERRORCODE csc_get_dst_format( - void *handle, - unsigned int *width, - unsigned int *height, - unsigned int *crop_left, - unsigned int *crop_top, - unsigned int *crop_width, - unsigned int *crop_height, - unsigned int *color_format, - unsigned int *cacheable); - -/* - * Set destination format - * Don't call each converting time. - * Pls call this function as below. - * 1. first converting time - * 2. format is changed - * - * @param handle - * CSC handle[in] - * - * @param width - * image width[in] - * - * @param height - * image height[in] - * - * @param crop_left - * image left crop size[in] - * - * @param crop_top - * image top crop size[in] - * - * @param crop_width - * cropped image width[in] - * - * @param crop_height - * cropped image height[in] - * - * @param color_format - * destination color format(HAL format)[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_set_dst_format( - void *handle, - unsigned int width, - unsigned int height, - unsigned int crop_left, - unsigned int crop_top, - unsigned int crop_width, - unsigned int crop_height, - unsigned int color_format, - unsigned int cacheable); - -/* - * Setup source buffer - * set_format func should be called before this this func. - * - * @param handle - * CSC handle[in] - * - * @param src_buffer - * source buffer pointer array[in] - * - * @param y - * y or RGB destination pointer[in] - * - * @param u - * u or uv destination pointer[in] - * - * @param v - * v or none destination pointer[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_set_src_buffer( - void *handle, - unsigned char *y, - unsigned char *u, - unsigned char *v, - int ion_fd); - -/* - * Setup destination buffer - * - * @param handle - * CSC handle[in] - * - * @param y - * y or RGB destination pointer[in] - * - * @param u - * u or uv destination pointer[in] - * - * @param v - * v or none destination pointer[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_set_dst_buffer( - void *handle, - unsigned char *y, - unsigned char *u, - unsigned char *v, - int ion_fd); - -/* - * Convert color space with presetup color format - * - * @param handle - * CSC handle[in] - * - * @return - * error code - */ -CSC_ERRORCODE csc_convert( - void *handle); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.cpp b/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.cpp deleted file mode 100644 index 9f6cd07..0000000 --- a/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file hwconverter_wrapper.cpp - * - * @brief hwconverter_wrapper abstract libhwconverter and support c functions - * - * @author ShinWon Lee (shinwon.lee@samsung.com) - * - * @version 1.0 - * - * @history - * 2012.02.01 : Create - */ - -#include -#include - -#include "SEC_OMX_Def.h" -#include "hwconverter_wrapper.h" -#include "HardwareConverter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * create hwconverter handle - * - * @return - * fimc handle - */ -void *csc_hwconverter_open() -{ - HardwareConverter *hw_converter = NULL; - - hw_converter = new HardwareConverter; - if (hw_converter->bHWconvert_flag == 0) { - delete hw_converter; - hw_converter = NULL; - LOGE("%s LINE = %d HardwareConverter failed", __func__, __LINE__); - } - - return (void *)hw_converter; -} - -/* - * destroy hwconverter handle - * - * @param handle - * fimc handle[in] - * - * @return - * pass or fail - */ -HWCONVERTER_ERROR_CODE csc_hwconverter_close( - void *handle) -{ - HardwareConverter *hw_converter = (HardwareConverter *)handle; - - if (hw_converter != NULL) - delete hw_converter; - - return HWCONVERTER_RET_OK; -} - -/* - * convert color space nv12t to omxformat - * - * @param handle - * hwconverter handle[in] - * - * @param dst_addr - * y,u,v address of dst_addr[out] - * - * @param src_addr - * y,uv address of src_addr.Format is nv12t[in] - * - * @param width - * width of dst image[in] - * - * @param height - * height of dst image[in] - * - * @param omxformat - * omxformat of dst image[in] - * - * @return - * pass or fail - */ -HWCONVERTER_ERROR_CODE csc_hwconverter_convert_nv12t( - void *handle, - void **dst_addr, - void **src_addr, - unsigned int width, - unsigned int height, - OMX_COLOR_FORMATTYPE omxformat) -{ - HWCONVERTER_ERROR_CODE ret = HWCONVERTER_RET_OK; - HardwareConverter *hw_converter = (HardwareConverter *)handle; - - if (hw_converter == NULL) { - ret = HWCONVERTER_RET_FAIL; - goto EXIT; - } - - hw_converter->convert( - (void *)src_addr, (void *)dst_addr, - (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress, - width, height, omxformat); - - ret = HWCONVERTER_RET_OK; - -EXIT: - - return ret; -} - -#ifdef __cplusplus -} -#endif diff --git a/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.h b/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.h deleted file mode 100644 index 292a680..0000000 --- a/exynos4/multimedia/libs/libcsc/hwconverter_wrapper.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file hwconverter_wrapper.h - * - * @brief hwconverter_wrapper abstract libhwconverter and support c functions - * - * @author ShinWon Lee (shinwon.lee@samsung.com) - * - * @version 1.0 - * - * @history - * 2012.02.01 : Create - */ - -#ifndef HWCONVERTER_WRAPPER_H - -#define HWCONVERTER_WRAPPER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/*--------------------------------------------------------------------------------*/ -/* Structure and Type */ -/*--------------------------------------------------------------------------------*/ -typedef enum { - HWCONVERTER_RET_OK = 0, - HWCONVERTER_RET_FAIL = -1 -} HWCONVERTER_ERROR_CODE; - -/*--------------------------------------------------------------------------------*/ -/* CSC FIMC APIs */ -/*--------------------------------------------------------------------------------*/ -/* - * create hwconverter handle - * - * @return - * hwconverter handle - */ -void *csc_fimc_open(); - -/* - * destroy hwconverter handle - * - * @param handle - * hwconverter handle[in] - * - * @return - * error code - */ -HWCONVERTER_ERROR_CODE csc_fimc_close( - void *handle); - -/* - * convert color space nv12t to omxformat - * - * @param handle - * hwconverter handle[in] - * - * @param dst_addr - * y,u,v address of dst_addr[out] - * - * @param src_addr - * y,uv address of src_addr.Format is nv12t[in] - * - * @param width - * width of dst image[in] - * - * @param height - * height of dst image[in] - * - * @param omxformat - * omxformat of dst image[in] - * - * @return - * error code - */ -HWCONVERTER_ERROR_CODE csc_fimc_convert_nv12t( - void *handle, - void **dst_addr, - void **src_addr, - unsigned int width, - unsigned int height, - OMX_COLOR_FORMATTYPE omxformat); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/libstagefrighthw/Android.mk b/exynos4/multimedia/libstagefrighthw/Android.mk deleted file mode 100644 index ce7a5e7..0000000 --- a/exynos4/multimedia/libstagefrighthw/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - SEC_OMX_Plugin.cpp - -LOCAL_CFLAGS += $(PV_CFLAGS_MINUS_VISIBILITY) - -LOCAL_C_INCLUDES:= \ - $(TOP)/frameworks/base/include/media/stagefright/openmax \ - -LOCAL_SHARED_LIBRARIES := \ - libbinder \ - libutils \ - libcutils \ - libui \ - libdl \ - libsurfaceflinger_client - -LOCAL_MODULE := libstagefrighthw - -LOCAL_MODULE_TAGS := optional -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp b/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp deleted file mode 100644 index efc8691..0000000 --- a/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "SEC_OMX_Plugin.h" - -#include - -#include -#include - -namespace android { - -OMXPluginBase *createOMXPlugin() { - return new SECOMXPlugin; -} - -SECOMXPlugin::SECOMXPlugin() - : mLibHandle(dlopen("libSEC_OMX_Core.so", RTLD_NOW)), - mInit(NULL), - mDeinit(NULL), - mComponentNameEnum(NULL), - mGetHandle(NULL), - mFreeHandle(NULL), - mGetRolesOfComponentHandle(NULL) { - if (mLibHandle != NULL) { - mInit = (InitFunc)dlsym(mLibHandle, "SEC_OMX_Init"); - mDeinit = (DeinitFunc)dlsym(mLibHandle, "SEC_OMX_Deinit"); - - mComponentNameEnum = - (ComponentNameEnumFunc)dlsym(mLibHandle, "SEC_OMX_ComponentNameEnum"); - - mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "SEC_OMX_GetHandle"); - mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "SEC_OMX_FreeHandle"); - - mGetRolesOfComponentHandle = - (GetRolesOfComponentFunc)dlsym( - mLibHandle, "SEC_OMX_GetRolesOfComponent"); - - (*mInit)(); - - } -} - -SECOMXPlugin::~SECOMXPlugin() { - if (mLibHandle != NULL) { - (*mDeinit)(); - - dlclose(mLibHandle); - mLibHandle = NULL; - } -} - -OMX_ERRORTYPE SECOMXPlugin::makeComponentInstance( - const char *name, - const OMX_CALLBACKTYPE *callbacks, - OMX_PTR appData, - OMX_COMPONENTTYPE **component) { - if (mLibHandle == NULL) { - return OMX_ErrorUndefined; - } - - return (*mGetHandle)( - reinterpret_cast(component), - const_cast(name), - appData, const_cast(callbacks)); -} - -OMX_ERRORTYPE SECOMXPlugin::destroyComponentInstance( - OMX_COMPONENTTYPE *component) { - if (mLibHandle == NULL) { - return OMX_ErrorUndefined; - } - - return (*mFreeHandle)(reinterpret_cast(component)); -} - -OMX_ERRORTYPE SECOMXPlugin::enumerateComponents( - OMX_STRING name, - size_t size, - OMX_U32 index) { - if (mLibHandle == NULL) { - return OMX_ErrorUndefined; - } - - return (*mComponentNameEnum)(name, size, index); -} - -OMX_ERRORTYPE SECOMXPlugin::getRolesOfComponent( - const char *name, - Vector *roles) { - roles->clear(); - - if (mLibHandle == NULL) { - return OMX_ErrorUndefined; - } - - OMX_U32 numRoles; - OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)( - const_cast(name), &numRoles, NULL); - - if (err != OMX_ErrorNone) { - return err; - } - - if (numRoles > 0) { - OMX_U8 **array = new OMX_U8 *[numRoles]; - for (OMX_U32 i = 0; i < numRoles; ++i) { - array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE]; - } - - OMX_U32 numRoles2; - err = (*mGetRolesOfComponentHandle)( - const_cast(name), &numRoles2, array); - - CHECK_EQ(err, OMX_ErrorNone); - CHECK_EQ(numRoles, numRoles2); - - for (OMX_U32 i = 0; i < numRoles; ++i) { - String8 s((const char *)array[i]); - roles->push(s); - - delete[] array[i]; - array[i] = NULL; - } - - delete[] array; - array = NULL; - } - - return OMX_ErrorNone; -} - -} // namespace android - diff --git a/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.h b/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.h deleted file mode 100644 index 6df2d31..0000000 --- a/exynos4/multimedia/libstagefrighthw/SEC_OMX_Plugin.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SEC_OMX_PLUGIN - -#define SEC_OMX_PLUGIN - -#include - -namespace android { - -struct SECOMXPlugin : public OMXPluginBase { - SECOMXPlugin(); - virtual ~SECOMXPlugin(); - - virtual OMX_ERRORTYPE makeComponentInstance( - const char *name, - const OMX_CALLBACKTYPE *callbacks, - OMX_PTR appData, - OMX_COMPONENTTYPE **component); - - virtual OMX_ERRORTYPE destroyComponentInstance( - OMX_COMPONENTTYPE *component); - - virtual OMX_ERRORTYPE enumerateComponents( - OMX_STRING name, - size_t size, - OMX_U32 index); - - virtual OMX_ERRORTYPE getRolesOfComponent( - const char *name, - Vector *roles); - -private: - void *mLibHandle; - - typedef OMX_ERRORTYPE (*InitFunc)(); - typedef OMX_ERRORTYPE (*DeinitFunc)(); - typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)( - OMX_STRING, OMX_U32, OMX_U32); - - typedef OMX_ERRORTYPE (*GetHandleFunc)( - OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *); - - typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *); - - typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)( - OMX_STRING, OMX_U32 *, OMX_U8 **); - - InitFunc mInit; - DeinitFunc mDeinit; - ComponentNameEnumFunc mComponentNameEnum; - GetHandleFunc mGetHandle; - FreeHandleFunc mFreeHandle; - GetRolesOfComponentFunc mGetRolesOfComponentHandle; - - SECOMXPlugin(const SECOMXPlugin &); - SECOMXPlugin &operator=(const SECOMXPlugin &); -}; - -} // namespace android - -#endif // SEC_OMX_PLUGIN diff --git a/exynos4/multimedia/openmax/Android.mk b/exynos4/multimedia/openmax/Android.mk deleted file mode 100644 index 6571161..0000000 --- a/exynos4/multimedia/openmax/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/exynos4/multimedia/openmax/sec_omx/Android.mk b/exynos4/multimedia/openmax/sec_omx/Android.mk deleted file mode 100644 index a15f70d..0000000 --- a/exynos4/multimedia/openmax/sec_omx/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -LOCAL_PATH := $(call my-dir) -BOARD_USE_ANB := true - -include $(CLEAR_VARS) - -SEC_OMX_TOP := $(LOCAL_PATH) - -SEC_COPY_HEADERS_TO := libsecmm - -SEC_OMX_INC := $(SEC_OMX_TOP)/include/ -SEC_OMX_COMPONENT := $(SEC_OMX_TOP)/component - -include $(SEC_OMX_TOP)/osal/Android.mk -include $(SEC_OMX_TOP)/core/Android.mk - -include $(SEC_OMX_COMPONENT)/common/Android.mk -include $(SEC_OMX_COMPONENT)/video/dec/Android.mk -include $(SEC_OMX_COMPONENT)/video/dec/h264/Android.mk -include $(SEC_OMX_COMPONENT)/video/dec/mpeg4/Android.mk -include $(SEC_OMX_COMPONENT)/video/dec/vc1/Android.mk -include $(SEC_OMX_COMPONENT)/video/enc/Android.mk -include $(SEC_OMX_COMPONENT)/video/enc/h264/Android.mk -include $(SEC_OMX_COMPONENT)/video/enc/mpeg4/Android.mk - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -include $(SEC_OMX_COMPONENT)/video/dec/vp8/Android.mk -endif - -ifeq ($(BOARD_USE_ALP_AUDIO), true) -include $(SEC_OMX_COMPONENT)/audio/dec/Android.mk -include $(SEC_OMX_COMPONENT)/audio/dec/mp3/Android.mk -endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/Android.mk deleted file mode 100644 index 303737b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/Android.mk +++ /dev/null @@ -1,19 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - SEC_OMX_Adec.c - -LOCAL_MODULE := libSEC_OMX_Adec -LOCAL_ARM_MODE := arm -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/audio/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.c b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.c deleted file mode 100644 index dab7247..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.c +++ /dev/null @@ -1,1376 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Adec.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#include -#include -#include -#include "SEC_OMX_Macros.h" -#include "SEC_OSAL_Event.h" -#include "SEC_OMX_Adec.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_ETC.h" -#include "srp_api.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_AUDIO_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - if (pSECPort->portState != OMX_StateIdle) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = pBuffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBufferHdr = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } -/* - if (pSECPort->portState != OMX_StateIdle ) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } -*/ - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); - if (temp_buffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - SEC_OSAL_Free(temp_buffer); - temp_buffer = NULL; - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = temp_buffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBuffer = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - SEC_OSAL_Free(temp_buffer); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { - (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, - pSECComponent->callbackData, - (OMX_U32)OMX_EventError, - (OMX_U32)OMX_ErrorPortUnpopulated, - nPortIndex, NULL); - } - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { - if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { - if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { - SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); - pSECPort->bufferHeader[i]->pBuffer = NULL; - pBufferHdr->pBuffer = NULL; - } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { - ; /* None*/ - } - pSECPort->assignedBufferNum--; - if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { - SEC_OSAL_Free(pSECPort->bufferHeader[i]); - pSECPort->bufferHeader[i] = NULL; - pBufferHdr = NULL; - } - pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; - ret = OMX_ErrorNone; - goto EXIT; - } - } - } - -EXIT: - if (ret == OMX_ErrorNone) { - if (pSECPort->assignedBufferNum == 0) { - SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - pSECPort->portDefinition.bPopulated = OMX_FALSE; - } - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - OMX_PARAM_PORTDEFINITIONTYPE portDefinition; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT* pSECPort = NULL; - OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - if ((pSECComponent->currentState == OMX_StateExecuting) && - (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) { - return OMX_TRUE; - } else { - return OMX_FALSE; - } -} - -static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { - bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; - bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; - secOMXInputPort->markType.hMarkTargetComponent = NULL; - secOMXInputPort->markType.pMarkData = NULL; - } - - if (bufferHeader->hMarkTargetComponent != NULL) { - if (bufferHeader->hMarkTargetComponent == pOMXComponent) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventMark, - 0, 0, bufferHeader->pMarkData); - } else { - pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; - pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; - } - } - - if (CHECK_PORT_TUNNELED(secOMXInputPort)) { - OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); - } else { - bufferHeader->nFilledLen = 0; - pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE* message = NULL; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; - dataBuffer->dataValid = OMX_TRUE; - dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; - dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; - - SEC_OSAL_Free(message); - - if (dataBuffer->allocSize <= dataBuffer->dataLen) - SEC_OSAL_Log(SEC_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); - } - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - bufferHeader->nFilledLen = dataBuffer->remainDataLen; - bufferHeader->nOffset = 0; - bufferHeader->nFlags = dataBuffer->nFlags; - bufferHeader->nTimeStamp = dataBuffer->timeStamp; - - if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { - bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; - bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; - pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; - pSECComponent->propagateMarkType.pMarkData = NULL; - } - - if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventBufferFlag, - OUTPUT_PORT_INDEX, - bufferHeader->nFlags, NULL); - } - - if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { - OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); - } else { - pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - /* reset dataBuffer */ - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE *message = NULL; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; - dataBuffer->dataValid =OMX_TRUE; - /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ - /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ - pSECComponent->processData[OUTPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; - pSECComponent->processData[OUTPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; - - SEC_OSAL_Free(message); - } - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; - -} - -static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - - return ret; -} - -static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; - - processData->dataLen = 0; - processData->remainDataLen = 0; - processData->usedDataLen = 0; - processData->nFlags = 0; - processData->timeStamp = 0; - - return ret; -} - -OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - OMX_BYTE checkInputStream = NULL; - OMX_U32 checkInputStreamLen = 0; - OMX_U32 checkedSize = 0; - OMX_BOOL flagEOF = OMX_FALSE; - OMX_BOOL previousFrameEOF = OMX_FALSE; - - FunctionIn(); - - if (inputUseBuffer->dataValid == OMX_TRUE) { - checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; - checkInputStreamLen = inputUseBuffer->remainDataLen; - - if (inputData->dataLen == 0) { - previousFrameEOF = OMX_TRUE; - } else { - previousFrameEOF = OMX_FALSE; - } - - /* Audio extractor should parse into frame units. */ - flagEOF = OMX_TRUE; - checkedSize = checkInputStreamLen; - copySize = checkedSize; - - if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) - pSECComponent->bSaveFlagEOS = OMX_TRUE; - - if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { - if (copySize > 0) - SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); - - inputUseBuffer->dataLen -= copySize; - inputUseBuffer->remainDataLen -= copySize; - inputUseBuffer->usedDataLen += copySize; - - inputData->dataLen += copySize; - inputData->remainDataLen += copySize; - - if (previousFrameEOF == OMX_TRUE) { - inputData->timeStamp = inputUseBuffer->timeStamp; - inputData->nFlags = inputUseBuffer->nFlags; - } - - if (pSECComponent->bUseFlagEOF == OMX_TRUE) { - if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } else { - inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - } else { - if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && - ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || - (inputData->dataLen == 0))) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && - (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) && - (inputData->dataLen != 0)) { - inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_TRUE; - } - } else { - inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - } - } else { - /*????????????????????????????????? Error ?????????????????????????????????*/ - SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); - flagEOF = OMX_FALSE; - } - - if ((inputUseBuffer->remainDataLen == 0) || - (CHECK_PORT_BEING_FLUSHED(secInputPort))) - SEC_InputBufferReturn(pOMXComponent); - else - inputUseBuffer->dataValid = OMX_TRUE; - } - - if (flagEOF == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - /* Flush SRP buffers */ - SRP_Flush(); - - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; - pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - SEC_OSAL_Log(SEC_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", - inputData->timeStamp, inputData->timeStamp / 1E6); - } - - ret = OMX_TRUE; - } else { - ret = OMX_FALSE; - } - - FunctionOut(); - - return ret; -} - -OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - FunctionIn(); - - if (outputUseBuffer->dataValid == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) { - pSECComponent->checkTimeStamp.startTimeStamp = -19761123; - pSECComponent->checkTimeStamp.nStartFlags = 0x0; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - } else { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - ret = OMX_TRUE; - goto EXIT; - } - } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - ret = OMX_TRUE; - goto EXIT; - } - - if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { - copySize = outputData->remainDataLen; - - outputUseBuffer->dataLen += copySize; - outputUseBuffer->remainDataLen += copySize; - outputUseBuffer->nFlags = outputData->nFlags; - outputUseBuffer->timeStamp = outputData->timeStamp; - - ret = OMX_TRUE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - - if ((outputUseBuffer->remainDataLen > 0) || - (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) || - (CHECK_PORT_BEING_FLUSHED(secOutputPort))) - SEC_OutputBufferReturn(pOMXComponent); - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); - - ret = OMX_FALSE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - } - } else { - ret = OMX_FALSE; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_AUDIODEC_COMPONENT *pVideoDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - pSECComponent->remainOutputData = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - - FunctionIn(); - - while (!pSECComponent->bExitBufferProcessThread) { - SEC_OSAL_SleepMillisec(0); - - if (((pSECComponent->currentState == OMX_StatePause) || - (pSECComponent->currentState == OMX_StateIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& - ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - while ((SEC_Check_BufferProcess_State(pSECComponent)) && (!pSECComponent->bExitBufferProcessThread)) { - SEC_OSAL_SleepMillisec(0); - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if ((outputUseBuffer->dataValid != OMX_TRUE) && - (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = SEC_OutputBufferGetQueue(pSECComponent); - if ((ret == OMX_ErrorUndefined) || - (secInputPort->portState != OMX_StateIdle) || - (secOutputPort->portState != OMX_StateIdle)) { - break; - } - } else { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - - if (pSECComponent->remainOutputData == OMX_FALSE) { - if (pSECComponent->reInputData == OMX_FALSE) { - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && - (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = SEC_InputBufferGetQueue(pSECComponent); - break; - } - - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - } - - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - - if (ret == OMX_ErrorInputDataDecodeYet) - pSECComponent->reInputData = OMX_TRUE; - else - pSECComponent->reInputData = OMX_FALSE; - } - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - - if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) - pSECComponent->remainOutputData = OMX_TRUE; - else - pSECComponent->remainOutputData = OMX_FALSE; - - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - } - -EXIT: - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - portParam->nPorts = pSECComponent->portParam.nPorts; - portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamAudioPortFormat: - { - OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - - if (portIndex == INPUT_PORT_INDEX) { - supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - portFormat->eEncoding = portDefinition->format.audio.eEncoding; - } else if (portIndex == OUTPUT_PORT_INDEX) { - supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - portFormat->eEncoding = portDefinition->format.audio.eEncoding; - } - ret = OMX_ErrorNone; - } - break; - default: - { - ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} -OMX_ERRORTYPE SEC_OMX_AudioDecodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamAudioPortFormat: - { - OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - portDefinition->format.audio.eEncoding = portFormat->eEncoding; - ret = OMX_ErrorNone; - } - break; - default: - { - ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexConfigAudioMute: - { - SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_IndexConfigAudioMute"); - ret = OMX_ErrorUnsupportedIndex; - } - break; - case OMX_IndexConfigAudioVolume: - { - SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_IndexConfigAudioVolume"); - ret = OMX_ErrorUnsupportedIndex; - } - break; - default: - ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_Port_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pAudioDec = SEC_OSAL_Malloc(sizeof(SEC_OMX_AUDIODEC_COMPONENT)); - if (pAudioDec == NULL) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - - SEC_OSAL_Memset(pAudioDec, 0, sizeof(SEC_OMX_AUDIODEC_COMPONENT)); - pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pAudioDec; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_AUDIO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_AUDIO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = DEFAULT_AUDIO_INPUT_BUFFER_SIZE; - pSECPort->portDefinition.eDomain = OMX_PortDomainAudio; - - pSECPort->portDefinition.format.audio.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); - pSECPort->portDefinition.format.audio.pNativeRender = 0; - pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_AUDIO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_AUDIO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.eDomain = OMX_PortDomainAudio; - - pSECPort->portDefinition.format.audio.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); - pSECPort->portDefinition.format.audio.pNativeRender = 0; - pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; - - - pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; - pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; - pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; - pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; - - pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; - pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; - pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; - pSECComponent->sec_BufferReset = &SEC_BufferReset; - pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; - pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; - int i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OSAL_Free(pAudioDec); - pSECComponent->hComponentHandle = pAudioDec = NULL; - - for(i = 0; i < ALL_PORT_NUM; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - SEC_OSAL_Free(pSECPort->portDefinition.format.audio.cMIMEType); - pSECPort->portDefinition.format.audio.cMIMEType = NULL; - } - - ret = SEC_OMX_Port_Destructor(pOMXComponent); - - ret = SEC_OMX_BaseComponent_Destructor(hComponent); - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.h b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.h deleted file mode 100644 index 8ff20ab..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/SEC_OMX_Adec.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Adec.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#ifndef SEC_OMX_AUDIO_DECODE -#define SEC_OMX_AUDIO_DECODE - -#include "OMX_Component.h" -#include "SEC_OMX_Def.h" -#include "SEC_OSAL_Queue.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" - -#define MAX_AUDIO_INPUTBUFFER_NUM 2 -#define MAX_AUDIO_OUTPUTBUFFER_NUM 2 - -#define DEFAULT_AUDIO_INPUT_BUFFER_SIZE (16 * 1024) -#define DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE (32 * 1024) - -#define DEFAULT_AUDIO_SAMPLING_FREQ 44100 -#define DEFAULT_AUDIO_CHANNELS_NUM 2 -#define DEFAULT_AUDIO_BIT_PER_SAMPLE 16 - -#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 -#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 - -typedef struct _SRP_DEC_INPUT_BUFFER -{ - void *PhyAddr; // physical address - void *VirAddr; // virtual address - int bufferSize; // input buffer alloc size - int dataSize; // Data length -} SRP_DEC_INPUT_BUFFER; - -typedef struct _SEC_OMX_AUDIODEC_COMPONENT -{ - OMX_HANDLETYPE hCodecHandle; - - OMX_BOOL bFirstFrame; - OMX_PTR pInputBuffer; - SRP_DEC_INPUT_BUFFER SRPDecInputBuffer[MAX_AUDIO_INPUTBUFFER_NUM]; - OMX_U32 indexInputBuffer; -} SEC_OMX_AUDIODEC_COMPONENT; - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer); -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes); -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_AudioDecodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_AudioDecodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_AudioDecodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType); -OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); -inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); - -#ifdef __cplusplus -} -#endif - -#endif /* SEC_OMX_AUDIO_DECODE */ diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/Android.mk deleted file mode 100644 index 43af655..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/Android.mk +++ /dev/null @@ -1,31 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Mp3dec.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.MP3.Decoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Adec libsecosal libsecbasecomponent \ - libsrpapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/audio/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.c b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.c deleted file mode 100644 index a8c77f6..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.c +++ /dev/null @@ -1,918 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mp3dec.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Adec.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "library_register.h" -#include "SEC_OMX_Mp3dec.h" -#include "srp_api.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MP3_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -//#define SRP_DUMP_TO_FILE -#ifdef SRP_DUMP_TO_FILE -#include "stdio.h" - -FILE *inFile; -FILE *outFile; -#endif - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamAudioMp3: - { - OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure; - OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL; - SEC_MP3_HANDLE *pMp3Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcMp3Param = &pMp3Dec->mp3Param; - - SEC_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); - } - break; - case OMX_IndexParamAudioPcm: - { - OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure; - OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL; - SEC_MP3_HANDLE *pMp3Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcPcmParam = &pMp3Dec->pcmParam; - - SEC_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_S32 codecType; - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE); - } - break; - default: - ret = SEC_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamAudioMp3: - { - OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL; - OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure; - SEC_MP3_HANDLE *pMp3Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstMp3Param = &pMp3Dec->mp3Param; - - SEC_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); - } - break; - case OMX_IndexParamAudioPcm: - { - OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL; - OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure; - SEC_MP3_HANDLE *pMp3Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstPcmParam = &pMp3Dec->pcmParam; - - SEC_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - default: - ret = SEC_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - ret = SEC_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_ComponentRoleEnum( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 codecType; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MP3_DEC_ROLE); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_MP3_HANDLE *pMp3Dec = (SEC_MP3_HANDLE *)pAudioDec->hCodecHandle; - - FunctionIn(); - - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pSECComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */ - pSECComponent->bSaveFlagEOS = OMX_FALSE; - pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_FALSE; - pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - -#ifdef SRP_DUMP_TO_FILE - inFile = fopen("/data/InFile.mp3", "w+"); - outFile = fopen("/data/OutFile.pcm", "w+"); -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - FunctionIn(); - -#ifdef SRP_DUMP_TO_FILE - fclose(inFile); - fclose(outFile); -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_MP3_HANDLE *pMp3Dec = (SEC_MP3_HANDLE *)pAudioDec->hCodecHandle; - struct srp_dec_info codecDecInfo; - OMX_S32 returnCodec = 0; - unsigned long isSRPStopped = 0; - OMX_PTR dataBuffer = NULL; - unsigned int dataLen = 0; - OMX_BOOL isSRPIbufOverflow = OMX_FALSE; - - FunctionIn(); - -#ifdef SRP_DUMP_TO_FILE - if (pSECComponent->reInputData == OMX_FALSE) { - fwrite(pInputData->dataBuffer, pInputData->dataLen, 1, inFile); - } -#endif - - /* Save timestamp and flags of input data */ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS); - - /* Decoding mp3 frames by SRP */ - if (pSECComponent->getAllDelayBuffer == OMX_FALSE) { - returnCodec = SRP_Decode(pInputData->dataBuffer, pInputData->dataLen); - - if (returnCodec >= 0) { - if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) { - SRP_Send_EOS(); - pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE; - } - } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) { - isSRPIbufOverflow = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } - } - - if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_FALSE) { - returnCodec = SRP_Get_Dec_Info(&codecDecInfo); - if (returnCodec < 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Dec_Info failed: %d", returnCodec); - ret = OMX_ErrorHardware; - goto EXIT; - } - - if (!codecDecInfo.sample_rate || !codecDecInfo.channels) { - if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { - pOutputData->dataLen = 0; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - if (isSRPIbufOverflow) - ret = OMX_ErrorInputDataDecodeYet; - else - ret = OMX_ErrorNone; - } - goto EXIT; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "numChannels(%d), samplingRate(%d)", - codecDecInfo.channels, codecDecInfo.sample_rate); - - if (pMp3Dec->pcmParam.nChannels != codecDecInfo.channels || - pMp3Dec->pcmParam.nSamplingRate != codecDecInfo.sample_rate) { - /* Change channel count and sampling rate information */ - pMp3Dec->pcmParam.nChannels = codecDecInfo.channels; - pMp3Dec->pcmParam.nSamplingRate = codecDecInfo.sample_rate; - - /* Send Port Settings changed call back */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - - pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE; - - if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { - pOutputData->dataLen = 0; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - if (isSRPIbufOverflow) - ret = OMX_ErrorInputDataDecodeYet; - else - ret = OMX_ErrorNone; - } - goto EXIT; - } - - /* Get decoded data from SRP */ - returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen); - if (dataLen > 0) { - pOutputData->dataLen = dataLen; - SEC_OSAL_Memcpy(pOutputData->dataBuffer, dataBuffer, dataLen); - } else { - pOutputData->dataLen = 0; - } - -#ifdef SRP_DUMP_TO_FILE - if (pOutputData->dataLen > 0) - fwrite(pOutputData->dataBuffer, pOutputData->dataLen, 1, outFile); -#endif - - /* Delay EOS signal until all the PCM is returned from the SRP driver. */ - if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) { - if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) { - returnCodec = SRP_GetParams(SRP_STOP_EOS_STATE, &isSRPStopped); - if (returnCodec != 0) - SEC_OSAL_Log(SEC_LOG_ERROR, "Fail SRP_STOP_EOS_STATE"); - if (isSRPStopped == 1) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */ - ret = OMX_ErrorNone; - } else { - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } - } else { /* Flush after EOS */ - pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; - } - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || - (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { - if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) - ret = OMX_ErrorInputDataDecodeYet; - else - ret = OMX_ErrorNone; - - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) - ret = OMX_ErrorInputDataDecodeYet; - else - ret = OMX_ErrorNone; - - goto EXIT; - } - - ret = SEC_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData); - - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataDecodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->previousDataLen = pInputData->dataLen; - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; - SEC_MP3_HANDLE *pMp3Dec = NULL; - OMX_PTR pInputBuffer = NULL; - OMX_PTR pOutputBuffer = NULL; - unsigned int inputBufferSize = 0; - unsigned int inputBufferNum = 0; - unsigned int outputBufferSize = 0; - unsigned int outputBufferNum = 0; - OMX_S32 returnCodec; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MP3_DEC, componentName) != 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_AudioDecodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_AUDIO_DEC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); - ret = OMX_ErrorInsufficientResources; - goto EXIT_ERROR_1; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MP3_DEC); - - pMp3Dec = SEC_OSAL_Malloc(sizeof(SEC_MP3_HANDLE)); - if (pMp3Dec == NULL) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret); - ret = OMX_ErrorInsufficientResources; - goto EXIT_ERROR_2; - } - SEC_OSAL_Memset(pMp3Dec, 0, sizeof(SEC_MP3_HANDLE)); - pAudioDec = (SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle; - pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec; - - /* Create and Init SRP */ - pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_FALSE; - returnCodec = SRP_Create(SRP_INIT_BLOCK_MODE); - if (returnCodec < 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Create failed: %d", returnCodec); - ret = OMX_ErrorHardware; - goto EXIT_ERROR_3; - } - pMp3Dec->hSRPMp3Handle.hSRPHandle = (OMX_HANDLETYPE)returnCodec; /* SRP's fd */ - returnCodec = SRP_Init(); - if (returnCodec < 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Init failed: %d", returnCodec); - ret = OMX_ErrorHardware; - goto EXIT_ERROR_4; - } - pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE; - - /* Get input buffer info from SRP */ - returnCodec = SRP_Get_Ibuf_Info(&pInputBuffer, &inputBufferSize, &inputBufferNum); - if (returnCodec < 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec); - ret = OMX_ErrorHardware; - goto EXIT_ERROR_5; - } - - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = inputBufferSize; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = SEC_OSAL_Malloc(inputBufferSize); - if (pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer == NULL) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Input data buffer alloc failed"); - ret = OMX_ErrorInsufficientResources; - goto EXIT_ERROR_5; - } - - /* Get output buffer info from SRP */ - returnCodec = SRP_Get_Obuf_Info(&pOutputBuffer, &outputBufferSize, &outputBufferNum); - if (returnCodec < 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec); - ret = OMX_ErrorHardware; - goto EXIT_ERROR_6; - } - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = inputBufferNum; - pSECPort->portDefinition.nBufferCountMin = inputBufferNum; - pSECPort->portDefinition.nBufferSize = inputBufferSize; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - SEC_OSAL_Memset(pSECPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/mpeg"); - pSECPort->portDefinition.format.audio.pNativeRender = 0; - pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = outputBufferNum; - pSECPort->portDefinition.nBufferCountMin = outputBufferNum; - pSECPort->portDefinition.nBufferSize = outputBufferSize; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - SEC_OSAL_Memset(pSECPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.audio.cMIMEType, "audio/raw"); - pSECPort->portDefinition.format.audio.pNativeRender = 0; - pSECPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM; - - /* Default values for Mp3 audio param */ - INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE); - pMp3Dec->mp3Param.nPortIndex = INPUT_PORT_INDEX; - pMp3Dec->mp3Param.nChannels = DEFAULT_AUDIO_CHANNELS_NUM; - pMp3Dec->mp3Param.nBitRate = 0; - pMp3Dec->mp3Param.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ; - pMp3Dec->mp3Param.nAudioBandWidth = 0; - pMp3Dec->mp3Param.eChannelMode = OMX_AUDIO_ChannelModeStereo; - pMp3Dec->mp3Param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3; - - /* Default values for PCM audio param */ - INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE); - pMp3Dec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX; - pMp3Dec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM; - pMp3Dec->pcmParam.eNumData = OMX_NumericalDataSigned; - pMp3Dec->pcmParam.eEndian = OMX_EndianLittle; - pMp3Dec->pcmParam.bInterleaved = OMX_TRUE; - pMp3Dec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE; - pMp3Dec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ; - pMp3Dec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear; - pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF; - pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF; - - pOMXComponent->GetParameter = &SEC_SRP_Mp3Dec_GetParameter; - pOMXComponent->SetParameter = &SEC_SRP_Mp3Dec_SetParameter; - pOMXComponent->GetConfig = &SEC_SRP_Mp3Dec_GetConfig; - pOMXComponent->SetConfig = &SEC_SRP_Mp3Dec_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_SRP_Mp3Dec_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_SRP_Mp3Dec_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - /* ToDo: Change the function name associated with a specific codec */ - pSECComponent->sec_mfc_componentInit = &SEC_SRP_Mp3Dec_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_SRP_Mp3Dec_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_SRP_Mp3Dec_bufferProcess; - pSECComponent->sec_checkInputFrame = NULL; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - goto EXIT; /* This function is performed successfully. */ - -EXIT_ERROR_6: - SEC_OSAL_Free(pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer); - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; -EXIT_ERROR_5: - SRP_Deinit(); -EXIT_ERROR_4: - SRP_Terminate(); -EXIT_ERROR_3: - SEC_OSAL_Free(pMp3Dec); - pAudioDec->hCodecHandle = NULL; -EXIT_ERROR_2: - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; -EXIT_ERROR_1: - SEC_OMX_AudioDecodeComponentDeinit(pOMXComponent); -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_MP3_HANDLE *pMp3Dec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - if (pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer) { - SEC_OSAL_Free(pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer); - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; - } - - pMp3Dec = (SEC_MP3_HANDLE *)((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pMp3Dec != NULL) { - if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) { - SRP_Deinit(); - SRP_Terminate(); - } - SEC_OSAL_Free(pMp3Dec); - ((SEC_OMX_AUDIODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_AudioDecodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.h b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.h deleted file mode 100644 index a8b80f5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/SEC_OMX_Mp3dec.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mp3dec.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#ifndef SEC_OMX_MP3_DEC_COMPONENT -#define SEC_OMX_MP3_DEC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" - -typedef struct _SEC_SRP_MP3_HANDLE -{ - OMX_HANDLETYPE hSRPHandle; - OMX_BOOL bConfiguredSRP; - OMX_BOOL bSRPLoaded; - OMX_BOOL bSRPSendEOS; - OMX_S32 returnCodec; -} SEC_SRP_MP3_HANDLE; - -typedef struct _SEC_MP3_HANDLE -{ - /* OMX Codec specific */ - OMX_AUDIO_PARAM_MP3TYPE mp3Param; - OMX_AUDIO_PARAM_PCMMODETYPE pcmParam; - - /* SEC SRP Codec specific */ - SEC_SRP_MP3_HANDLE hSRPMp3Handle; -} SEC_MP3_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); - OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif /* SEC_OMX_MP3_DEC_COMPONENT */ diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.c deleted file mode 100644 index c94377a..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MP3_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) -{ - FunctionIn(); - - if (ppSECComponent == NULL) - goto EXIT; - - /* component 1 - audio decoder MP3 */ - SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MP3_DEC); - SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MP3_DEC_ROLE); - ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.h deleted file mode 100644 index 90ae8c2..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/audio/dec/mp3/library_register.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2011.10.18 : Create - */ - -#ifndef SEC_OMX_MP3_DEC_REG -#define SEC_OMX_MP3_DEC_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 1 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* MP3 */ -#define SEC_OMX_COMPONENT_MP3_DEC "OMX.SEC.MP3.Decoder" -#define SEC_OMX_COMPONENT_MP3_DEC_ROLE "audio_decoder.mp3" - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); - -#ifdef __cplusplus -}; -#endif - -#endif /* SEC_OMX_MP3_DEC_REG */ - diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/common/Android.mk deleted file mode 100644 index a6f84bf..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/Android.mk +++ /dev/null @@ -1,43 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Basecomponent.c \ - SEC_OMX_Baseport.c - -LOCAL_MODULE := libsecbasecomponent - -LOCAL_CFLAGS := - -LOCAL_STATIC_LIBRARIES := libsecosal -LOCAL_SHARED_LIBRARIES := libcutils libutils - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal - -include $(BUILD_STATIC_LIBRARY) - - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Resourcemanager.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libSEC_OMX_Resourcemanager - -LOCAL_CFLAGS := - -LOCAL_STATIC_LIBRARIES := libsecosal -LOCAL_SHARED_LIBRARIES := libcutils libutils - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.c b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.c deleted file mode 100644 index e615d18..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.c +++ /dev/null @@ -1,1535 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Basecomponent.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Event.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Resourcemanager.h" -#include "SEC_OMX_Macros.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_BASE_COMP" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -/* Change CHECK_SIZE_VERSION Macro */ -OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - OMX_VERSIONTYPE* version = NULL; - if (header == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32)); - if (*((OMX_U32*)header) != size) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || - version->s.nVersionMinor != VERSIONMINOR_NUMBER) { - ret = OMX_ErrorVersionMismatch; - goto EXIT; - } - ret = OMX_ErrorNone; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_GetComponentVersion( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STRING pComponentName, - OMX_OUT OMX_VERSIONTYPE *pComponentVersion, - OMX_OUT OMX_VERSIONTYPE *pSpecVersion, - OMX_OUT OMX_UUIDTYPE *pComponentUUID) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_U32 compUUID[3]; - - FunctionIn(); - - /* check parameters */ - if (hComponent == NULL || - pComponentName == NULL || pComponentVersion == NULL || - pSpecVersion == NULL || pComponentUUID == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - SEC_OSAL_Strcpy(pComponentName, pSECComponent->componentName); - SEC_OSAL_Memcpy(pComponentVersion, &(pSECComponent->componentVersion), sizeof(OMX_VERSIONTYPE)); - SEC_OSAL_Memcpy(pSpecVersion, &(pSECComponent->specVersion), sizeof(OMX_VERSIONTYPE)); - - /* Fill UUID with handle address, PID and UID. - * This should guarantee uiniqness */ - compUUID[0] = (OMX_U32)pOMXComponent; - compUUID[1] = getpid(); - compUUID[2] = getuid(); - SEC_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID)); - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_GetState ( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STATETYPE *pState) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pState == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - *pState = pSECComponent->currentState; - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_OMX_BufferProcessThread(OMX_PTR threadData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_MESSAGE *message = NULL; - - FunctionIn(); - - if (threadData == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)threadData; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->sec_BufferProcess(pOMXComponent); - - SEC_OSAL_ThreadExit(NULL); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_MESSAGE *message; - OMX_STATETYPE destState = messageParam; - OMX_STATETYPE currentState = pSECComponent->currentState; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 countValue = 0; - unsigned int i = 0, j = 0; - int k = 0; - - FunctionIn(); - - /* check parameters */ - if (currentState == destState) { - ret = OMX_ErrorSameState; - goto EXIT; - } - if (currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { - ret = SEC_OMX_Get_Resource(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - } - if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded)) || - ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid)) || - ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) || - ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) { - SEC_OMX_Release_Resource(pOMXComponent); - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "destState: %d", destState); - - switch (destState) { - case OMX_StateInvalid: - switch (currentState) { - case OMX_StateWaitForResources: - SEC_OMX_Out_WaitForResource(pOMXComponent); - case OMX_StateIdle: - case OMX_StateExecuting: - case OMX_StatePause: - case OMX_StateLoaded: - pSECComponent->currentState = OMX_StateInvalid; - if (pSECComponent->hBufferProcess) { - pSECComponent->bExitBufferProcessThread = OMX_TRUE; - - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); - if (countValue == 0) - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); - } - - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); - pSECComponent->hBufferProcess = NULL; - - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); - pSECComponent->secDataBuffer[i].bufferMutex = NULL; - } - - SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); - pSECComponent->pSECPort[i].bufferSemID = NULL; - } - } - if (pSECComponent->sec_mfc_componentTerminate != NULL) - pSECComponent->sec_mfc_componentTerminate(pOMXComponent); - - ret = OMX_ErrorInvalidState; - break; - default: - ret = OMX_ErrorInvalidState; - break; - } - break; - case OMX_StateLoaded: - switch (currentState) { - case OMX_StateIdle: - pSECComponent->bExitBufferProcessThread = OMX_TRUE; - - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); - if (countValue == 0) - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); - } - - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); - pSECComponent->hBufferProcess = NULL; - - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); - pSECComponent->secDataBuffer[i].bufferMutex = NULL; - } - - SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); - pSECComponent->pSECPort[i].bufferSemID = NULL; - } - - pSECComponent->sec_mfc_componentTerminate(pOMXComponent); - - for (i = 0; i < (pSECComponent->portParam.nPorts); i++) { - pSECPort = (pSECComponent->pSECPort + i); - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { - message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message != NULL) - SEC_OSAL_Free(message); - } - ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, i); - if (OMX_ErrorNone != ret) { - goto EXIT; - } - } else { - if (CHECK_PORT_ENABLED(pSECPort)) { - SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); - pSECPort->portDefinition.bPopulated = OMX_FALSE; - } - } - } - pSECComponent->currentState = OMX_StateLoaded; - break; - case OMX_StateWaitForResources: - ret = SEC_OMX_Out_WaitForResource(pOMXComponent); - pSECComponent->currentState = OMX_StateLoaded; - break; - case OMX_StateExecuting: - case OMX_StatePause: - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - break; - case OMX_StateIdle: - switch (currentState) { - case OMX_StateLoaded: - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECPort = (pSECComponent->pSECPort + i); - if (pSECPort == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - if (CHECK_PORT_ENABLED(pSECPort)) { - ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, i); - if (ret!=OMX_ErrorNone) - goto EXIT; - } - } else { - if (CHECK_PORT_ENABLED(pSECPort)) { - SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[i].loadedResource); - pSECPort->portDefinition.bPopulated = OMX_TRUE; - } - } - } - ret = pSECComponent->sec_mfc_componentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - /* - * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free - */ - goto EXIT; - } - pSECComponent->bExitBufferProcessThread = OMX_FALSE; - SEC_OSAL_SignalCreate(&pSECComponent->pauseEvent); - for (i = 0; i < ALL_PORT_NUM; i++) { - ret = SEC_OSAL_SemaphoreCreate(&pSECComponent->pSECPort[i].bufferSemID); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - } - for (i = 0; i < ALL_PORT_NUM; i++) { - ret = SEC_OSAL_MutexCreate(&pSECComponent->secDataBuffer[i].bufferMutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - } - ret = SEC_OSAL_ThreadCreate(&pSECComponent->hBufferProcess, - SEC_OMX_BufferProcessThread, - pOMXComponent); - if (ret != OMX_ErrorNone) { - /* - * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free - */ - - SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); - pSECComponent->secDataBuffer[i].bufferMutex = NULL; - } - for (i = 0; i < ALL_PORT_NUM; i++) { - SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); - pSECComponent->pSECPort[i].bufferSemID = NULL; - } - - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pSECComponent->currentState = OMX_StateIdle; - break; - case OMX_StateExecuting: - case OMX_StatePause: - SEC_OMX_BufferFlushProcessNoEvent(pOMXComponent, ALL_PORT_INDEX); - pSECComponent->currentState = OMX_StateIdle; - break; - case OMX_StateWaitForResources: - pSECComponent->currentState = OMX_StateIdle; - break; - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - break; - case OMX_StateExecuting: - switch (currentState) { - case OMX_StateLoaded: - ret = OMX_ErrorIncorrectStateTransition; - break; - case OMX_StateIdle: - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { - for (j = 0; j < pSECPort->tunnelBufferNum; j++) { - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); - } - } - } - - pSECComponent->transientState = SEC_OMX_TransStateMax; - pSECComponent->currentState = OMX_StateExecuting; - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - break; - case OMX_StatePause: - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { - OMX_S32 semaValue = 0, cnt = 0; - SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &semaValue); - if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > semaValue) { - cnt = SEC_OSAL_GetElemNum(&pSECPort->bufferQ) - semaValue; - for (k = 0; k < cnt; k++) { - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); - } - } - } - } - - pSECComponent->currentState = OMX_StateExecuting; - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - break; - case OMX_StateWaitForResources: - ret = OMX_ErrorIncorrectStateTransition; - break; - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - break; - case OMX_StatePause: - switch (currentState) { - case OMX_StateLoaded: - ret = OMX_ErrorIncorrectStateTransition; - break; - case OMX_StateIdle: - pSECComponent->currentState = OMX_StatePause; - break; - case OMX_StateExecuting: - pSECComponent->currentState = OMX_StatePause; - break; - case OMX_StateWaitForResources: - ret = OMX_ErrorIncorrectStateTransition; - break; - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - break; - case OMX_StateWaitForResources: - switch (currentState) { - case OMX_StateLoaded: - ret = SEC_OMX_In_WaitForResource(pOMXComponent); - pSECComponent->currentState = OMX_StateWaitForResources; - break; - case OMX_StateIdle: - case OMX_StateExecuting: - case OMX_StatePause: - ret = OMX_ErrorIncorrectStateTransition; - break; - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - break; - default: - ret = OMX_ErrorIncorrectStateTransition; - break; - } - -EXIT: - if (ret == OMX_ErrorNone) { - if (pSECComponent->pCallbacks != NULL) { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventCmdComplete, OMX_CommandStateSet, - destState, NULL); - } - } else { - if (pSECComponent->pCallbacks != NULL) { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_OMX_MessageHandlerThread(OMX_PTR threadData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_MESSAGE *message = NULL; - OMX_U32 messageType = 0, portIndex = 0; - - FunctionIn(); - - if (threadData == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)threadData; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - while (pSECComponent->bExitMessageHandlerThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pSECComponent->msgSemaphoreHandle); - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECComponent->messageQ); - if (message != NULL) { - messageType = message->messageType; - switch (messageType) { - case OMX_CommandStateSet: - ret = SEC_OMX_ComponentStateSet(pOMXComponent, message->messageParam); - break; - case OMX_CommandFlush: - ret = SEC_OMX_BufferFlushProcess(pOMXComponent, message->messageParam); - break; - case OMX_CommandPortDisable: - ret = SEC_OMX_PortDisableProcess(pOMXComponent, message->messageParam); - break; - case OMX_CommandPortEnable: - ret = SEC_OMX_PortEnableProcess(pOMXComponent, message->messageParam); - break; - case OMX_CommandMarkBuffer: - portIndex = message->messageParam; - pSECComponent->pSECPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent; - pSECComponent->pSECPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData; - break; - case (OMX_COMMANDTYPE)SEC_OMX_CommandComponentDeInit: - pSECComponent->bExitMessageHandlerThread = OMX_TRUE; - break; - default: - break; - } - SEC_OSAL_Free(message); - message = NULL; - } - } - - SEC_OSAL_ThreadExit(NULL); - -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_StateSet(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) -{ - OMX_U32 destState = nParam; - OMX_U32 i = 0; - - if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateLoaded)) { - pSECComponent->transientState = SEC_OMX_TransStateLoadedToIdle; - for(i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECComponent->pSECPort[i].portState = OMX_StateIdle; - } - SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); - } else if ((destState == OMX_StateLoaded) && (pSECComponent->currentState == OMX_StateIdle)) { - pSECComponent->transientState = SEC_OMX_TransStateIdleToLoaded; - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECComponent->pSECPort[i].portState = OMX_StateLoaded; - } - SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateLoaded"); - } else if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateExecuting)) { - pSECComponent->transientState = SEC_OMX_TransStateExecutingToIdle; - SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); - } else if ((destState == OMX_StateExecuting) && (pSECComponent->currentState == OMX_StateIdle)) { - pSECComponent->transientState = SEC_OMX_TransStateIdleToExecuting; - SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateExecuting"); - } else if (destState == OMX_StateInvalid) { - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECComponent->pSECPort[i].portState = OMX_StateInvalid; - } - } - - return OMX_ErrorNone; -} - -static OMX_ERRORTYPE SEC_SetPortFlush(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 portIndex = nParam; - OMX_U16 i = 0, cnt = 0, index = 0; - - - if ((pSECComponent->currentState == OMX_StateExecuting) || - (pSECComponent->currentState == OMX_StatePause)) { - if ((portIndex != ALL_PORT_INDEX) && - ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - /********************* - * need flush event set ????? - **********************/ - cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; - for (i = 0; i < cnt; i++) { - if (portIndex == ALL_PORT_INDEX) - index = i; - else - index = portIndex; - pSECComponent->pSECPort[index].bIsPortFlushed = OMX_TRUE; - } - } else { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - ret = OMX_ErrorNone; - -EXIT: - return ret; -} - -static OMX_ERRORTYPE SEC_SetPortEnable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 portIndex = nParam; - OMX_U16 i = 0, cnt = 0; - - FunctionIn(); - - if ((portIndex != ALL_PORT_INDEX) && - ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if (portIndex == ALL_PORT_INDEX) { - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - if (CHECK_PORT_ENABLED(pSECPort)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } else { - pSECPort->portState = OMX_StateIdle; - } - } - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - if (CHECK_PORT_ENABLED(pSECPort)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } else { - pSECPort->portState = OMX_StateIdle; - } - } - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; - -} - -static OMX_ERRORTYPE SEC_SetPortDisable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 portIndex = nParam; - OMX_U16 i = 0, cnt = 0; - - FunctionIn(); - - if ((portIndex != ALL_PORT_INDEX) && - ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if (portIndex == ALL_PORT_INDEX) { - for (i = 0; i < pSECComponent->portParam.nPorts; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - if (!CHECK_PORT_ENABLED(pSECPort)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - pSECPort->portState = OMX_StateLoaded; - pSECPort->bIsPortDisabled = OMX_TRUE; - } - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - pSECPort->portState = OMX_StateLoaded; - pSECPort->bIsPortDisabled = OMX_TRUE; - } - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_SetMarkBuffer(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_U32 portIndex = nParam; - OMX_U16 i = 0, cnt = 0; - - - if (nParam >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if ((pSECComponent->currentState == OMX_StateExecuting) || - (pSECComponent->currentState == OMX_StatePause)) { - ret = OMX_ErrorNone; - } else { - ret = OMX_ErrorIncorrectStateOperation; - } - -EXIT: - return ret; -} - -static OMX_ERRORTYPE SEC_OMX_CommandQueue( - SEC_OMX_BASECOMPONENT *pSECComponent, - OMX_COMMANDTYPE Cmd, - OMX_U32 nParam, - OMX_PTR pCmdData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_MESSAGE *command = (SEC_OMX_MESSAGE *)SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); - - if (command == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - command->messageType = (OMX_U32)Cmd; - command->messageParam = nParam; - command->pCmdData = pCmdData; - - ret = SEC_OSAL_Queue(&pSECComponent->messageQ, (void *)command); - if (ret != 0) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - ret = SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_SendCommand( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_COMMANDTYPE Cmd, - OMX_IN OMX_U32 nParam, - OMX_IN OMX_PTR pCmdData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_MESSAGE *message = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (Cmd) { - case OMX_CommandStateSet : - SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandStateSet"); - SEC_StateSet(pSECComponent, nParam); - break; - case OMX_CommandFlush : - SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandFlush"); - ret = SEC_SetPortFlush(pSECComponent, nParam); - if (ret != OMX_ErrorNone) - goto EXIT; - break; - case OMX_CommandPortDisable : - SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortDisable"); - ret = SEC_SetPortDisable(pSECComponent, nParam); - if (ret != OMX_ErrorNone) - goto EXIT; - break; - case OMX_CommandPortEnable : - SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortEnable"); - ret = SEC_SetPortEnable(pSECComponent, nParam); - if (ret != OMX_ErrorNone) - goto EXIT; - break; - case OMX_CommandMarkBuffer : - SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandMarkBuffer"); - ret = SEC_SetMarkBuffer(pSECComponent, nParam); - if (ret != OMX_ErrorNone) - goto EXIT; - break; -/* - case SEC_CommandFillBuffer : - case SEC_CommandEmptyBuffer : - case SEC_CommandDeInit : -*/ - default: - break; - } - - ret = SEC_OMX_CommandQueue(pSECComponent, Cmd, nParam, pCmdData); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case (OMX_INDEXTYPE)OMX_COMPONENT_CAPABILITY_TYPE_INDEX: - { - /* For Android PV OpenCORE */ - OMXComponentCapabilityFlagsType *capabilityFlags = (OMXComponentCapabilityFlagsType *)ComponentParameterStructure; - SEC_OSAL_Memcpy(capabilityFlags, &pSECComponent->capabilityFlags, sizeof(OMXComponentCapabilityFlagsType)); - } - break; - case OMX_IndexParamAudioInit: - case OMX_IndexParamVideoInit: - case OMX_IndexParamImageInit: - case OMX_IndexParamOtherInit: - { - OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - portParam->nPorts = 0; - portParam->nStartPortNumber = 0; - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize); - } - break; - case OMX_IndexParamPriorityMgmt: - { - OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - compPriority->nGroupID = pSECComponent->compPriority.nGroupID; - compPriority->nGroupPriority = pSECComponent->compPriority.nGroupPriority; - } - break; - - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = bufferSupplier->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - - if ((pSECComponent->currentState == OMX_StateLoaded) || - (pSECComponent->currentState == OMX_StateWaitForResources)) { - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - - if (pSECPort->portDefinition.eDir == OMX_DirInput) { - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; - } else if (CHECK_PORT_TUNNELED(pSECPort)) { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; - } else { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; - } - } else { - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; - } else if (CHECK_PORT_TUNNELED(pSECPort)) { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; - } else { - bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; - } - } - } - else - { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - break; - default: - { - ret = OMX_ErrorUnsupportedIndex; - goto EXIT; - } - break; - } - - ret = OMX_ErrorNone; - -EXIT: - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamAudioInit: - case OMX_IndexParamVideoInit: - case OMX_IndexParamImageInit: - case OMX_IndexParamOtherInit: - { - OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && - (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - ret = OMX_ErrorUndefined; - /* SEC_OSAL_Memcpy(&pSECComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */ - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if (portDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, portDefinition, portDefinition->nSize); - } - break; - case OMX_IndexParamPriorityMgmt: - { - OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; - - if ((pSECComponent->currentState != OMX_StateLoaded) && - (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECComponent->compPriority.nGroupID = compPriority->nGroupID; - pSECComponent->compPriority.nGroupPriority = compPriority->nGroupPriority; - } - break; - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = bufferSupplier->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - - if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) { - ret = OMX_ErrorNone; - goto EXIT; - } - if (CHECK_PORT_TUNNELED(pSECPort) == 0) { - ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/ - goto EXIT; - } - - if (pSECPort->portDefinition.eDir == OMX_DirInput) { - if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { - /* - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorNone; - } - */ - pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; - bufferSupplier->nPortIndex = pSECPort->tunneledPort; - ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); - goto EXIT; - } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { - ret = OMX_ErrorNone; - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; - bufferSupplier->nPortIndex = pSECPort->tunneledPort; - ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); - } - goto EXIT; - } - } else if (pSECPort->portDefinition.eDir == OMX_DirOutput) { - if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { - ret = OMX_ErrorNone; - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; - ret = OMX_ErrorNone; - } - goto EXIT; - } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { - /* - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorNone; - } - */ - pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; - ret = OMX_ErrorNone; - goto EXIT; - } - } - } - break; - default: - { - ret = OMX_ErrorUnsupportedIndex; - goto EXIT; - } - break; - } - - ret = OMX_ErrorNone; - -EXIT: - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_GetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = OMX_ErrorUnsupportedIndex; - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = OMX_ErrorUnsupportedIndex; - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - ret = OMX_ErrorBadParameter; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_SetCallbacks ( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_CALLBACKTYPE* pCallbacks, - OMX_IN OMX_PTR pAppData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pCallbacks == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - if (pSECComponent->currentState != OMX_StateLoaded) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - pSECComponent->pCallbacks = pCallbacks; - pSECComponent->callbackData = pAppData; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_UseEGLImage( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN void *eglImage) -{ - return OMX_ErrorNotImplemented; -} - -OMX_ERRORTYPE SEC_OMX_BaseComponent_Constructor( - OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASECOMPONENT)); - if (pSECComponent == NULL) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent, 0, sizeof(SEC_OMX_BASECOMPONENT)); - pOMXComponent->pComponentPrivate = (OMX_PTR)pSECComponent; - - ret = SEC_OSAL_SemaphoreCreate(&pSECComponent->msgSemaphoreHandle); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - ret = SEC_OSAL_MutexCreate(&pSECComponent->compMutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - - pSECComponent->bExitMessageHandlerThread = OMX_FALSE; - SEC_OSAL_QueueCreate(&pSECComponent->messageQ); - ret = SEC_OSAL_ThreadCreate(&pSECComponent->hMessageHandler, SEC_OMX_MessageHandlerThread, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - - pOMXComponent->GetComponentVersion = &SEC_OMX_GetComponentVersion; - pOMXComponent->SendCommand = &SEC_OMX_SendCommand; - pOMXComponent->GetState = &SEC_OMX_GetState; - pOMXComponent->SetCallbacks = &SEC_OMX_SetCallbacks; - pOMXComponent->UseEGLImage = &SEC_OMX_UseEGLImage; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BaseComponent_Destructor( - OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 semaValue = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OMX_CommandQueue(pSECComponent, SEC_OMX_CommandComponentDeInit, 0, NULL); - SEC_OSAL_SleepMillisec(0); - SEC_OSAL_Get_SemaphoreCount(pSECComponent->msgSemaphoreHandle, &semaValue); - if (semaValue == 0) - SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); - SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); - - SEC_OSAL_ThreadTerminate(pSECComponent->hMessageHandler); - pSECComponent->hMessageHandler = NULL; - - SEC_OSAL_MutexTerminate(pSECComponent->compMutex); - pSECComponent->compMutex = NULL; - SEC_OSAL_SemaphoreTerminate(pSECComponent->msgSemaphoreHandle); - pSECComponent->msgSemaphoreHandle = NULL; - SEC_OSAL_QueueTerminate(&pSECComponent->messageQ); - - SEC_OSAL_Free(pSECComponent); - pSECComponent = NULL; - - ret = OMX_ErrorNone; -EXIT: - FunctionOut(); - - return ret; -} - - diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.h b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.h deleted file mode 100644 index 47c6771..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Basecomponent.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Basecomponent.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_BASECOMP -#define SEC_OMX_BASECOMP - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OSAL_Queue.h" -#include "SEC_OMX_Baseport.h" - - -typedef struct _SEC_OMX_MESSAGE -{ - OMX_U32 messageType; - OMX_U32 messageParam; - OMX_PTR pCmdData; -} SEC_OMX_MESSAGE; - -typedef struct _SEC_OMX_DATABUFFER -{ - OMX_HANDLETYPE bufferMutex; - OMX_BUFFERHEADERTYPE* bufferHeader; - OMX_BOOL dataValid; - OMX_U32 allocSize; - OMX_U32 dataLen; - OMX_U32 usedDataLen; - OMX_U32 remainDataLen; - OMX_U32 nFlags; - OMX_TICKS timeStamp; -} SEC_OMX_DATABUFFER; - -typedef struct _SEC_OMX_DATA -{ - OMX_BYTE dataBuffer; - OMX_U32 allocSize; - OMX_U32 dataLen; - OMX_U32 usedDataLen; - OMX_U32 remainDataLen; - OMX_U32 previousDataLen; - OMX_U32 nFlags; - OMX_TICKS timeStamp; -} SEC_OMX_DATA; - -/* for Check TimeStamp after Seek */ -typedef struct _SEC_OMX_TIMESTAPM -{ - OMX_BOOL needSetStartTimeStamp; - OMX_BOOL needCheckStartTimeStamp; - OMX_TICKS startTimeStamp; - OMX_U32 nStartFlags; -} SEC_OMX_TIMESTAMP; - -typedef struct _SEC_OMX_BASECOMPONENT -{ - OMX_STRING componentName; - OMX_VERSIONTYPE componentVersion; - OMX_VERSIONTYPE specVersion; - - OMX_STATETYPE currentState; - SEC_OMX_TRANS_STATETYPE transientState; - - SEC_CODEC_TYPE codecType; - SEC_OMX_PRIORITYMGMTTYPE compPriority; - OMX_MARKTYPE propagateMarkType; - OMX_HANDLETYPE compMutex; - - OMX_HANDLETYPE hComponentHandle; - - /* Message Handler */ - OMX_BOOL bExitMessageHandlerThread; - OMX_HANDLETYPE hMessageHandler; - OMX_HANDLETYPE msgSemaphoreHandle; - SEC_QUEUE messageQ; - - /* Buffer Process */ - OMX_BOOL bExitBufferProcessThread; - OMX_HANDLETYPE hBufferProcess; - - /* Buffer */ - SEC_OMX_DATABUFFER secDataBuffer[2]; - - /* Data */ - SEC_OMX_DATA processData[2]; - - /* Port */ - OMX_PORT_PARAM_TYPE portParam; - SEC_OMX_BASEPORT *pSECPort; - - OMX_HANDLETYPE pauseEvent; - - /* Callback function */ - OMX_CALLBACKTYPE *pCallbacks; - OMX_PTR callbackData; - - /* Save Timestamp */ - OMX_TICKS timeStamp[MAX_TIMESTAMP]; - SEC_OMX_TIMESTAMP checkTimeStamp; - - /* Save Flags */ - OMX_U32 nFlags[MAX_FLAGS]; - - OMX_BOOL getAllDelayBuffer; - OMX_BOOL remainOutputData; - OMX_BOOL reInputData; - - /* Android CapabilityFlags */ - OMXComponentCapabilityFlagsType capabilityFlags; - - OMX_BOOL bUseFlagEOF; - OMX_BOOL bSaveFlagEOS; - - OMX_ERRORTYPE (*sec_mfc_componentInit)(OMX_COMPONENTTYPE *pOMXComponent); - OMX_ERRORTYPE (*sec_mfc_componentTerminate)(OMX_COMPONENTTYPE *pOMXComponent); - OMX_ERRORTYPE (*sec_mfc_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData); - - OMX_ERRORTYPE (*sec_AllocateTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); - OMX_ERRORTYPE (*sec_FreeTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); - OMX_ERRORTYPE (*sec_BufferProcess)(OMX_HANDLETYPE hComponent); - OMX_ERRORTYPE (*sec_BufferReset)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); - OMX_ERRORTYPE (*sec_InputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); - OMX_ERRORTYPE (*sec_OutputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); - - OMX_ERRORTYPE (*sec_allocSecureInputBuffer)(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nBufferSize, - OMX_INOUT OMX_PTR *pInputBuffer_physicalAddress); - OMX_ERRORTYPE (*sec_freeSecureInputBuffer)(OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_PTR pInputBuffer_physicalAddress); - - int (*sec_checkInputFrame)(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); -} SEC_OMX_BASECOMPONENT; - -OMX_ERRORTYPE SEC_OMX_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure); - -OMX_ERRORTYPE SEC_OMX_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure); - -OMX_ERRORTYPE SEC_OMX_GetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR pComponentConfigStructure); - -OMX_ERRORTYPE SEC_OMX_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure); - -OMX_ERRORTYPE SEC_OMX_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType); - -OMX_ERRORTYPE SEC_OMX_BaseComponent_Constructor(OMX_IN OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_BaseComponent_Destructor(OMX_IN OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -extern "C" { -#endif - - OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size); - - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.c b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.c deleted file mode 100644 index 3bd37f5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Baseport.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OSAL_Event.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Mutex.h" - -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_BASE_PORT" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OMX_ERRORTYPE SEC_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *bufferHeader = NULL; - SEC_OMX_MESSAGE *message = NULL; - OMX_U32 flushNum = 0; - OMX_S32 semValue = 0; - - FunctionIn(); - - pSECPort = &pSECComponent->pSECPort[portIndex]; - while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { - SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &semValue); - if (semValue == 0) - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); - SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); - - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message != NULL) { - bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; - bufferHeader->nFilledLen = 0; - - if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - if (portIndex) { - OMX_EmptyThisBuffer(pSECPort->tunneledComponent, bufferHeader); - } else { - OMX_FillThisBuffer(pSECPort->tunneledComponent, bufferHeader); - } - SEC_OSAL_Free(message); - message = NULL; - } else if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Tunneled mode is not working, Line:%d", __LINE__); - ret = OMX_ErrorNotImplemented; - SEC_OSAL_Queue(&pSECPort->bufferQ, pSECPort); - goto EXIT; - } else { - if (portIndex == OUTPUT_PORT_INDEX) { - pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } else { - pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - - SEC_OSAL_Free(message); - message = NULL; - } - } - } - - if (pSECComponent->secDataBuffer[portIndex].dataValid == OMX_TRUE) { - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); - message->pCmdData = pSECComponent->secDataBuffer[portIndex].bufferHeader; - message->messageType = 0; - message->messageParam = -1; - SEC_OSAL_Queue(&pSECPort->bufferQ, message); - pSECComponent->sec_BufferReset(pOMXComponent, portIndex); - } else { - if (portIndex == INPUT_PORT_INDEX) - pSECComponent->sec_InputBufferReturn(pOMXComponent); - else if (portIndex == OUTPUT_PORT_INDEX) - pSECComponent->sec_OutputBufferReturn(pOMXComponent); - } - } - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) < (int)pSECPort->assignedBufferNum) { - SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); - } - if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) != (int)pSECPort->assignedBufferNum) - SEC_OSAL_SetElemNum(&pSECPort->bufferQ, pSECPort->assignedBufferNum); - } else { - while(1) { - OMX_S32 cnt = 0; - SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &cnt); - if (cnt <= 0) - break; - SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); - } - SEC_OSAL_SetElemNum(&pSECPort->bufferQ, 0); - } - - pSECComponent->processData[portIndex].dataLen = 0; - pSECComponent->processData[portIndex].nFlags = 0; - pSECComponent->processData[portIndex].remainDataLen = 0; - pSECComponent->processData[portIndex].timeStamp = 0; - pSECComponent->processData[portIndex].usedDataLen = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 portIndex = 0; - OMX_U32 i = 0, cnt = 0; - SEC_OMX_DATABUFFER *flushBuffer = NULL; - - FunctionIn(); - - if (pOMXComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; - - for (i = 0; i < cnt; i++) { - if (nPortIndex == ALL_PORT_INDEX) - portIndex = i; - else - portIndex = nPortIndex; - - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - - flushBuffer = &pSECComponent->secDataBuffer[portIndex]; - - SEC_OSAL_MutexLock(flushBuffer->bufferMutex); - ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); - SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); - - pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; - - if (ret == OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_TRACE,"OMX_CommandFlush EventCmdComplete"); - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventCmdComplete, - OMX_CommandFlush, portIndex, NULL); - } - - if (portIndex == INPUT_PORT_INDEX) { - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - } else if (portIndex == OUTPUT_PORT_INDEX) { - pSECComponent->remainOutputData = OMX_FALSE; - } - } - -EXIT: - if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, - ret, 0, NULL); - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_S32 portIndex = 0; - OMX_U32 i = 0, cnt = 0; - SEC_OMX_DATABUFFER *flushBuffer = NULL; - - FunctionIn(); - - if (pOMXComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; - - for (i = 0; i < cnt; i++) { - if (nPortIndex == ALL_PORT_INDEX) - portIndex = i; - else - portIndex = nPortIndex; - - pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; - - SEC_OSAL_SignalSet(pSECComponent->pauseEvent); - - flushBuffer = &pSECComponent->secDataBuffer[portIndex]; - - SEC_OSAL_MutexLock(flushBuffer->bufferMutex); - ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); - SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); - - pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; - - if (portIndex == INPUT_PORT_INDEX) { - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - pSECComponent->remainOutputData = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - } else if (portIndex == OUTPUT_PORT_INDEX) { - pSECComponent->remainOutputData = OMX_FALSE; - } - } - -EXIT: - if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, - ret, 0, NULL); - } - - FunctionOut(); - - return ret; -} - - -OMX_ERRORTYPE SEC_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_U32 i = 0, cnt = 0; - - FunctionIn(); - - pSECPort = &pSECComponent->pSECPort[portIndex]; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, portIndex); - if (OMX_ErrorNone != ret) { - goto EXIT; - } - pSECPort->portDefinition.bPopulated = OMX_TRUE; - if (pSECComponent->currentState == OMX_StateExecuting) { - for (i=0; itunnelBufferNum; i++) { - SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); - } - } - } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); - pSECPort->portDefinition.bPopulated = OMX_TRUE; - } - } else { - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); - pSECPort->portDefinition.bPopulated = OMX_TRUE; - } - } - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 portIndex = 0; - OMX_U32 i = 0, cnt = 0; - - FunctionIn(); - - if (pOMXComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; - - for (i = 0; i < cnt; i++) { - if (nPortIndex == ALL_PORT_INDEX) - portIndex = i; - else - portIndex = nPortIndex; - - ret = SEC_OMX_EnablePort(pOMXComponent, portIndex); - if (ret == OMX_ErrorNone) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventCmdComplete, - OMX_CommandPortEnable, portIndex, NULL); - } - } - -EXIT: - if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, - ret, 0, NULL); - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_U32 i = 0, elemNum = 0; - SEC_OMX_MESSAGE *message; - - FunctionIn(); - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if (!CHECK_PORT_ENABLED(pSECPort)) { - ret = OMX_ErrorNone; - goto EXIT; - } - - if (pSECComponent->currentState!=OMX_StateLoaded) { - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { - message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - SEC_OSAL_Free(message); - } - ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, portIndex); - if (OMX_ErrorNone != ret) { - goto EXIT; - } - pSECPort->portDefinition.bPopulated = OMX_FALSE; - } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - pSECPort->portDefinition.bPopulated = OMX_FALSE; - SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); - } else { - if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { - message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - SEC_OSAL_Free(message); - } - } - pSECPort->portDefinition.bPopulated = OMX_FALSE; - SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); - } - } - pSECPort->portDefinition.bEnabled = OMX_FALSE; - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 portIndex = 0; - OMX_U32 i = 0, cnt = 0; - SEC_OMX_DATABUFFER *flushBuffer = NULL; - - FunctionIn(); - - if (pOMXComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; - - /* port flush*/ - for(i = 0; i < cnt; i++) { - if (nPortIndex == ALL_PORT_INDEX) - portIndex = i; - else - portIndex = nPortIndex; - - pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; - - flushBuffer = &pSECComponent->secDataBuffer[portIndex]; - - SEC_OSAL_MutexLock(flushBuffer->bufferMutex); - ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); - SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); - - pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; - - if (portIndex == INPUT_PORT_INDEX) { - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - } else if (portIndex == OUTPUT_PORT_INDEX) { - pSECComponent->remainOutputData = OMX_FALSE; - } - } - - for(i = 0; i < cnt; i++) { - if (nPortIndex == ALL_PORT_INDEX) - portIndex = i; - else - portIndex = nPortIndex; - - ret = SEC_OMX_DisablePort(pOMXComponent, portIndex); - pSECComponent->pSECPort[portIndex].bIsPortDisabled = OMX_FALSE; - if (ret == OMX_ErrorNone) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventCmdComplete, - OMX_CommandPortDisable, portIndex, NULL); - } - } - -EXIT: - if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pSECComponent != NULL)) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, - ret, 0, NULL); - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_EmptyThisBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BOOL findBuffer = OMX_FALSE; - SEC_OMX_MESSAGE *message; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (pBuffer == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateIdle) && - (pSECComponent->currentState != OMX_StateExecuting) && - (pSECComponent->currentState != OMX_StatePause)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - if ((!CHECK_PORT_ENABLED(pSECPort)) || - ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && - (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || - ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && - (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pBuffer == pSECPort->bufferHeader[i]) { - findBuffer = OMX_TRUE; - break; - } - } - - if (findBuffer == OMX_FALSE) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } else { - ret = OMX_ErrorNone; - } - - message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); - if (message == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - message->messageType = SEC_OMX_CommandEmptyBuffer; - message->messageParam = (OMX_U32) i; - message->pCmdData = (OMX_PTR)pBuffer; - - ret = SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); - if (ret != 0) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - ret = SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FillThisBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BOOL findBuffer = OMX_FALSE; - SEC_OMX_MESSAGE *message; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (pBuffer == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateIdle) && - (pSECComponent->currentState != OMX_StateExecuting) && - (pSECComponent->currentState != OMX_StatePause)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - if ((!CHECK_PORT_ENABLED(pSECPort)) || - ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && - (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || - ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && - (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pBuffer == pSECPort->bufferHeader[i]) { - findBuffer = OMX_TRUE; - break; - } - } - - if (findBuffer == OMX_FALSE) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } else { - ret = OMX_ErrorNone; - } - - message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); - if (message == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - message->messageType = SEC_OMX_CommandFillBuffer; - message->messageParam = (OMX_U32) i; - message->pCmdData = (OMX_PTR)pBuffer; - - ret = SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); - if (ret != 0) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - ret = SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - int i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - INIT_SET_SIZE_VERSION(&pSECComponent->portParam, OMX_PORT_PARAM_TYPE); - pSECComponent->portParam.nPorts = ALL_PORT_NUM; - pSECComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; - - pSECPort = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); - if (pSECPort == NULL) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECPort, 0, sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); - pSECComponent->pSECPort = pSECPort; - - /* Input Port */ - pSECInputPort = &pSECPort[INPUT_PORT_INDEX]; - - SEC_OSAL_QueueCreate(&pSECInputPort->bufferQ); - - pSECInputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); - if (pSECInputPort->bufferHeader == NULL) { - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECInputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); - - pSECInputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); - if (pSECInputPort->bufferStateAllocate == NULL) { - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); - - pSECInputPort->bufferSemID = NULL; - pSECInputPort->assignedBufferNum = 0; - pSECInputPort->portState = OMX_StateMax; - pSECInputPort->bIsPortFlushed = OMX_FALSE; - pSECInputPort->bIsPortDisabled = OMX_FALSE; - pSECInputPort->tunneledComponent = NULL; - pSECInputPort->tunneledPort = 0; - pSECInputPort->tunnelBufferNum = 0; - pSECInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; - pSECInputPort->tunnelFlags = 0; - ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->loadedResource); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - goto EXIT; - } - ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->unloadedResource); - if (ret != OMX_ErrorNone) { - SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); - pSECInputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - goto EXIT; - } - - INIT_SET_SIZE_VERSION(&pSECInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); - pSECInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; - pSECInputPort->portDefinition.eDir = OMX_DirInput; - pSECInputPort->portDefinition.nBufferCountActual = 0; - pSECInputPort->portDefinition.nBufferCountMin = 0; - pSECInputPort->portDefinition.nBufferSize = 0; - pSECInputPort->portDefinition.bEnabled = OMX_FALSE; - pSECInputPort->portDefinition.bPopulated = OMX_FALSE; - pSECInputPort->portDefinition.eDomain = OMX_PortDomainMax; - pSECInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; - pSECInputPort->portDefinition.nBufferAlignment = 0; - pSECInputPort->markType.hMarkTargetComponent = NULL; - pSECInputPort->markType.pMarkData = NULL; - - /* Output Port */ - pSECOutputPort = &pSECPort[OUTPUT_PORT_INDEX]; - - SEC_OSAL_QueueCreate(&pSECOutputPort->bufferQ); - - pSECOutputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); - if (pSECOutputPort->bufferHeader == NULL) { - SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); - pSECInputPort->unloadedResource = NULL; - SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); - pSECInputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(pSECOutputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); - - pSECOutputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); - if (pSECOutputPort->bufferStateAllocate == NULL) { - SEC_OSAL_Free(pSECOutputPort->bufferHeader); - pSECOutputPort->bufferHeader = NULL; - - SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); - pSECInputPort->unloadedResource = NULL; - SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); - pSECInputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(pSECOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); - - pSECOutputPort->bufferSemID = NULL; - pSECOutputPort->assignedBufferNum = 0; - pSECOutputPort->portState = OMX_StateMax; - pSECOutputPort->bIsPortFlushed = OMX_FALSE; - pSECOutputPort->bIsPortDisabled = OMX_FALSE; - pSECOutputPort->tunneledComponent = NULL; - pSECOutputPort->tunneledPort = 0; - pSECOutputPort->tunnelBufferNum = 0; - pSECOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; - pSECOutputPort->tunnelFlags = 0; - ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->loadedResource); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); - pSECOutputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECOutputPort->bufferHeader); - pSECOutputPort->bufferHeader = NULL; - - SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); - pSECInputPort->unloadedResource = NULL; - SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); - pSECInputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - goto EXIT; - } - ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->unloadedResource); - if (ret != OMX_ErrorNone) { - SEC_OSAL_SemaphoreTerminate(pSECOutputPort->loadedResource); - pSECOutputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); - pSECOutputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECOutputPort->bufferHeader); - pSECOutputPort->bufferHeader = NULL; - - SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); - pSECInputPort->unloadedResource = NULL; - SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); - pSECInputPort->loadedResource = NULL; - SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); - pSECInputPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECInputPort->bufferHeader); - pSECInputPort->bufferHeader = NULL; - SEC_OSAL_Free(pSECPort); - pSECPort = NULL; - goto EXIT; - } - - INIT_SET_SIZE_VERSION(&pSECOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); - pSECOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; - pSECOutputPort->portDefinition.eDir = OMX_DirOutput; - pSECOutputPort->portDefinition.nBufferCountActual = 0; - pSECOutputPort->portDefinition.nBufferCountMin = 0; - pSECOutputPort->portDefinition.nBufferSize = 0; - pSECOutputPort->portDefinition.bEnabled = OMX_FALSE; - pSECOutputPort->portDefinition.bPopulated = OMX_FALSE; - pSECOutputPort->portDefinition.eDomain = OMX_PortDomainMax; - pSECOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; - pSECOutputPort->portDefinition.nBufferAlignment = 0; - pSECOutputPort->markType.hMarkTargetComponent = NULL; - pSECOutputPort->markType.pMarkData = NULL; - - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - pSECComponent->checkTimeStamp.startTimeStamp = 0; - pSECComponent->checkTimeStamp.nStartFlags = 0x0; - - pOMXComponent->EmptyThisBuffer = &SEC_OMX_EmptyThisBuffer; - pOMXComponent->FillThisBuffer = &SEC_OMX_FillThisBuffer; - - ret = OMX_ErrorNone; -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - int i = 0; - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - for (i = 0; i < ALL_PORT_NUM; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - - SEC_OSAL_SemaphoreTerminate(pSECPort->loadedResource); - pSECPort->loadedResource = NULL; - SEC_OSAL_SemaphoreTerminate(pSECPort->unloadedResource); - pSECPort->unloadedResource = NULL; - SEC_OSAL_Free(pSECPort->bufferStateAllocate); - pSECPort->bufferStateAllocate = NULL; - SEC_OSAL_Free(pSECPort->bufferHeader); - pSECPort->bufferHeader = NULL; - - SEC_OSAL_QueueTerminate(&pSECPort->bufferQ); - } - SEC_OSAL_Free(pSECComponent->pSECPort); - pSECComponent->pSECPort = NULL; - ret = OMX_ErrorNone; -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.h b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.h deleted file mode 100644 index a69a443..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Baseport.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Baseport.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_BASE_PORT -#define SEC_OMX_BASE_PORT - - -#include "OMX_Component.h" -#include "SEC_OMX_Def.h" -#include "SEC_OSAL_Queue.h" - - -#define BUFFER_STATE_ALLOCATED (1 << 0) -#define BUFFER_STATE_ASSIGNED (1 << 1) -#define HEADER_STATE_ALLOCATED (1 << 2) -#define BUFFER_STATE_FREE 0 - -#define MAX_BUFFER_NUM 20 - -#define INPUT_PORT_INDEX 0 -#define OUTPUT_PORT_INDEX 1 -#define ALL_PORT_INDEX -1 -#define ALL_PORT_NUM 2 - -typedef struct _SEC_OMX_BASEPORT -{ - OMX_BUFFERHEADERTYPE **bufferHeader; - OMX_U32 *bufferStateAllocate; - OMX_PARAM_PORTDEFINITIONTYPE portDefinition; - OMX_HANDLETYPE bufferSemID; - SEC_QUEUE bufferQ; - OMX_U32 assignedBufferNum; - OMX_STATETYPE portState; - OMX_HANDLETYPE loadedResource; - OMX_HANDLETYPE unloadedResource; - - OMX_BOOL bIsPortFlushed; - OMX_BOOL bIsPortDisabled; - OMX_MARKTYPE markType; - - OMX_CONFIG_RECTTYPE cropRectangle; - - /* Tunnel Info */ - OMX_HANDLETYPE tunneledComponent; - OMX_U32 tunneledPort; - OMX_U32 tunnelBufferNum; - OMX_BUFFERSUPPLIERTYPE bufferSupplier; - OMX_U32 tunnelFlags; - - OMX_BOOL bIsANBEnabled; - OMX_BOOL bStoreMetaData; -} SEC_OMX_BASEPORT; - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.c b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.c deleted file mode 100644 index 6a2c979..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Resourcemanager.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Resourcemanager.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Mutex.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_RM" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -#define MAX_RESOURCE_VIDEO_DEC 3 /* for Android */ -#define MAX_RESOURCE_VIDEO_ENC 1 /* for Android */ - -/* Max allowable video scheduler component instance */ -static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL; -static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL; -static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL; -static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL; -static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; - - -OMX_ERRORTYPE addElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (*ppList != NULL) { - pTempComp = *ppList; - while (pTempComp->pNext != NULL) { - pTempComp = pTempComp->pNext; - } - pTempComp->pNext = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); - if (pTempComp->pNext == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL; - ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent; - ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pSECComponent->compPriority.nGroupPriority; - goto EXIT; - } else { - *ppList = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); - if (*ppList == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pTempComp = *ppList; - pTempComp->pNext = NULL; - pTempComp->pOMXStandComp = pOMXComponent; - pTempComp->groupPriority = pSECComponent->compPriority.nGroupPriority; - } - -EXIT: - return ret; -} - -OMX_ERRORTYPE removeElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; - SEC_OMX_RM_COMPONENT_LIST *pPrevComp = NULL; - OMX_BOOL bDetectComp = OMX_FALSE; - - if (*ppList == NULL) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - pCurrComp = *ppList; - while (pCurrComp != NULL) { - if (pCurrComp->pOMXStandComp == pOMXComponent) { - if (*ppList == pCurrComp) { - *ppList = pCurrComp->pNext; - SEC_OSAL_Free(pCurrComp); - } else { - if (pPrevComp != NULL) - pPrevComp->pNext = pCurrComp->pNext; - - SEC_OSAL_Free(pCurrComp); - } - bDetectComp = OMX_TRUE; - break; - } else { - pPrevComp = pCurrComp; - pCurrComp = pCurrComp->pNext; - } - } - - if (bDetectComp == OMX_FALSE) - ret = OMX_ErrorComponentNotFound; - else - ret = OMX_ErrorNone; - -EXIT: - return ret; -} - -int searchLowPriority(SEC_OMX_RM_COMPONENT_LIST *RMComp_list, OMX_U32 inComp_priority, SEC_OMX_RM_COMPONENT_LIST **outLowComp) -{ - int ret = 0; - SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; - SEC_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL; - - if (RMComp_list == NULL) - ret = -1; - - pTempComp = RMComp_list; - *outLowComp = 0; - - while (pTempComp != NULL) { - if (pTempComp->groupPriority > inComp_priority) { - if (pCandidateComp != NULL) { - if (pCandidateComp->groupPriority < pTempComp->groupPriority) - pCandidateComp = pTempComp; - } else { - pCandidateComp = pTempComp; - } - } - - pTempComp = pTempComp->pNext; - } - - *outLowComp = pCandidateComp; - if (pCandidateComp == NULL) - ret = 0; - else - ret = 1; - -EXIT: - return ret; -} - -OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateIdle) { - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, pSECComponent->callbackData, - OMX_EventError, OMX_ErrorResourcesLost, 0, NULL); - ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - } else if ((pSECComponent->currentState == OMX_StateExecuting) || (pSECComponent->currentState == OMX_StatePause)) { - /* Todo */ - } - - ret = OMX_ErrorNone; - -EXIT: - return ret; -} - - -OMX_ERRORTYPE SEC_OMX_ResourceManager_Init() -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - FunctionIn(); - ret = SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex); - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit() -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_RM_COMPONENT_LIST *pCurrComponent; - SEC_OMX_RM_COMPONENT_LIST *pNextComponent; - - FunctionIn(); - - SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); - - if (gpVideoDecRMComponentList) { - pCurrComponent = gpVideoDecRMComponentList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - SEC_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoDecRMComponentList = NULL; - } - if (gpVideoDecRMWaitingList) { - pCurrComponent = gpVideoDecRMWaitingList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - SEC_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoDecRMWaitingList = NULL; - } - - if (gpVideoEncRMComponentList) { - pCurrComponent = gpVideoEncRMComponentList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - SEC_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoEncRMComponentList = NULL; - } - if (gpVideoEncRMWaitingList) { - pCurrComponent = gpVideoEncRMWaitingList; - while (pCurrComponent != NULL) { - pNextComponent = pCurrComponent->pNext; - SEC_OSAL_Free(pCurrComponent); - pCurrComponent = pNextComponent; - } - gpVideoEncRMWaitingList = NULL; - } - - SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); - - SEC_OSAL_MutexTerminate(ghVideoRMComponentListMutex); - ghVideoRMComponentListMutex = NULL; - - ret = OMX_ErrorNone; -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; - SEC_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; - int numElem = 0; - int lowCompDetect = 0; - - FunctionIn(); - - SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) { - pComponentTemp = gpVideoDecRMComponentList; - if (pComponentTemp != NULL) { - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - } else { - numElem = 0; - } - if (numElem >= MAX_RESOURCE_VIDEO_DEC) { - lowCompDetect = searchLowPriority(gpVideoDecRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate); - if (lowCompDetect <= 0) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeComponent(pComponentCandidate->pOMXStandComp); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeElementList(&gpVideoDecRMComponentList, pComponentCandidate->pOMXStandComp); - ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - } else { - ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) { - pComponentTemp = gpVideoEncRMComponentList; - if (pComponentTemp != NULL) { - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - } else { - numElem = 0; - } - if (numElem >= MAX_RESOURCE_VIDEO_ENC) { - lowCompDetect = searchLowPriority(gpVideoEncRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate); - if (lowCompDetect <= 0) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeComponent(pComponentCandidate->pOMXStandComp); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } else { - ret = removeElementList(&gpVideoEncRMComponentList, pComponentCandidate->pOMXStandComp); - ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - } else { - ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - } - ret = OMX_ErrorNone; - -EXIT: - - SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; - OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; - int numElem = 0; - - FunctionIn(); - - SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) { - pComponentTemp = gpVideoDecRMWaitingList; - if (gpVideoDecRMComponentList == NULL) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - ret = removeElementList(&gpVideoDecRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - if (numElem > 0) { - pOMXWaitComponent = gpVideoDecRMWaitingList->pOMXStandComp; - removeElementList(&gpVideoDecRMWaitingList, pOMXWaitComponent); - ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - } - } else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) { - pComponentTemp = gpVideoEncRMWaitingList; - if (gpVideoEncRMComponentList == NULL) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - ret = removeElementList(&gpVideoEncRMComponentList, pOMXComponent); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - while (pComponentTemp) { - numElem++; - pComponentTemp = pComponentTemp->pNext; - } - if (numElem > 0) { - pOMXWaitComponent = gpVideoEncRMWaitingList->pOMXStandComp; - removeElementList(&gpVideoEncRMWaitingList, pOMXWaitComponent); - ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - } - } - -EXIT: - - SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) - ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent); - else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) - ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent); - - SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC) - ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent); - else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC) - ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent); - - SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); - - FunctionOut(); - - return ret; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.h b/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.h deleted file mode 100644 index e78b378..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/common/SEC_OMX_Resourcemanager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Resourcemanager.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_RESOURCEMANAGER -#define SEC_OMX_RESOURCEMANAGER - - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" - - -struct SEC_OMX_RM_COMPONENT_LIST; -typedef struct _SEC_OMX_RM_COMPONENT_LIST -{ - OMX_COMPONENTTYPE *pOMXStandComp; - OMX_U32 groupPriority; - struct _SEC_OMX_RM_COMPONENT_LIST *pNext; -} SEC_OMX_RM_COMPONENT_LIST; - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OMX_ResourceManager_Init(); -OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit(); -OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent); -OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent); -OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); -OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/dec/Android.mk deleted file mode 100644 index 349be6f..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - SEC_OMX_Vdec.c - -LOCAL_MODULE := libSEC_OMX_Vdec -LOCAL_ARM_MODE := arm -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec - -ifeq ($(BOARD_USE_ANB), true) -LOCAL_STATIC_LIBRARIES := libsecosal -LOCAL_CFLAGS += -DUSE_ANB -endif - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.c deleted file mode 100644 index 042dd25..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.c +++ /dev/null @@ -1,1544 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Vdec.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include "SEC_OMX_Macros.h" -#include "SEC_OSAL_Event.h" -#include "SEC_OMX_Vdec.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_ETC.h" - -#ifdef USE_ANB -#include "SEC_OSAL_Android.h" -#endif - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_VIDEO_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) -{ - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - if ((secOutputPort->portDefinition.format.video.nFrameWidth != - secInputPort->portDefinition.format.video.nFrameWidth) || - (secOutputPort->portDefinition.format.video.nFrameHeight != - secInputPort->portDefinition.format.video.nFrameHeight)) { - OMX_U32 width = 0, height = 0; - - secOutputPort->portDefinition.format.video.nFrameWidth = - secInputPort->portDefinition.format.video.nFrameWidth; - secOutputPort->portDefinition.format.video.nFrameHeight = - secInputPort->portDefinition.format.video.nFrameHeight; - width = secOutputPort->portDefinition.format.video.nStride = - secInputPort->portDefinition.format.video.nStride; - height = secOutputPort->portDefinition.format.video.nSliceHeight = - secInputPort->portDefinition.format.video.nSliceHeight; - - switch(secOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - if (width && height) - secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - width = secOutputPort->portDefinition.format.video.nFrameWidth; - height = secOutputPort->portDefinition.format.video.nFrameHeight; - if (width && height) { - secOutputPort->portDefinition.nBufferSize = - ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height/2)); - } - break; - default: - if (width && height) - secOutputPort->portDefinition.nBufferSize = width * height * 2; - break; - } - } - - return ; -} - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - if (pSECPort->portState != OMX_StateIdle) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = pBuffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBufferHdr = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } -/* - if (pSECPort->portState != OMX_StateIdle ) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } -*/ - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { - ret = pSECComponent->sec_allocSecureInputBuffer(hComponent, sizeof(OMX_U8) * nSizeBytes, &temp_buffer); - if (ret != OMX_ErrorNone) - goto EXIT; - } else { - temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); - if (temp_buffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) - pSECComponent->sec_freeSecureInputBuffer(hComponent, temp_buffer); - else - SEC_OSAL_Free(temp_buffer); - - temp_buffer = NULL; - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = temp_buffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBuffer = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) - pSECComponent->sec_freeSecureInputBuffer(hComponent, temp_buffer); - else - SEC_OSAL_Free(temp_buffer); - - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { - (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, - pSECComponent->callbackData, - (OMX_U32)OMX_EventError, - (OMX_U32)OMX_ErrorPortUnpopulated, - nPortIndex, NULL); - } - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { - if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { - if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { - if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) - pSECComponent->sec_freeSecureInputBuffer(hComponent, pSECPort->bufferHeader[i]->pBuffer); - else - SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); - pSECPort->bufferHeader[i]->pBuffer = NULL; - pBufferHdr->pBuffer = NULL; - } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { - ; /* None*/ - } - pSECPort->assignedBufferNum--; - if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { - SEC_OSAL_Free(pSECPort->bufferHeader[i]); - pSECPort->bufferHeader[i] = NULL; - pBufferHdr = NULL; - } - pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; - ret = OMX_ErrorNone; - goto EXIT; - } - } - } - -EXIT: - if (ret == OMX_ErrorNone) { - if (pSECPort->assignedBufferNum == 0) { - SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - pSECPort->portDefinition.bPopulated = OMX_FALSE; - } - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - OMX_PARAM_PORTDEFINITIONTYPE portDefinition; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT* pSECPort = NULL; - OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - if ((pSECComponent->currentState == OMX_StateExecuting) && - (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) { - return OMX_TRUE; - } else { - return OMX_FALSE; - } -} - -static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { - bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; - bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; - secOMXInputPort->markType.hMarkTargetComponent = NULL; - secOMXInputPort->markType.pMarkData = NULL; - } - - if (bufferHeader->hMarkTargetComponent != NULL) { - if (bufferHeader->hMarkTargetComponent == pOMXComponent) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventMark, - 0, 0, bufferHeader->pMarkData); - } else { - pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; - pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; - } - } - - if (CHECK_PORT_TUNNELED(secOMXInputPort)) { - OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); - } else { - bufferHeader->nFilledLen = 0; - pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE* message = NULL; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; - dataBuffer->dataValid = OMX_TRUE; - dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; - dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; - - SEC_OSAL_Free(message); - - if (dataBuffer->allocSize <= dataBuffer->dataLen) - SEC_OSAL_Log(SEC_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); - } - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - bufferHeader->nFilledLen = dataBuffer->remainDataLen; - bufferHeader->nOffset = 0; - bufferHeader->nFlags = dataBuffer->nFlags; - bufferHeader->nTimeStamp = dataBuffer->timeStamp; - - if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { - bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; - bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; - pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; - pSECComponent->propagateMarkType.pMarkData = NULL; - } - - if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventBufferFlag, - OUTPUT_PORT_INDEX, - bufferHeader->nFlags, NULL); - } - - if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { - OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); - } else { - pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - /* reset dataBuffer */ - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE *message = NULL; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; - dataBuffer->dataValid =OMX_TRUE; - /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ - /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ - pSECComponent->processData[OUTPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; - pSECComponent->processData[OUTPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; - - SEC_OSAL_Free(message); - } - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; - -} - -static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - - return ret; -} - -static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; - - processData->dataLen = 0; - processData->remainDataLen = 0; - processData->usedDataLen = 0; - processData->nFlags = 0; - processData->timeStamp = 0; - - return ret; -} - -OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - OMX_BYTE checkInputStream = NULL; - OMX_U32 checkInputStreamLen = 0; - OMX_U32 checkedSize = 0; - OMX_BOOL flagEOF = OMX_FALSE; - OMX_BOOL previousFrameEOF = OMX_FALSE; - - FunctionIn(); - - if (inputUseBuffer->dataValid == OMX_TRUE) { - checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; - checkInputStreamLen = inputUseBuffer->remainDataLen; - - if (inputData->dataLen == 0) { - previousFrameEOF = OMX_TRUE; - } else { - previousFrameEOF = OMX_FALSE; - } - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - flagEOF = OMX_TRUE; - checkedSize = checkInputStreamLen; - } else if ((pSECComponent->bUseFlagEOF == OMX_TRUE) && - !(inputUseBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { - flagEOF = OMX_TRUE; - checkedSize = checkInputStreamLen; - } else { - pSECComponent->bUseFlagEOF = OMX_FALSE; - checkedSize = pSECComponent->sec_checkInputFrame(checkInputStream, checkInputStreamLen, inputUseBuffer->nFlags, previousFrameEOF, &flagEOF); - } - - if (flagEOF == OMX_TRUE) { - copySize = checkedSize; - SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); - } else { - copySize = checkInputStreamLen; - SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); - } - - if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) - pSECComponent->bSaveFlagEOS = OMX_TRUE; - - if ((((inputData->allocSize) - (inputData->dataLen)) >= copySize) || (pVideoDec->bDRMPlayerMode == OMX_TRUE)) { - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - inputData->dataBuffer = checkInputStream; - } else { - if (copySize > 0) - SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); - } - - inputUseBuffer->dataLen -= copySize; - inputUseBuffer->remainDataLen -= copySize; - inputUseBuffer->usedDataLen += copySize; - - inputData->dataLen += copySize; - inputData->remainDataLen += copySize; - - if (previousFrameEOF == OMX_TRUE) { - inputData->timeStamp = inputUseBuffer->timeStamp; - inputData->nFlags = inputUseBuffer->nFlags; - } - - if (pSECComponent->bUseFlagEOF == OMX_TRUE) { - if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } else { - inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - } else { - if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && - ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || - (inputData->dataLen == 0))) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && - (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) && - (inputData->dataLen != 0)) { - inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_TRUE; - } - } else { - inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - } - - if(((inputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && - (inputData->dataLen <= 0) && (flagEOF == OMX_TRUE)) { - inputData->dataLen = inputData->previousDataLen; - inputData->remainDataLen = inputData->previousDataLen; - } - } else { - /*????????????????????????????????? Error ?????????????????????????????????*/ - SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); - flagEOF = OMX_FALSE; - } - - if (inputUseBuffer->remainDataLen == 0) { - if (pVideoDec->bDRMPlayerMode != OMX_TRUE) - SEC_InputBufferReturn(pOMXComponent); - } else { - inputUseBuffer->dataValid = OMX_TRUE; - } - } - - if (flagEOF == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; - pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - SEC_OSAL_Log(SEC_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", - inputData->timeStamp, inputData->timeStamp / 1E6); - } - - ret = OMX_TRUE; - } else { - ret = OMX_FALSE; - } - - FunctionOut(); - - return ret; -} - -OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - FunctionIn(); - - if (outputUseBuffer->dataValid == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { - if ((pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) && - (pSECComponent->checkTimeStamp.nStartFlags == outputData->nFlags)){ - pSECComponent->checkTimeStamp.startTimeStamp = -19761123; - pSECComponent->checkTimeStamp.nStartFlags = 0x0; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - } else { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - ret = OMX_TRUE; - goto EXIT; - } - } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - ret = OMX_TRUE; - goto EXIT; - } - - if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { - copySize = outputData->remainDataLen; - - outputUseBuffer->dataLen += copySize; - outputUseBuffer->remainDataLen += copySize; - outputUseBuffer->nFlags = outputData->nFlags; - outputUseBuffer->timeStamp = outputData->timeStamp; - - ret = OMX_TRUE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - - if ((outputUseBuffer->remainDataLen > 0) || - (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) - SEC_OutputBufferReturn(pOMXComponent); - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); - - ret = OMX_FALSE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - } - } else { - ret = OMX_FALSE; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - pSECComponent->remainOutputData = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - - FunctionIn(); - - while (!pSECComponent->bExitBufferProcessThread) { - SEC_OSAL_SleepMillisec(0); - - if (((pSECComponent->currentState == OMX_StatePause) || - (pSECComponent->currentState == OMX_StateIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& - ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - while ((SEC_Check_BufferProcess_State(pSECComponent)) && (!pSECComponent->bExitBufferProcessThread)) { - SEC_OSAL_SleepMillisec(0); - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if ((outputUseBuffer->dataValid != OMX_TRUE) && - (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = SEC_OutputBufferGetQueue(pSECComponent); - if ((ret == OMX_ErrorUndefined) || - (secInputPort->portState != OMX_StateIdle) || - (secOutputPort->portState != OMX_StateIdle)) { - break; - } - } else { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - - if (pSECComponent->remainOutputData == OMX_FALSE) { - if (pSECComponent->reInputData == OMX_FALSE) { - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && - (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = SEC_InputBufferGetQueue(pSECComponent); - break; - } - - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - } - - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); - - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - if ((inputUseBuffer->remainDataLen == 0) && - (ret != OMX_ErrorInputDataDecodeYet)) - SEC_InputBufferReturn(pOMXComponent); - else - inputUseBuffer->dataValid = OMX_TRUE; - } - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - - if (ret == OMX_ErrorInputDataDecodeYet) - pSECComponent->reInputData = OMX_TRUE; - else - pSECComponent->reInputData = OMX_FALSE; - } - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - - if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) - pSECComponent->remainOutputData = OMX_TRUE; - else - pSECComponent->remainOutputData = OMX_FALSE; - - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - } - -EXIT: - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - portParam->nPorts = pSECComponent->portParam.nPorts; - portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - - if (portIndex == INPUT_PORT_INDEX) { - supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; - portFormat->eColorFormat = portDefinition->format.video.eColorFormat; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - } else if (portIndex == OUTPUT_PORT_INDEX) { - supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - switch (index) { - case supportFormat_0: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_1: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_2: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_3: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - } - } - ret = OMX_ErrorNone; - } - break; -#ifdef USE_ANB - case OMX_IndexParamGetAndroidNativeBuffer: - { - ret = SEC_OSAL_GetANBParameter(hComponent, nParamIndex, ComponentParameterStructure); - } - break; -#endif - default: - { - ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} -OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - portDefinition->format.video.eColorFormat = portFormat->eColorFormat; - portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; - portDefinition->format.video.xFramerate = portFormat->xFramerate; - } - } - break; -#ifdef USE_ANB - case OMX_IndexParamEnableAndroidBuffers: - case OMX_IndexParamUseAndroidNativeBuffer: - { - ret = SEC_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure); - } - break; -#endif - default: - { - ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexVendorThumbnailMode: - { - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoDec->bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure); - - ret = OMX_ErrorNone; - } - break; - default: - ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - -#ifdef USE_ANB - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_ANB) == 0) - *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableAndroidBuffers; - else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_GET_ANB) == 0) - *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer; - else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_USE_ANB) == 0) - *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer; - else - ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); -#else - ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_Port_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pVideoDec = SEC_OSAL_Malloc(sizeof(SEC_OMX_VIDEODEC_COMPONENT)); - if (pVideoDec == NULL) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - - SEC_OSAL_Memset(pVideoDec, 0, sizeof(SEC_OMX_VIDEODEC_COMPONENT)); - pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec; - - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = 0; - pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; - - pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - pSECPort->portDefinition.format.video.nFrameWidth = 0; - pSECPort->portDefinition.format.video.nFrameHeight= 0; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate = (15 << 16); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.format.video.pNativeWindow = NULL; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; - - pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - pSECPort->portDefinition.format.video.nFrameWidth = 0; - pSECPort->portDefinition.format.video.nFrameHeight= 0; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate = (15 << 16); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.format.video.pNativeWindow = NULL; - - pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; - pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; - pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; - pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; - - pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; - pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; - pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; - pSECComponent->sec_BufferReset = &SEC_BufferReset; - pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; - pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - int i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OSAL_Free(pVideoDec); - pSECComponent->hComponentHandle = pVideoDec = NULL; - - for(i = 0; i < ALL_PORT_NUM; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); - pSECPort->portDefinition.format.video.cMIMEType = NULL; - } - - ret = SEC_OMX_Port_Destructor(pOMXComponent); - - ret = SEC_OMX_BaseComponent_Destructor(hComponent); - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.h deleted file mode 100644 index d3bbdf4..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/SEC_OMX_Vdec.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Vdec.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_VIDEO_DECODE -#define SEC_OMX_VIDEO_DECODE - -#include "OMX_Component.h" -#include "SEC_OMX_Def.h" -#include "SEC_OSAL_Queue.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" - -#define MAX_VIDEO_INPUTBUFFER_NUM 5 -#define MAX_VIDEO_OUTPUTBUFFER_NUM 2 - -#define DEFAULT_FRAME_WIDTH 176 -#define DEFAULT_FRAME_HEIGHT 144 - -#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2 -#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 - -#define MFC_INPUT_BUFFER_NUM_MAX 2 -#define DEFAULT_MFC_INPUT_BUFFER_SIZE 1024 * 1024 * MFC_INPUT_BUFFER_NUM_MAX /*DEFAULT_VIDEO_INPUT_BUFFER_SIZE*/ - -#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 -#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 4 - -typedef struct -{ - void *pAddrY; - void *pAddrC; -} MFC_DEC_ADDR_INFO; - -typedef struct _SEC_MFC_NBDEC_THREAD -{ - OMX_HANDLETYPE hNBDecodeThread; - OMX_HANDLETYPE hDecFrameStart; - OMX_HANDLETYPE hDecFrameEnd; - OMX_BOOL bExitDecodeThread; - OMX_BOOL bDecoderRun; - - OMX_U32 oneFrameSize; -} SEC_MFC_NBDEC_THREAD; - -typedef struct _MFC_DEC_INPUT_BUFFER -{ - void *PhyAddr; // physical address - void *VirAddr; // virtual address - int bufferSize; // input buffer alloc size - int dataSize; // Data length -} MFC_DEC_INPUT_BUFFER; - -typedef struct _SEC_OMX_VIDEODEC_COMPONENT -{ - OMX_HANDLETYPE hCodecHandle; - SEC_MFC_NBDEC_THREAD NBDecThread; - - OMX_BOOL bThumbnailMode; - OMX_BOOL bFirstFrame; - MFC_DEC_INPUT_BUFFER MFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; - OMX_U32 indexInputBuffer; - - /* CSC handle */ - OMX_PTR csc_handle; - OMX_U32 csc_set_format; - - /* For DRM Play */ - OMX_BOOL bDRMPlayerMode; -} SEC_OMX_VIDEODEC_COMPONENT; - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer); -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes); -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_VideoDecodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_VideoDecodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType); -OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); -inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/Android.mk deleted file mode 100644 index da5880e..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/Android.mk +++ /dev/null @@ -1,84 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_H264dec.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.AVC.Decoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_DRM), true) -LOCAL_CFLAGS += -DUSE_DRM -endif - -ifeq ($(BOARD_USE_ANB), true) -LOCAL_CFLAGS += -DUSE_ANB -ifeq ($(BOARD_USE_CSC_FIMC), true) -ifeq ($(BOARD_USE_V4L2_ION), false) -LOCAL_CFLAGS += -DUSE_CSC_FIMC -endif -endif - -ifeq ($(BOARD_USE_CSC_GSCALER), true) -LOCAL_CFLAGS += -DUSE_CSC_GSCALER -endif -endif - - -ifeq ($(TARGET_BOARD_PLATFORM), exynos4) -ifeq ($(BOARD_USE_V4L2_ION),false) -ifeq ($(BOARD_USE_S3D_SUPPORT), true) -LOCAL_CFLAGS += -DS3D_SUPPORT -endif -endif -endif - -ifeq ($(TARGET_BOARD_PLATFORM), exynos5) -ifeq ($(BOARD_USE_S3D_SUPPORT), true) -LOCAL_CFLAGS += -DS3D_SUPPORT -endif -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libfimc libhwconverter -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libexynosgscaler -endif - -#ifeq ($(BOARD_USE_V4L2_ION),true) -#LOCAL_SHARED_LIBRARIES += libion -#endif - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS += -DCONFIG_MFC_FPS -endif - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) \ - $(BOARD_HAL_PATH)/include - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.c deleted file mode 100644 index 2ad34d8..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.c +++ /dev/null @@ -1,2611 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_H264dec.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Vdec.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "library_register.h" -#include "SEC_OMX_H264dec.h" -#include "SsbSipMfcApi.h" - -#ifdef USE_ANB -#include "SEC_OSAL_Android.h" -#endif - -/* To use CSC_METHOD_PREFER_HW or CSC_METHOD_HW in SEC OMX, gralloc should allocate physical memory using FIMC */ -/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_H264_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -#define H264_DEC_NUM_OF_EXTRA_BUFFERS 7 - -#ifdef S3D_SUPPORT -#define ADD_SPS_PPS_I_FRAME -#else -//#define ADD_SPS_PPS_I_FRAME -#endif -//#define FULL_FRAME_SEARCH - -/* H.264 Decoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, - - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, - - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; - - -static int Check_H264_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) -{ - OMX_U32 preFourByte = (OMX_U32)-1; - int accessUnitSize = 0; - int frameTypeBoundary = 0; - int nextNaluSize = 0; - int naluStart = 0; - - if (bPreviousFrameEOF == OMX_TRUE) - naluStart = 0; - else - naluStart = 1; - - while (1) { - int inputOneByte = 0; - - if (accessUnitSize == (int)buffSize) - goto EXIT; - - inputOneByte = *(pInputStream++); - accessUnitSize += 1; - - if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) { - int naluType = inputOneByte & 0x1F; - - SEC_OSAL_Log(SEC_LOG_TRACE, "NaluType : %d", naluType); - if (naluStart == 0) { -#ifdef ADD_SPS_PPS_I_FRAME - if (naluType == 1 || naluType == 5) -#else - if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8) -#endif - naluStart = 1; - } else { -#ifdef OLD_DETECT - frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9) -#else - if (naluType == 9) - frameTypeBoundary = -2; -#endif - if (naluType == 1 || naluType == 5) { - if (accessUnitSize == (int)buffSize) { - accessUnitSize--; - goto EXIT; - } - inputOneByte = *pInputStream++; - accessUnitSize += 1; - - if (inputOneByte >= 0x80) - frameTypeBoundary = -1; - } - if (frameTypeBoundary < 0) { - break; - } - } - - } - preFourByte = (preFourByte << 8) + inputOneByte; - } - - *pbEndOfFrame = OMX_TRUE; - nextNaluSize = -5; - if (frameTypeBoundary == -1) - nextNaluSize = -6; - if (preFourByte != 0x00000001) - nextNaluSize++; - return (accessUnitSize + nextNaluSize); - -EXIT: - *pbEndOfFrame = OMX_FALSE; - - return accessUnitSize; -} - -OMX_BOOL Check_H264_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize) -{ - if (streamSize < 4) { - return OMX_FALSE; - } else if ((pInputStream[0] == 0x00) && - (pInputStream[1] == 0x00) && - (pInputStream[2] == 0x00) && - (pInputStream[3] != 0x00) && - ((pInputStream[3] >> 3) == 0x00)) { - return OMX_TRUE; - } else if ((pInputStream[0] == 0x00) && - (pInputStream[1] == 0x00) && - (pInputStream[2] != 0x00) && - ((pInputStream[2] >> 3) == 0x00)) { - return OMX_TRUE; - } else { - return OMX_FALSE; - } -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_Alloc_SecureInputBuffer(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nBufferSize, - OMX_INOUT OMX_PTR *pInputBuffer_physicalAddress) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_PTR pStreamBuffer = NULL; - OMX_PTR pStreamPhyBuffer = NULL; - -#ifdef USE_DRM - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pH264Dec == NULL) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - pStreamBuffer = SsbSipMfcDecAllocInputBuffer(pH264Dec->hMFCH264Handle.hMFCHandle, &pStreamPhyBuffer, nBufferSize); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pStreamPhyBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = nBufferSize; - - *pInputBuffer_physicalAddress = pStreamPhyBuffer; -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_Free_SecureInputBuffer(OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_PTR pInputBuffer_physicalAddress) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_PTR pStreamPhyBuffer = NULL; - -#ifdef USE_DRM - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pH264Dec == NULL) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - pStreamPhyBuffer = pInputBuffer_physicalAddress; - SsbSipMfcDecFreeInputBuffer(pH264Dec->hMFCH264Handle.hMFCHandle, pStreamPhyBuffer); -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex]; - - SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); - } - break; - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; - SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; - OMX_U32 maxProfileLevelNum = 0; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pProfileLevel = supportedAVCProfileLevels; - maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - - if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pProfileLevel += pDstProfileLevel->nProfileIndex; - pDstProfileLevel->eProfile = pProfileLevel->profile; - pDstProfileLevel->eLevel = pProfileLevel->level; - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex]; - - pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; - pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex]; - - SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; - OMX_U32 portIndex = pPortDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - OMX_U32 width, height, size; - OMX_U32 realWidth, realHeight; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); - - realWidth = pSECPort->portDefinition.format.video.nFrameWidth; - realHeight = pSECPort->portDefinition.format.video.nFrameHeight; - width = ((realWidth + 15) & (~15)); - height = ((realHeight + 15) & (~15)); - size = (width * height * 3) / 2; - pSECPort->portDefinition.format.video.nStride = width; - pSECPort->portDefinition.format.video.nSliceHeight = height; - pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; - - if (portIndex == INPUT_PORT_INDEX) { - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; - pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; - pSECOutputPort->portDefinition.format.video.nStride = width; - pSECOutputPort->portDefinition.format.video.nSliceHeight = height; - - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.nBufferSize = - ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); - break; - default: - SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); - ret = OMX_ErrorUnsupportedSetting; - break; - } - } - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) - goto EXIT; - - if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex]; - pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; - pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_GetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexConfigCommonOutputCrop: - { - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_CONFIG_RECTTYPE *pSrcRectType = NULL; - OMX_CONFIG_RECTTYPE *pDstRectType = NULL; - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - ret = OMX_ErrorNotReady; - break; - } - - pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure; - - if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) && - (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[pDstRectType->nPortIndex]; - - pSrcRectType = &(pSECPort->cropRectangle); - - pDstRectType->nTop = pSrcRectType->nTop; - pDstRectType->nLeft = pSrcRectType->nLeft; - pDstRectType->nHeight = pSrcRectType->nHeight; - pDstRectType->nWidth = pSrcRectType->nWidth; - } - break; - default: - ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_SetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - *pIndexType = OMX_IndexVendorThumbnailMode; - - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); - ret = OMX_ErrorNone; - } else { - ret = OMX_ErrorNoMore; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pVideoDec->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); - - if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_DEC); -#endif - pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_DEC); -#endif - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); - } - } - -EXIT: - SEC_OSAL_ThreadExit(NULL); - FunctionOut(); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_PTR pStreamBuffer = NULL; - OMX_PTR pStreamPhyBuffer = NULL; - OMX_PTR hMFCHandle; - -#ifdef S3D_SUPPORT - OMX_S32 setConfVal = 0; -#endif - CSC_METHOD csc_method = CSC_METHOD_SW; - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfInit(PERF_ID_DEC); - SEC_OSAL_PerfInit(PERF_ID_CSC); -#endif - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ - if (pVideoDec->bDRMPlayerMode == OMX_FALSE) { - hMFCHandle = NULL; - - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); - } else { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pH264Dec->hMFCH264Handle.hMFCHandle = hMFCHandle; - } else { - hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; - pSECComponent->bUseFlagEOF = OMX_TRUE; - } - -#ifdef S3D_SUPPORT - /*Enable SEI parsing for checking frame_packing S3D*/ - setConfVal = 1; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_SEI_PARSE, &setConfVal); -#endif - - /* Allocate decoder's input buffer */ - /* Get first input buffer */ - if (pVideoDec->bDRMPlayerMode == OMX_FALSE) { - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[0].dataSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - /* Get second input buffer */ - pStreamBuffer = NULL; - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[1].dataSize = 0; - pVideoDec->indexInputBuffer = 0; - - pVideoDec->bFirstFrame = OMX_TRUE; - - pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - pVideoDec->NBDecThread.oneFrameSize = 0; - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, - SEC_MFC_DecodeThread, - pOMXComponent)) { - pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; - } -#endif - - pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; - } - - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pH264Dec->hMFCH264Handle.indexTimestamp = 0; - pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0; - - pSECComponent->getAllDelayBuffer = OMX_FALSE; - -#ifdef USE_ANB -#if defined(USE_CSC_FIMC) || defined(USE_CSC_GSCALER) - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) - csc_method = CSC_METHOD_PREFER_HW; -#endif - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - csc_method = CSC_METHOD_HW; - } -#endif - pVideoDec->csc_handle = csc_init(&csc_method); - pVideoDec->csc_set_format = OMX_FALSE; - - SEC_OSAL_Log(SEC_LOG_ERROR, "%s::csc_method=%d", __func__, csc_method); - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_PTR hMFCHandle = NULL; - - FunctionIn(); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfPrint("[DEC]", PERF_ID_DEC); - SEC_OSAL_PerfPrint("[CSC]", PERF_ID_CSC); -#endif - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; - - pH264Dec->hMFCH264Handle.pMFCStreamBuffer = NULL; - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; - - if (pVideoDec->bDRMPlayerMode == OMX_FALSE) { -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { - pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); - pVideoDec->NBDecThread.hNBDecodeThread = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.hDecFrameEnd = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.hDecFrameStart = NULL; - } -#endif - } - - if (pVideoDec->bDRMPlayerMode == OMX_FALSE) { - if (hMFCHandle != NULL) { - SsbSipMfcDecClose(hMFCHandle); - hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle = NULL; - } - } - - if (pVideoDec->csc_handle != NULL) { - csc_deinit(pVideoDec->csc_handle); - pVideoDec->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 setConfVal = 0; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize = 0; - OMX_U32 FrameBufferUVSize = 0; - OMX_BOOL outputDataValid = OMX_FALSE; -#ifdef S3D_SUPPORT - SSBSIP_MFC_FRAME_PACKING frame_packing; -#endif - - FunctionIn(); - - if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Default number in the driver is optimized */ - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - setConfVal = 0; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } else { - setConfVal = H264_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); - - setConfVal = 8; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } - - SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer, - pH264Dec->hMFCH264Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); - if (pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - SSBSIP_MFC_CROP_INFORMATION cropInfo; - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); - SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", - pSECInputPort->portDefinition.format.video.nFrameWidth, - pSECInputPort->portDefinition.format.video.nFrameHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", - imgResol.width, imgResol.height); - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", - cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , - cropInfo.crop_left_offset , cropInfo.crop_right_offset); - - pSECOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; - pSECOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; - pSECOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; - pSECOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; - - pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; - - /** Update Frame Size **/ - if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || - (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send crop info call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - OMX_IndexConfigCommonOutputCrop, - NULL); - } - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); - - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send Port Settings changed call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - -#ifdef ADD_SPS_PPS_I_FRAME - ret = OMX_ErrorInputDataDecodeYet; -#else - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; -#endif - goto EXIT; - } else { - ret = OMX_ErrorMFCInit; - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - - if ((pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) && - (pVideoDec->bFirstFrame == OMX_FALSE)) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - /* wait for mfc decode done */ - if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - -#ifdef S3D_SUPPORT - /* Check Whether frame packing information is available */ - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_PACKING, &frame_packing); - - if (pVideoDec->bThumbnailMode == OMX_FALSE && - frame_packing.available && - pH264Dec->hMFCH264Handle.bS3DMode == OMX_FALSE) { - - SEC_OSAL_Log(SEC_LOG_TRACE, "arrangement ID: 0x%08x", frame_packing.arrangement_id); - SEC_OSAL_Log(SEC_LOG_TRACE, "arrangement_type: %d", frame_packing.arrangement_type); - SEC_OSAL_Log(SEC_LOG_TRACE, "content_interpretation_type: %d", frame_packing.content_interpretation_type); - SEC_OSAL_Log(SEC_LOG_TRACE, "current_frame_is_frame0_flag: %d", frame_packing.current_frame_is_frame0_flag); - SEC_OSAL_Log(SEC_LOG_TRACE, "spatial_flipping_flag: %d", frame_packing.spatial_flipping_flag); - SEC_OSAL_Log(SEC_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", frame_packing.frame0_grid_pos_x, - frame_packing.frame0_grid_pos_y, frame_packing.frame1_grid_pos_x, frame_packing.frame1_grid_pos_y); - - /* Change Outport eColorFormat based on Framepacking information*/ - if (frame_packing.arrangement_type == 3) { - if (frame_packing.content_interpretation_type == 1) { - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR; - break; - case OMX_COLOR_FormatYUV420Planar: - default: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR; - break; - } - } else if (frame_packing.content_interpretation_type == 2) { - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL; - break; - case OMX_COLOR_FormatYUV420Planar: - default: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL; - break; - } - } - } else if (frame_packing.arrangement_type == 4) { - if (frame_packing.content_interpretation_type == 1) { - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_TB_LR; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR; - break; - case OMX_COLOR_FormatYUV420Planar: - default: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_TB_LR; - break; - } - } else if (frame_packing.content_interpretation_type == 2) { - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled_TB_RL; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL; - break; - case OMX_COLOR_FormatYUV420Planar: - default: - pSECOutputPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatYUV420Planar_TB_RL; - break; - } - } - } - - /** Send Port Settings changed call back - output color format change */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - - if ((pSECOutputPort->cropRectangle.nTop != 0) || (pSECOutputPort->cropRectangle.nLeft != 0)) { - /** Send crop info call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - OMX_IndexConfigCommonOutputCrop, - NULL); - } - pH264Dec->hMFCH264Handle.bS3DMode = OMX_TRUE; - SEC_OSAL_SleepMillisec(0); - ret = OMX_ErrorInputDataDecodeYet; - goto EXIT; - } -#endif - - if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if ((outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) || - (pH264Dec->hMFCH264Handle.bFlashPlayerMode == OMX_TRUE)) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - outputDataValid = OMX_TRUE; - pH264Dec->hMFCH264Handle.outputIndexTimestamp++; - pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - outputDataValid = OMX_FALSE; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - outputDataValid = OMX_FALSE; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && - ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { - pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - - outputDataValid = OMX_FALSE; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - } - - if (ret == OMX_ErrorInputDataDecodeYet) { - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; - //pInputData->dataLen = oneFrameSize; - //pInputData->remainDataLen = oneFrameSize; - } - - if ((Check_H264_StartCode(pInputData->dataBuffer, oneFrameSize) == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { - if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); - pH264Dec->hMFCH264Handle.indexTimestamp++; - pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer, - pH264Dec->hMFCH264Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; - - /* mfc decode start */ - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; - pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; - - SEC_OSAL_SleepMillisec(0); - - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE) && - (outputDataValid == OMX_FALSE)) { - ret = OMX_ErrorInputDataDecodeYet; - } - - pVideoDec->bFirstFrame = OMX_FALSE; - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - } - - /** Fill Output Buffer **/ - if (outputDataValid == OMX_TRUE) { - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int actualWidth = outputInfo.img_width; - int actualHeight = outputInfo.img_height; - int actualImageSize = actualWidth * actualHeight; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + actualImageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + actualImageSize + actualImageSize / 4; - pOutputData->dataLen = (actualImageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, actualWidth, actualHeight, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - actualWidth = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (actualWidth * actualHeight * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420p out for ThumbnailMode/Flash player mode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: -#ifdef S3D_SUPPORT - case OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR: - case OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL: - case OMX_SEC_COLOR_FormatNV12Tiled_TB_LR: - case OMX_SEC_COLOR_FormatNV12Tiled_TB_RL: -#endif - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: -#ifdef S3D_SUPPORT - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL: -#endif - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: -#ifdef S3D_SUPPORT - case OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR: - case OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL: - case OMX_SEC_COLOR_FormatYUV420Planar_TB_LR: - case OMX_SEC_COLOR_FormatYUV420Planar_TB_RL: -#endif - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, /* handle */ - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - } else { - pOutputData->dataLen = 0; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 setConfVal = 0; - OMX_S32 returnCodec = 0; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize; - OMX_U32 FrameBufferUVSize; - - FunctionIn(); - - if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Default number in the driver is optimized */ - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - setConfVal = 0; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } else { - setConfVal = H264_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); - - setConfVal = 8; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } - - returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - SSBSIP_MFC_CROP_INFORMATION cropInfo; - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); - SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", - pSECInputPort->portDefinition.format.video.nFrameWidth, - pSECInputPort->portDefinition.format.video.nFrameHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", - imgResol.width, imgResol.height); - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", - cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , - cropInfo.crop_left_offset , cropInfo.crop_right_offset); - - pSECOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; - pSECOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; - pSECOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; - pSECOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; - - pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; - - /** Update Frame Size **/ - if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || - (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send crop info call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - OMX_IndexConfigCommonOutputCrop, - NULL); - } - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send Port Settings changed call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - -#ifdef ADD_SPS_PPS_I_FRAME - ret = OMX_ErrorInputDataDecodeYet; -#else - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; -#endif - goto EXIT; - } else { - ret = OMX_ErrorMFCInit; - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - if (Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { - pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); - - returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, oneFrameSize); - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { - pH264Dec->hMFCH264Handle.indexTimestamp++; - pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if ((outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) || - (pH264Dec->hMFCH264Handle.bFlashPlayerMode != OMX_FALSE)) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - /** Fill Output Buffer **/ - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int actualWidth = outputInfo.img_width; - int actualHeight = outputInfo.img_height; - int actualImageSize = actualWidth * actualHeight; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + actualImageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + actualImageSize + actualImageSize / 4; - pOutputData->dataLen = (actualImageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, actualWidth, actualHeight, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - actualWidth = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (actualWidth * actualHeight * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420p out for ThumbnailMode/Flash player mode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, /* handle */ - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - pH264Dec->hMFCH264Handle.outputIndexTimestamp++; - pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - goto EXIT; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - pOutputData->dataLen = 0; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264_Decode_DRM(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 setConfVal = 0; - OMX_S32 returnCodec = 0; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize; - OMX_U32 FrameBufferUVSize; - // DRM - OMX_PTR pInputPhysBuffer; - OMX_PTR pInputVirtBuffer; - - FunctionIn(); - - if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Set the number of extra buffer to prevent tearing */ - /* DRM Play mode is returned only PhysicalAddress */ - setConfVal = H264_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); - - /* Default number in the driver is optimized */ - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - setConfVal = 0; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } else { - setConfVal = 8; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } - - pInputPhysBuffer = pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer; - pInputVirtBuffer = NULL; /* ??????????? */ - - SEC_OSAL_Log(SEC_LOG_ERROR, "pInputPhysBuffer = 0x%x, allocSize = 0x%0x", pInputPhysBuffer, pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, - pInputPhysBuffer, pInputVirtBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - SSBSIP_MFC_CROP_INFORMATION cropInfo; - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); - SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", - pSECInputPort->portDefinition.format.video.nFrameWidth, - pSECInputPort->portDefinition.format.video.nFrameHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", - imgResol.width, imgResol.height); - - SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", - cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , - cropInfo.crop_left_offset , cropInfo.crop_right_offset); - - pSECOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; - pSECOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; - pSECOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; - pSECOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; - - pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; - - /** Update Frame Size **/ - if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || - (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send crop info call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - OMX_IndexConfigCommonOutputCrop, - NULL); - } - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send Port Settings changed call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - -#ifdef ADD_SPS_PPS_I_FRAME - ret = OMX_ErrorInputDataDecodeYet; -#else - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; -#endif - goto EXIT; - } else { - ret = OMX_ErrorMFCInit; - goto EXIT; - } - } - - if ((pInputData->dataBuffer != NULL) && (pInputData->dataLen != 0)) { - pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); - if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - pInputPhysBuffer = pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer; - pInputVirtBuffer = NULL; /* ??????????? */ - - SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, - pInputPhysBuffer, pInputVirtBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - } - returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, oneFrameSize); - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { - pH264Dec->hMFCH264Handle.indexTimestamp++; - pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if ((outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) || - (pH264Dec->hMFCH264Handle.bFlashPlayerMode != OMX_FALSE)) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - /** Fill Output Buffer **/ - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int actualWidth = outputInfo.img_width; - int actualHeight = outputInfo.img_height; - int actualImageSize = actualWidth * actualHeight; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + actualImageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + actualImageSize + actualImageSize / 4; - pOutputData->dataLen = (actualImageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, actualWidth, actualHeight, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - actualWidth = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { - /* if use Post copy address structure */ - SEC_OSAL_Log(SEC_LOG_TRACE, "DRM] physical address data mode"); - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (actualWidth * actualHeight * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "DRM] Real data method"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - actualWidth, /* width */ - actualHeight, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - actualWidth, /* crop_width */ - actualHeight, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, /* handle */ - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); -#endif - pH264Dec->hMFCH264Handle.outputIndexTimestamp++; - pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - goto EXIT; - } - - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - pOutputData->dataLen = 0; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Decode */ -OMX_ERRORTYPE SEC_MFC_H264Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_BOOL endOfFrame = OMX_FALSE; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || - (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { - ret = OMX_ErrorNone; - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - ret = OMX_ErrorNone; - goto EXIT; - } - - if (pVideoDec->bDRMPlayerMode == OMX_FALSE) { -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_H264_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_H264_Decode_Block(pOMXComponent, pInputData, pOutputData); -#endif - } else { - ret = SEC_MFC_H264_Decode_DRM(pOMXComponent, pInputData, pOutputData); - } - - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataDecodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->previousDataLen = pInputData->dataLen; - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - OMX_BOOL bDRMPlayerMode = OMX_FALSE; - OMX_BOOL bFlashPlayerMode = OMX_FALSE; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_DEC, componentName) == 0) { - bDRMPlayerMode = OMX_FALSE; - bFlashPlayerMode = OMX_FALSE; - } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) { - bDRMPlayerMode = OMX_TRUE; - bFlashPlayerMode = OMX_FALSE; - } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_FP_DEC, componentName) == 0) { - bDRMPlayerMode = OMX_FALSE; - bFlashPlayerMode = OMX_TRUE; - } else { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_DEC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pH264Dec = SEC_OSAL_Malloc(sizeof(SEC_H264DEC_HANDLE)); - if (pH264Dec == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pH264Dec, 0, sizeof(SEC_H264DEC_HANDLE)); - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec; - - if (bDRMPlayerMode == OMX_TRUE) - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_DRM_DEC); - else if (bFlashPlayerMode == OMX_TRUE) - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_FP_DEC); - else - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_DEC); - - pVideoDec->bDRMPlayerMode = bDRMPlayerMode; - pH264Dec->hMFCH264Handle.bFlashPlayerMode = bFlashPlayerMode; -#ifdef S3D_SUPPORT - pH264Dec->hMFCH264Handle.bS3DMode = OMX_FALSE; -#endif - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - if (bFlashPlayerMode != OMX_FALSE) { - pSECPort->portDefinition.nBufferCountActual = MAX_H264_FP_VIDEO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_H264_FP_VIDEO_INPUTBUFFER_NUM; - } - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - if (bFlashPlayerMode != OMX_FALSE) { - pSECPort->portDefinition.nBufferCountActual = MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM; - } - - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); - pH264Dec->AVCComponent[i].nPortIndex = i; - pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; - pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; - } - - pOMXComponent->GetParameter = &SEC_MFC_H264Dec_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_H264Dec_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_H264Dec_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_H264Dec_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Dec_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Dec_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Dec_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Dec_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Dec_bufferProcess; - pSECComponent->sec_checkInputFrame = &Check_H264_Frame; - - pSECComponent->sec_allocSecureInputBuffer = &SEC_MFC_H264Dec_Alloc_SecureInputBuffer; - pSECComponent->sec_freeSecureInputBuffer = &SEC_MFC_H264Dec_Free_SecureInputBuffer; - - if (bDRMPlayerMode == OMX_TRUE) { - OMX_PTR hMFCHandle = NULL; - SEC_OSAL_Log(SEC_LOG_ERROR, "DRM--SsbSipMfcDecOpen, Line:%d", __LINE__); - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pH264Dec->hMFCH264Handle.hMFCHandle = hMFCHandle; - } - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_H264DEC_HANDLE *pH264Dec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pH264Dec = (SEC_H264DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pH264Dec != NULL) { - OMX_PTR hMFCHandle = NULL; - hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; - if ((hMFCHandle != NULL) && (pVideoDec->bDRMPlayerMode == OMX_TRUE)) { - SEC_OSAL_Log(SEC_LOG_ERROR, "DRM--SsbSipMfcDecClose, Line:%d", __LINE__); - SsbSipMfcDecClose(hMFCHandle); - hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle = NULL; - } - SEC_OSAL_Free(pH264Dec); - pH264Dec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.h deleted file mode 100644 index 370a15f..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/SEC_OMX_H264dec.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_H264dec.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_H264_DEC_COMPONENT -#define SEC_OMX_H264_DEC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "OMX_Video.h" - - -#define MAX_H264_FP_VIDEO_INPUTBUFFER_NUM 4 -#define MAX_H264_FP_VIDEO_OUTPUTBUFFER_NUM 4 - -typedef struct _SEC_MFC_H264DEC_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - OMX_PTR pMFCStreamBuffer; - OMX_PTR pMFCStreamPhyBuffer; - OMX_U32 indexTimestamp; - OMX_U32 outputIndexTimestamp; - OMX_BOOL bConfiguredMFC; - OMX_BOOL bFlashPlayerMode; -#ifdef S3D_SUPPORT - OMX_BOOL bS3DMode; -#endif - OMX_S32 returnCodec; -} SEC_MFC_H264DEC_HANDLE; - -typedef struct _SEC_H264DEC_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_H264DEC_HANDLE hMFCH264Handle; -} SEC_H264DEC_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.c deleted file mode 100644 index aa63c6c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) -{ - FunctionIn(); - - if (secComponents == NULL) - goto EXIT; - - /* component 1 - video decoder H.264 */ - SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPONENT_H264_DEC); - SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPONENT_H264_DEC_ROLE); - secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - - /* component 2 - video decoder H.264 for flash player */ - SEC_OSAL_Strcpy(secComponents[1]->componentName, SEC_OMX_COMPONENT_H264_FP_DEC); - SEC_OSAL_Strcpy(secComponents[1]->roles[0], SEC_OMX_COMPONENT_H264_DEC_ROLE); - secComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - - /* component 3 - video decoder H.264 for DRM */ - SEC_OSAL_Strcpy(secComponents[2]->componentName, SEC_OMX_COMPONENT_H264_DRM_DEC); - SEC_OSAL_Strcpy(secComponents[2]->roles[0], SEC_OMX_COMPONENT_H264_DEC_ROLE); - secComponents[2]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.h deleted file mode 100644 index 8c03cbe..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/h264/library_register.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_H264_REG -#define SEC_OMX_H264_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 3 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* H.264 */ -#define SEC_OMX_COMPONENT_H264_DEC "OMX.SEC.AVC.Decoder" -#define SEC_OMX_COMPONENT_H264_FP_DEC "OMX.SEC.FP.AVC.Decoder" -#define SEC_OMX_COMPONENT_H264_DRM_DEC "OMX.SEC.AVC.Decoder.secure" -#define SEC_OMX_COMPONENT_H264_DEC_ROLE "video_decoder.avc" - - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); - -#ifdef __cplusplus -}; -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/Android.mk deleted file mode 100644 index d353180..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/Android.mk +++ /dev/null @@ -1,65 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Mpeg4dec.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.M4V.Decoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_ANB), true) -LOCAL_CFLAGS += -DUSE_ANB -ifeq ($(BOARD_USE_CSC_FIMC), true) -ifeq ($(BOARD_USE_V4L2_ION), false) -LOCAL_CFLAGS += -DUSE_CSC_FIMC -endif -endif - -ifeq ($(BOARD_USE_CSC_GSCALER), true) -LOCAL_CFLAGS += -DUSE_CSC_GSCALER -endif -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libfimc libhwconverter -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libexynosgscaler -endif - -#ifeq ($(BOARD_USE_V4L2_ION),true) -#LOCAL_SHARED_LIBRARIES += libion -#endif - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS += -DCONFIG_MFC_FPS -endif - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) \ - $(BOARD_HAL_PATH)/include - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c deleted file mode 100644 index e820503..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.c +++ /dev/null @@ -1,2103 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mpeg4dec.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Vdec.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "library_register.h" -#include "SEC_OMX_Mpeg4dec.h" -#include "SsbSipMfcApi.h" - -#ifdef USE_ANB -#include "SEC_OSAL_Android.h" -#endif - -/* To use CSC_METHOD_PREFER_HW or CSC_METHOD_HW in SEC OMX, gralloc should allocate physical memory using FIMC */ -/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MPEG4_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -#define MPEG4_DEC_NUM_OF_EXTRA_BUFFERS 7 - -//#define FULL_FRAME_SEARCH - -/* MPEG4 Decoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; - -/* H.263 Decoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { - /* Baseline (Profile 0) */ - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}, - /* Profile 1 */ - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level10}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level20}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level30}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level40}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level45}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level50}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level60}, - {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level70}, - /* Profile 2 */ - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level10}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level20}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level30}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level40}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level45}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level50}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level60}, - {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level70}, - /* Profile 3, restricted up to SD resolution */ - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level10}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level20}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level30}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level40}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level45}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level50}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level60}, - {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level70}}; - -static OMX_HANDLETYPE ghMFCHandle = NULL; -static OMX_BOOL gbFIMV1 = OMX_FALSE; - -static int Check_Mpeg4_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) -{ - OMX_U32 len; - int readStream; - unsigned startCode; - OMX_BOOL bFrameStart; - - len = 0; - bFrameStart = OMX_FALSE; - - if (flag & OMX_BUFFERFLAG_CODECCONFIG) { - if (*pInputStream == 0x03) { /* FIMV1 */ - if (ghMFCHandle != NULL) { - BitmapInfoHhr *pInfoHeader; - SSBSIP_MFC_IMG_RESOLUTION imgResolution; - - pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1); - imgResolution.width = pInfoHeader->BiWidth; - imgResolution.height = pInfoHeader->BiHeight; - SsbSipMfcDecSetConfig(ghMFCHandle, MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, &imgResolution); - - SEC_OSAL_Log(SEC_LOG_TRACE, "width(%d), height(%d)", imgResolution.width, imgResolution.height); - gbFIMV1 = OMX_TRUE; - *pbEndOfFrame = OMX_TRUE; - return buffSize; - } - } - } - - if (gbFIMV1) { - *pbEndOfFrame = OMX_TRUE; - return buffSize; - } - - if (bPreviousFrameEOF == OMX_FALSE) - bFrameStart = OMX_TRUE; - - startCode = 0xFFFFFFFF; - if (bFrameStart == OMX_FALSE) { - /* find VOP start code */ - while(startCode != 0x1B6) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - len++; - if (len > buffSize) - goto EXIT; - } - } - - /* find next VOP start code */ - startCode = 0xFFFFFFFF; - while ((startCode != 0x1B6)) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - len++; - if (len > buffSize) - goto EXIT; - } - - *pbEndOfFrame = OMX_TRUE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); - - return len - 4; - -EXIT : - *pbEndOfFrame = OMX_FALSE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); - - return --len; -} - -static int Check_H263_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) -{ - OMX_U32 len; - int readStream; - unsigned startCode; - OMX_BOOL bFrameStart = 0; - unsigned pTypeMask = 0x03; - unsigned pType = 0; - - len = 0; - bFrameStart = OMX_FALSE; - - if (bPreviousFrameEOF == OMX_FALSE) - bFrameStart = OMX_TRUE; - - startCode = 0xFFFFFFFF; - if (bFrameStart == OMX_FALSE) { - /* find PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */ - while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - - readStream = *(pInputStream + len + 1); - pType = readStream & pTypeMask; - - len++; - if (len > buffSize) - goto EXIT; - } - } - - /* find next PSC */ - startCode = 0xFFFFFFFF; - pType = 0; - while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - - readStream = *(pInputStream + len + 1); - pType = readStream & pTypeMask; - - len++; - if (len > buffSize) - goto EXIT; - } - - *pbEndOfFrame = OMX_TRUE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize); - - return len - 3; - -EXIT : - - *pbEndOfFrame = OMX_FALSE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize); - - return --len; -} - -OMX_BOOL Check_Stream_PrefixCode(OMX_U8 *pInputStream, OMX_U32 streamSize, CODEC_TYPE codecType) -{ - switch (codecType) { - case CODEC_TYPE_MPEG4: - if (gbFIMV1) { - return OMX_TRUE; - } else { - if (streamSize < 3) { - return OMX_FALSE; - } else if ((pInputStream[0] == 0x00) && - (pInputStream[1] == 0x00) && - (pInputStream[2] == 0x01)) { - return OMX_TRUE; - } else { - return OMX_FALSE; - } - } - break; - case CODEC_TYPE_H263: - if (streamSize > 0) - return OMX_TRUE; - else - return OMX_FALSE; - default: - SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType); - return OMX_FALSE; - } -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - } - break; - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_S32 codecType; - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); - else - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE); - } - break; - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; - OMX_U32 maxProfileLevelNum = 0; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - pProfileLevel = supportedMPEG4ProfileLevels; - maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - } else { - pProfileLevel = supportedH263ProfileLevels; - maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - } - - if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pProfileLevel += pDstProfileLevel->nProfileIndex; - pDstProfileLevel->eProfile = pProfileLevel->profile; - pDstProfileLevel->eLevel = pProfileLevel->level; - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex]; - pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; - pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; - } else { - pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex]; - pDstProfileLevel->eProfile = pSrcH263Param->eProfile; - pDstProfileLevel->eLevel = pSrcH263Param->eLevel; - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - } - break; - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - //((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; - } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - //((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; - OMX_U32 portIndex = pPortDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - OMX_U32 width, height, size; - OMX_U32 realWidth, realHeight; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); - - realWidth = pSECPort->portDefinition.format.video.nFrameWidth; - realHeight = pSECPort->portDefinition.format.video.nFrameHeight; - width = ((realWidth + 15) & (~15)); - height = ((realHeight + 15) & (~15)); - size = (width * height * 3) / 2; - pSECPort->portDefinition.format.video.nStride = width; - pSECPort->portDefinition.format.video.nSliceHeight = height; - pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; - - if (portIndex == INPUT_PORT_INDEX) { - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; - pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; - pSECOutputPort->portDefinition.format.video.nStride = width; - pSECOutputPort->portDefinition.format.video.nSliceHeight = height; - - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.nBufferSize = - ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); - break; - default: - SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); - ret = OMX_ErrorUnsupportedSetting; - break; - } - } - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - /* - * To do: Check validity of profile & level parameters - */ - - pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex]; - pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; - pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; - } else { - /* - * To do: Check validity of profile & level parameters - */ - - pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex]; - pDstH263Param->eProfile = pSrcProfileLevel->eProfile; - pDstH263Param->eLevel = pSrcProfileLevel->eLevel; - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { - SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - *pIndexType = OMX_IndexVendorThumbnailMode; - - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_ComponentRoleEnum( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 codecType; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - codecType = ((SEC_MPEG4_HANDLE *)(((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); - else - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H263_DEC_ROLE); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); - - if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_DEC); -#endif - pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecExe(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_DEC); -#endif - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); - } - } - -EXIT: - SEC_OSAL_ThreadExit(NULL); - FunctionOut(); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - OMX_PTR pStreamBuffer = NULL; - OMX_PTR pStreamPhyBuffer = NULL; -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfInit(PERF_ID_DEC); - SEC_OSAL_PerfInit(PERF_ID_CSC); -#endif - CSC_METHOD csc_method = CSC_METHOD_SW; - - FunctionIn(); - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); - } else { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - ghMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; - - /* Allocate decoder's input buffer */ - /* Get first input buffer */ - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[0].dataSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - /* Get second input buffer */ - pStreamBuffer = NULL; - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[1].dataSize = 0; - pVideoDec->indexInputBuffer = 0; - - pVideoDec->bFirstFrame = OMX_TRUE; - - pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - pVideoDec->NBDecThread.oneFrameSize = 0; - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, - SEC_MFC_DecodeThread, - pOMXComponent)) { - pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; - } -#endif - - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; - - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0; - - pSECComponent->getAllDelayBuffer = OMX_FALSE; - -#ifdef USE_ANB -#if defined(USE_CSC_FIMC) || defined(USE_CSC_GSCALER) - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - csc_method = CSC_METHOD_PREFER_HW; - } -#endif -#endif - pVideoDec->csc_handle = csc_init(&csc_method); - pVideoDec->csc_set_format = OMX_FALSE; - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - - FunctionIn(); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfPrint("[DEC]", PERF_ID_DEC); - SEC_OSAL_PerfPrint("[CSC]", PERF_ID_CSC); -#endif - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; - - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = NULL; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { - pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); - pVideoDec->NBDecThread.hNBDecodeThread = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.hDecFrameEnd = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.hDecFrameStart = NULL; - } -#endif - - if (hMFCHandle != NULL) { - SsbSipMfcDecClose(hMFCHandle); - ghMFCHandle = hMFCHandle = NULL; - pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL; - } - - if (pVideoDec->csc_handle != NULL) { - csc_deinit(pVideoDec->csc_handle); - pVideoDec->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 configValue; - int bufWidth; - int bufHeight; - OMX_U32 FrameBufferYSize = 0; - OMX_U32 FrameBufferUVSize = 0; - OMX_BOOL outputDataValid = OMX_FALSE; - - FunctionIn(); - - if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE MFCCodecType; - if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { - if (gbFIMV1) - MFCCodecType = FIMV1_DEC; - else - MFCCodecType = MPEG4_DEC; - } else { - MFCCodecType = H263_DEC; - } - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Set mpeg4 deblocking filter enable */ - configValue = 1; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_POST_ENABLE, &configValue); - - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - configValue = 0; // the number that you want to delay - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); - } else { - configValue = MPEG4_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); - } - - SsbSipMfcDecSetInBuf(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer, - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); - if (pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - if (SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { - ret = OMX_ErrorMFCInit; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecGetConfig failed", __FUNCTION__); - goto EXIT; - } - - /** Update Frame Size **/ - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /* Send Port Settings changed call back */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, // The command was completed - OMX_DirOutput, // This is the port index - 0, - NULL); - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; - if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - } else { - pOutputData->dataLen = 0; - ret = OMX_ErrorInputDataDecodeYet; - } - goto EXIT; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecInit failed", __FUNCTION__); - ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - - if ((pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && - (pVideoDec->bFirstFrame == OMX_FALSE)) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - /* wait for mfc decode done */ - if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if ((SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - outputDataValid = OMX_TRUE; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - outputDataValid = OMX_FALSE; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - outputDataValid = OMX_FALSE; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && - ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { - pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - - outputDataValid = OMX_FALSE; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - } - - if (ret == OMX_ErrorInputDataDecodeYet) { - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; - //pInputData->dataLen = oneFrameSize; - //pInputData->remainDataLen = oneFrameSize; - } - - if ((Check_Stream_PrefixCode(pInputData->dataBuffer, oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { - if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { - SsbSipMfcDecSetConfig(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - SsbSipMfcDecSetInBuf(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer, - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; - - /* mfc decode start */ - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; - pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; - - SEC_OSAL_SleepMillisec(0); - - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE) && - (outputDataValid == OMX_FALSE)) { - ret = OMX_ErrorInputDataDecodeYet; - } - - pVideoDec->bFirstFrame = OMX_FALSE; - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - } - - /** Fill Output Buffer **/ - if (outputDataValid == OMX_TRUE) { - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, /* handle */ - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - } else { - pOutputData->dataLen = 0; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 configValue; - OMX_S32 returnCodec; - int bufWidth; - int bufHeight; - OMX_U32 FrameBufferYSize; - OMX_U32 FrameBufferUVSize; - - FunctionIn(); - - if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE MFCCodecType; - if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { - if (gbFIMV1) - MFCCodecType = FIMV1_DEC; - else - MFCCodecType = MPEG4_DEC; - } else { - MFCCodecType = H263_DEC; - } - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Set mpeg4 deblocking filter enable */ - configValue = 1; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_POST_ENABLE, &configValue); - - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - configValue = 0; // the number that you want to delay - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); - } else { - configValue = MPEG4_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); - } - - returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - if (SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { - ret = OMX_ErrorMFCInit; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecGetConfig failed", __FUNCTION__); - goto EXIT; - } - - /** Update Frame Size **/ - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /* Send Port Settings changed call back */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, // The command was completed - OMX_DirOutput, // This is the port index - 0, - NULL); - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; - if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - } else { - pOutputData->dataLen = 0; - ret = OMX_ErrorInputDataDecodeYet; - } - goto EXIT; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecInit failed", __FUNCTION__); - ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) { - pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); - - returnCodec = SsbSipMfcDecExe(hMFCHandle, oneFrameSize); - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - if ((SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - /** Fill Output Buffer **/ - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, /* handle */ - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; - pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { - ret = OMX_ErrorInputDataDecodeYet; - } - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - goto EXIT; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - pOutputData->dataLen = 0; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Decode */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_BOOL bCheckPrefix = OMX_FALSE; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || - (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { - ret = OMX_ErrorNone; - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - ret = OMX_ErrorNone; - goto EXIT; - } - -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_Mpeg4_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_Mpeg4_Decode_Block(pOMXComponent, pInputData, pOutputData); -#endif - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataDecodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->previousDataLen = pInputData->dataLen; - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - OMX_S32 codecType = -1; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) { - codecType = CODEC_TYPE_MPEG4; - } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H263_DEC, componentName) == 0) { - codecType = CODEC_TYPE_H263; - } else { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_DEC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pMpeg4Dec = SEC_OSAL_Malloc(sizeof(SEC_MPEG4_HANDLE)); - if (pMpeg4Dec == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4_HANDLE alloc error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - SEC_OSAL_Memset(pMpeg4Dec, 0, sizeof(SEC_MPEG4_HANDLE)); - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec; - pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType; - - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MPEG4_DEC); - else - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H263_DEC); - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - if (codecType == CODEC_TYPE_MPEG4) { - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); - } else { - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); - } - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - if (codecType == CODEC_TYPE_MPEG4) { - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); - pMpeg4Dec->mpeg4Component[i].nPortIndex = i; - pMpeg4Dec->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; - pMpeg4Dec->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level3; - } - } else { - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); - pMpeg4Dec->h263Component[i].nPortIndex = i; - pMpeg4Dec->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2; - pMpeg4Dec->h263Component[i].eLevel = OMX_VIDEO_H263Level45; - } - } - - pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Dec_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Dec_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_Mpeg4Dec_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Dec_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_Mpeg4Dec_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Dec_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Dec_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Dec_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Dec_bufferProcess; - if (codecType == CODEC_TYPE_MPEG4) - pSECComponent->sec_checkInputFrame = &Check_Mpeg4_Frame; - else - pSECComponent->sec_checkInputFrame = &Check_H263_Frame; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pMpeg4Dec = (SEC_MPEG4_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pMpeg4Dec != NULL) { - SEC_OSAL_Free(pMpeg4Dec); - ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h deleted file mode 100644 index 256cb66..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/SEC_OMX_Mpeg4dec.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mpeg4dec.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_MPEG4_DEC_COMPONENT -#define SEC_OMX_MPEG4_DEC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" - - -typedef enum _CODEC_TYPE -{ - CODEC_TYPE_H263, - CODEC_TYPE_MPEG4 -} CODEC_TYPE; - -/* - * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file - */ -typedef struct _BitmapInfoHhr -{ - OMX_U32 BiSize; - OMX_U32 BiWidth; - OMX_U32 BiHeight; - OMX_U16 BiPlanes; - OMX_U16 BiBitCount; - OMX_U32 BiCompression; - OMX_U32 BiSizeImage; - OMX_U32 BiXPelsPerMeter; - OMX_U32 BiYPelsPerMeter; - OMX_U32 BiClrUsed; - OMX_U32 BiClrImportant; -} BitmapInfoHhr; - -typedef struct _SEC_MFC_MPEG4_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - OMX_PTR pMFCStreamBuffer; - OMX_PTR pMFCStreamPhyBuffer; - OMX_U32 indexTimestamp; - OMX_U32 outputIndexTimestamp; - OMX_BOOL bConfiguredMFC; - CODEC_TYPE codecType; - OMX_S32 returnCodec; -} SEC_MFC_MPEG4_HANDLE; - -typedef struct _SEC_MPEG4_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_MPEG4_HANDLE hMFCMpeg4Handle; -} SEC_MPEG4_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); - OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.c deleted file mode 100644 index 2ae1b0d..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MPEG4_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) -{ - FunctionIn(); - - if (ppSECComponent == NULL) - goto EXIT; - - /* component 1 - video decoder MPEG4 */ - SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MPEG4_DEC); - SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MPEG4_DEC_ROLE); - ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - - /* component 2 - video decoder H.263 */ - SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPONENT_H263_DEC); - SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPONENT_H263_DEC_ROLE); - ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.h deleted file mode 100644 index 40aec73..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/mpeg4/library_register.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_MPEG4_DEC_REG -#define SEC_OMX_MPEG4_DEC_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 2 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* MPEG4 */ -#define SEC_OMX_COMPONENT_MPEG4_DEC "OMX.SEC.MPEG4.Decoder" -#define SEC_OMX_COMPONENT_MPEG4_DEC_ROLE "video_decoder.mpeg4" - -/* H.263 */ -#define SEC_OMX_COMPONENT_H263_DEC "OMX.SEC.H263.Decoder" -#define SEC_OMX_COMPONENT_H263_DEC_ROLE "video_decoder.h263" - - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); - -#ifdef __cplusplus -}; -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/Android.mk deleted file mode 100644 index 8be63e1..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/Android.mk +++ /dev/null @@ -1,65 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Wmvdec.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.WMV.Decoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_ANB), true) -LOCAL_CFLAGS += -DUSE_ANB -ifeq ($(BOARD_USE_CSC_FIMC), true) -ifeq ($(BOARD_USE_V4L2_ION), false) -LOCAL_CFLAGS += -DUSE_CSC_FIMC -endif -endif - -ifeq ($(BOARD_USE_CSC_GSCALER), true) -LOCAL_CFLAGS += -DUSE_CSC_GSCALER -endif -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libfimc libhwconverter -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libexynosgscaler -endif - -#ifeq ($(BOARD_USE_V4L2_ION),true) -#LOCAL_SHARED_LIBRARIES += libion -#endif - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS += -DCONFIG_MFC_FPS -endif - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) \ - $(BOARD_HAL_PATH)/include - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.c deleted file mode 100644 index 7e9194b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.c +++ /dev/null @@ -1,2014 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Wmvdec.c - * @brief - * @author HyeYeon Chung (hyeon.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.8.16 : Create - * 2010.8.20 : Support WMV3 (Vc-1 Simple/Main Profile) - * 2010.8.21 : Support WMvC1 (Vc-1 Advanced Profile) - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Vdec.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_Memory.h" -#include "library_register.h" -#include "SEC_OMX_Wmvdec.h" -#include "SsbSipMfcApi.h" -#include "SEC_OSAL_Event.h" - -#ifdef USE_ANB -#include "SEC_OSAL_Android.h" -#endif - -/* To use CSC_METHOD_PREFER_HW or CSC_METHOD_HW in SEC OMX, gralloc should allocate physical memory using FIMC */ -/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_WMV_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -#define WMV_DEC_NUM_OF_EXTRA_BUFFERS 7 - -//#define FULL_FRAME_SEARCH - -/* ASF parser does not send start code on OpenCORE */ -#define WO_START_CODE - -static OMX_HANDLETYPE ghMFCHandle = NULL; -static WMV_FORMAT gWvmFormat = WMV_FORMAT_UNKNOWN; - -const OMX_U32 wmv3 = 0x33564d57; -const OMX_U32 wvc1 = 0x31435657; -const OMX_U32 wmva = 0x41564d57; - -static int Check_Wmv_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) -{ - OMX_U32 compressionID; - OMX_BOOL bFrameStart; - OMX_U32 len, readStream; - OMX_U32 startCode; - - SEC_OSAL_Log(SEC_LOG_TRACE, "buffSize = %d", buffSize); - - len = 0; - bFrameStart = OMX_FALSE; - - if (flag & OMX_BUFFERFLAG_CODECCONFIG) { - BitmapInfoHhr *pBitmapInfoHeader; - pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream; - - compressionID = pBitmapInfoHeader->BiCompression; - if (compressionID == wmv3) { - SEC_OSAL_Log(SEC_LOG_TRACE, "WMV_FORMAT_WMV3"); - gWvmFormat = WMV_FORMAT_WMV3; - - *pbEndOfFrame = OMX_TRUE; - return buffSize; - } - else if ((compressionID == wvc1) || (compressionID == wmva)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "WMV_FORMAT_VC1"); - gWvmFormat = WMV_FORMAT_VC1; - -#ifdef WO_START_CODE -/* ASF parser does not send start code on OpenCORE */ - *pbEndOfFrame = OMX_TRUE; - return buffSize; -#endif - } - } - - if (gWvmFormat == WMV_FORMAT_WMV3) { - *pbEndOfFrame = OMX_TRUE; - return buffSize; - } - -#ifdef WO_START_CODE -/* ASF parser does not send start code on OpenCORE */ - if (gWvmFormat == WMV_FORMAT_VC1) { - *pbEndOfFrame = OMX_TRUE; - return buffSize; - } -#else - /* TODO : for comformanc test based on common buffer scheme w/o parser */ - - if (bPreviousFrameEOF == OMX_FALSE) - bFrameStart = OMX_TRUE; - - startCode = 0xFFFFFFFF; - if (bFrameStart == OMX_FALSE) { - /* find Frame start code */ - while(startCode != 0x10D) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - len++; - if (len > buffSize) - goto EXIT; - } - } - - /* find next Frame start code */ - startCode = 0xFFFFFFFF; - while ((startCode != 0x10D)) { - readStream = *(pInputStream + len); - startCode = (startCode << 8) | readStream; - len++; - if (len > buffSize) - goto EXIT; - } - - *pbEndOfFrame = OMX_TRUE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); - - return len - 4; -#endif - -EXIT : - *pbEndOfFrame = OMX_FALSE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); - - return --len; -} - -OMX_BOOL Check_Stream_PrefixCode(OMX_U8 *pInputStream, OMX_U32 streamSize, WMV_FORMAT wmvFormat) -{ - switch (wmvFormat) { - case WMV_FORMAT_WMV3: - if (streamSize > 0) - return OMX_TRUE; - else - return OMX_FALSE; - break; - case WMV_FORMAT_VC1: - -#ifdef WO_START_CODE - /* ASF parser does not send start code on OpenCORE */ - if (streamSize > 3) - return OMX_TRUE; - else - return OMX_FALSE; - break; -#else - /* TODO : for comformanc test based on common buffer scheme w/o parser */ - if (streamSize < 3) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: streamSize is too small (%d)", __FUNCTION__, streamSize); - return OMX_FALSE; - } else if ((pInputStream[0] == 0x00) && - (pInputStream[1] == 0x00) && - (pInputStream[2] == 0x01)) { - return OMX_TRUE; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Cannot find prefix", __FUNCTION__); - return OMX_FALSE; - } -#endif - break; - - default: - SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); - return OMX_FALSE; - break; - } -} - -OMX_BOOL Make_Stream_MetaData(OMX_U8 *pInputStream, OMX_U32 *pStreamSize, WMV_FORMAT wmvFormat) -{ - OMX_U32 width, height; - OMX_U8 *pCurrBuf = pInputStream; - OMX_U32 currPos = 0; - - FunctionIn(); - - /* Sequence Layer Data Structure */ - OMX_U8 const_C5[4] = {0x00, 0x00, 0x00, 0xc5}; - OMX_U8 const_04[4] = {0x04, 0x00, 0x00, 0x00}; - OMX_U8 const_0C[4] = {0x0C, 0x00, 0x00, 0x00}; - OMX_U8 struct_B_1[4] = {0xB3, 0x19, 0x00, 0x00}; - OMX_U8 struct_B_2[4] = {0x44, 0x62, 0x05, 0x00}; - OMX_U8 struct_B_3[4] = {0x0F, 0x00, 0x00, 0x00}; - OMX_U8 struct_C[4] = {0x30, 0x00, 0x00, 0x00}; - - switch (wmvFormat) { - case WMV_FORMAT_WMV3: - if (*pStreamSize >= BITMAPINFOHEADER_SIZE) { - BitmapInfoHhr *pBitmapInfoHeader; - pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream; - - width = pBitmapInfoHeader->BiWidth; - height = pBitmapInfoHeader->BiHeight; - if (*pStreamSize > BITMAPINFOHEADER_SIZE) - SEC_OSAL_Memcpy(struct_C, pInputStream+BITMAPINFOHEADER_SIZE, 4); - - SEC_OSAL_Memcpy(pCurrBuf + currPos, const_C5, 4); - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos, const_04, 4); - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_C, 4); - currPos +=4; - - /* struct_A : VERT_SIZE */ - pCurrBuf[currPos] = height & 0xFF; - pCurrBuf[currPos+1] = (height>>8) & 0xFF; - pCurrBuf[currPos+2] = (height>>16) & 0xFF; - pCurrBuf[currPos+3] = (height>>24) & 0xFF; - currPos +=4; - - /* struct_A : HORIZ_SIZE */ - pCurrBuf[currPos] = width & 0xFF; - pCurrBuf[currPos+1] = (width>>8) & 0xFF; - pCurrBuf[currPos+2] = (width>>16) & 0xFF; - pCurrBuf[currPos+3] = (width>>24) & 0xFF; - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos,const_0C, 4); - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_1, 4); - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_2, 4); - currPos +=4; - - SEC_OSAL_Memcpy(pCurrBuf + currPos, struct_B_3, 4); - currPos +=4; - - *pStreamSize = currPos; - return OMX_TRUE; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize); - return OMX_FALSE; - } - break; - case WMV_FORMAT_VC1: - if (*pStreamSize >= BITMAPINFOHEADER_ASFBINDING_SIZE) { - SEC_OSAL_Memcpy(pCurrBuf, pInputStream + BITMAPINFOHEADER_ASFBINDING_SIZE, *pStreamSize - BITMAPINFOHEADER_ASFBINDING_SIZE); - *pStreamSize -= BITMAPINFOHEADER_ASFBINDING_SIZE; - return OMX_TRUE; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize); - return OMX_FALSE; - } - break; - default: - SEC_OSAL_Log(SEC_LOG_WARNING, "%s: It is not necessary to make bitstream metadata for wmvFormat (%d)", __FUNCTION__, wmvFormat); - return OMX_FALSE; - break; - } -} - -#ifdef WO_START_CODE -OMX_BOOL Make_Stream_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize, WMV_FORMAT wmvFormat) -{ - OMX_U8 frameStartCode[4] = {0x00, 0x00, 0x01, 0x0d}; - OMX_U32 i; - - switch (wmvFormat) { - case WMV_FORMAT_WMV3: - return OMX_TRUE; - break; - - case WMV_FORMAT_VC1: - /* Should find better way to shift data */ - SEC_OSAL_Memmove(pInputStream+4, pInputStream, streamSize); - SEC_OSAL_Memcpy(pInputStream, frameStartCode, 4); - - return OMX_TRUE; - break; - - default: - SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); - return OMX_FALSE; - break; - } -} -#endif - -OMX_ERRORTYPE SEC_MFC_WmvDec_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoWmv: - { - OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = NULL; - SEC_WMV_HANDLE *pWmvDec = NULL; - ret = SEC_OMX_Check_SizeVersion(pDstWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstWmvParam->nPortIndex > OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - } - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcWmvParam = &pWmvDec->WmvComponent[pDstWmvParam->nPortIndex]; - - SEC_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE); - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_WMV_HANDLE *pWmvDec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_WmvDec_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoWmv: - { - OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = NULL; - OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure; - SEC_WMV_HANDLE *pWmvDec = NULL; - ret = SEC_OMX_Check_SizeVersion(pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcWmvParam->nPortIndex > OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstWmvParam = &pWmvDec->WmvComponent[pSrcWmvParam->nPortIndex]; - - SEC_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; - OMX_U32 portIndex = pPortDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - OMX_U32 width, height, size; - OMX_U32 realWidth, realHeight; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); - - realWidth = pSECPort->portDefinition.format.video.nFrameWidth; - realHeight = pSECPort->portDefinition.format.video.nFrameHeight; - width = ((realWidth + 15) & (~15)); - height = ((realHeight + 15) & (~15)); - size = (width * height * 3) / 2; - pSECPort->portDefinition.format.video.nStride = width; - pSECPort->portDefinition.format.video.nSliceHeight = height; - pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; - - if (portIndex == INPUT_PORT_INDEX) { - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; - pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; - pSECOutputPort->portDefinition.format.video.nStride = width; - pSECOutputPort->portDefinition.format.video.nSliceHeight = height; - - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.nBufferSize = - ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); - break; - default: - SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); - ret = OMX_ErrorUnsupportedSetting; - break; - } - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_WMV_HANDLE *pWmvDec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_WmvDec_GetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_WmvDec_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_WmvDec_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { - SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - *pIndexType = OMX_IndexVendorThumbnailMode; - - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_WmvDec_ComponentRoleEnum( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_WMV_DEC_ROLE); - ret = OMX_ErrorNone; - } else { - ret = OMX_ErrorUnsupportedIndex; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); - - if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_DEC); -#endif - pWmvDec->hMFCWmvHandle.returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_DEC); -#endif - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); - } - } - -EXIT: - SEC_OSAL_ThreadExit(NULL); - FunctionOut(); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_WMV_HANDLE *pWmvDec = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - OMX_PTR pStreamBuffer = NULL; - OMX_PTR pStreamPhyBuffer = NULL; - CSC_METHOD csc_method = CSC_METHOD_SW; - - FunctionIn(); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfInit(PERF_ID_DEC); - SEC_OSAL_PerfInit(PERF_ID_CSC); -#endif - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); - } else { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - ghMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle = hMFCHandle; - - /* Allocate decoder's input buffer */ - /* Get first input buffer */ - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[0].dataSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - /* Get second input buffer */ - pStreamBuffer = NULL; - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[1].dataSize = 0; - pVideoDec->indexInputBuffer = 0; - - pVideoDec->bFirstFrame = OMX_TRUE; - - pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - pVideoDec->NBDecThread.oneFrameSize = 0; - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, - SEC_MFC_DecodeThread, - pOMXComponent)) { - pWmvDec->hMFCWmvHandle.returnCodec = MFC_RET_OK; - } -#endif - - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; - - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pWmvDec->hMFCWmvHandle.indexTimestamp = 0; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - -#ifdef USE_ANB -#if defined(USE_CSC_FIMC) || defined(USE_CSC_GSCALER) - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - csc_method = CSC_METHOD_PREFER_HW; - } -#endif -#endif - pVideoDec->csc_handle = csc_init(&csc_method); - pVideoDec->csc_set_format = OMX_FALSE; - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_WMV_HANDLE *pWmvDec = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - - FunctionIn(); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfPrint("[DEC]", PERF_ID_DEC); - SEC_OSAL_PerfPrint("[CSC]", PERF_ID_CSC); -#endif - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; - - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = NULL; - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { - pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); - pVideoDec->NBDecThread.hNBDecodeThread = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.hDecFrameEnd = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.hDecFrameStart = NULL; - } -#endif - - if (hMFCHandle != NULL) { - SsbSipMfcDecClose(hMFCHandle); - pWmvDec->hMFCWmvHandle.hMFCHandle = NULL; - } - - if (pVideoDec->csc_handle != NULL) { - csc_deinit(pVideoDec->csc_handle); - pVideoDec->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Wmv_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 configValue = 0; - OMX_BOOL bMetaData = OMX_FALSE; - OMX_BOOL bStartCode = OMX_FALSE; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize = 0; - OMX_U32 FrameBufferUVSize = 0; - OMX_BOOL outputDataValid = OMX_FALSE; - - FunctionIn(); - - if (pWmvDec->hMFCWmvHandle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE MFCCodecType; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) - MFCCodecType = VC1RCV_DEC; - else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) - MFCCodecType = VC1_DEC; - else - MFCCodecType = UNKNOWN_TYPE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "codec type = %d", MFCCodecType); - - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - configValue = 0; // the number that you want to delay - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); - } else { - configValue = WMV_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); - } - - bMetaData = Make_Stream_MetaData(pInputData->dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); - if (bMetaData == OMX_FALSE) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream MetaData"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } - - SsbSipMfcDecSetInBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer, - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pWmvDec->hMFCWmvHandle.returnCodec = SsbSipMfcDecInit(pWmvDec->hMFCWmvHandle.hMFCHandle, MFCCodecType, oneFrameSize); - if (pWmvDec->hMFCWmvHandle.returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { - ret = OMX_ErrorMFCInit; - SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecGetConfig failed"); - goto EXIT; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "## nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - /** Update Frame Size **/ - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - SEC_UpdateFrameSize(pOMXComponent); - - /* Send Port Settings changed call back */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, // The command was completed - OMX_DirOutput, // This is the port index - 0, - NULL); - } - - pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_TRUE; - - if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - } else { - -#ifdef WO_START_CODE -/* ASF parser does not send start code on OpenCORE */ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; -#else -/* TODO : for comformanc test based on common buffer scheme w/o parser */ - pOutputData->dataLen = 0; - ret = OMX_ErrorInputDataDecodeYet; -#endif - } - goto EXIT; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecInit failed"); - ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->nFlags; - - if ((pWmvDec->hMFCWmvHandle.returnCodec == MFC_RET_OK) && (pVideoDec->bFirstFrame == OMX_FALSE)) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - /* wait for mfc decode done */ - if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - status = SsbSipMfcDecGetOutBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if ((SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - outputDataValid = OMX_TRUE; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp++; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - outputDataValid = OMX_FALSE; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - outputDataValid = OMX_FALSE; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && - ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { - pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - - outputDataValid = OMX_FALSE; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - } - -#ifdef WO_START_CODE - if (pInputData->allocSize < oneFrameSize+4) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Can't attach startcode due to lack of buffer space"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } - - bStartCode = Make_Stream_StartCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); - if (bStartCode == OMX_FALSE) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream Start Code"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } -#endif - - if (ret == OMX_ErrorInputDataDecodeYet) { - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; - //pInputData->dataLen = oneFrameSize; - //pInputData->remainDataLen = oneFrameSize; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "SsbSipMfcDecExe oneFrameSize = %d", oneFrameSize); - - if ((Check_Stream_PrefixCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat) == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { - if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pWmvDec->hMFCWmvHandle.indexTimestamp)); - pWmvDec->hMFCWmvHandle.indexTimestamp++; - pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; - } - - SsbSipMfcDecSetInBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer, - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; -#ifdef WO_START_CODE - pVideoDec->NBDecThread.oneFrameSize = oneFrameSize + 4; /* Frame Start Code */ -#else - pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; -#endif - /* mfc decode start */ - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; - pWmvDec->hMFCWmvHandle.returnCodec = MFC_RET_OK; - - SEC_OSAL_SleepMillisec(0); - - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pWmvDec->hMFCWmvHandle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pWmvDec->hMFCWmvHandle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE) && - (outputDataValid == OMX_FALSE)) { - ret = OMX_ErrorInputDataDecodeYet; - } - - pVideoDec->bFirstFrame = OMX_FALSE; - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - } - - /** Fill Output Buffer **/ - if (outputDataValid == OMX_TRUE) { - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - } else { - pOutputData->dataLen = 0; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Wmv_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 configValue = 0; - OMX_S32 returnCodec = 0; - OMX_BOOL bMetaData = OMX_FALSE; - OMX_BOOL bStartCode = OMX_FALSE; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize; - OMX_U32 FrameBufferUVSize; - - FunctionIn(); - - if (pWmvDec->hMFCWmvHandle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE MFCCodecType; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) - MFCCodecType = VC1RCV_DEC; - else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) - MFCCodecType = VC1_DEC; - else - MFCCodecType = UNKNOWN_TYPE; - - SEC_OSAL_Log(SEC_LOG_TRACE, "codec type = %d", MFCCodecType); - - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - configValue = 0; // the number that you want to delay - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); - } else { - configValue = WMV_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); - } - - bMetaData = Make_Stream_MetaData(pInputData->dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); - if (bMetaData == OMX_FALSE) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream MetaData"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } - - returnCodec = SsbSipMfcDecInit(pWmvDec->hMFCWmvHandle.hMFCHandle, MFCCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { - ret = OMX_ErrorMFCInit; - SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecGetConfig failed"); - goto EXIT; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "## nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - /** Update Frame Size **/ - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != (unsigned int)imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != (unsigned int)imgResol.height)) { - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", - pSECInputPort->portDefinition.format.video.nFrameWidth, pSECInputPort->portDefinition.format.video.nFrameHeight, - pSECInputPort->portDefinition.format.video.nStride, pSECInputPort->portDefinition.format.video.nSliceHeight); - - SEC_UpdateFrameSize(pOMXComponent); - - /* Send Port Settings changed call back */ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, // The command was completed - OMX_DirOutput, // This is the port index - 0, - NULL); - } - - pWmvDec->hMFCWmvHandle.bConfiguredMFC = OMX_TRUE; - - if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - } else { - -#ifdef WO_START_CODE -/* ASF parser does not send start code on OpenCORE */ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; -#else -/* TODO : for comformanc test based on common buffer scheme w/o parser */ - pOutputData->dataLen = 0; - ret = OMX_ErrorInputDataDecodeYet; -#endif - } - goto EXIT; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "SsbSipMfcDecInit failed"); - ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - -#ifdef WO_START_CODE - if (pInputData->allocSize < oneFrameSize+4) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Can't attach startcode due to lack of buffer space"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } - - bStartCode = Make_Stream_StartCode(pInputData->dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); - if (bStartCode == OMX_FALSE) { - SEC_OSAL_Log(SEC_LOG_ERROR, "Fail to Make Stream Start Code"); - ret = OMX_ErrorMFCInit; - goto EXIT; - } -#endif - - SEC_OSAL_Log(SEC_LOG_TRACE, "SsbSipMfcDecExe oneFrameSize = %d", oneFrameSize); - - if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pWmvDec->hMFCWmvHandle.wmvFormat) == OMX_TRUE) { - pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pWmvDec->hMFCWmvHandle.indexTimestamp)); - -#ifdef WO_START_CODE - returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, oneFrameSize+4); /* Frame Start Code */ -#else - returnCodec = SsbSipMfcDecExe(pWmvDec->hMFCWmvHandle.hMFCHandle, oneFrameSize); -#endif - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - status = SsbSipMfcDecGetOutBuf(pWmvDec->hMFCWmvHandle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { - pWmvDec->hMFCWmvHandle.indexTimestamp++; - pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; - } - - if (SsbSipMfcDecGetConfig(pWmvDec->hMFCWmvHandle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - /** Fill Output Buffer **/ - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (outputInfo.img_width * outputInfo.img_height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - pWmvDec->hMFCWmvHandle.outputIndexTimestamp++; - pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - goto EXIT; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - pOutputData->dataLen = 0; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Decode */ -OMX_ERRORTYPE SEC_MFC_WmvDec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_WMV_HANDLE *pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_BOOL bCheckPrefix = OMX_FALSE; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || - (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - goto EXIT; - } - - pWmvDec->hMFCWmvHandle.wmvFormat = gWvmFormat; - -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_Wmv_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_Wmv_Decode_Block(pOMXComponent, pInputData, pOutputData); -#endif - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataDecodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->previousDataLen = pInputData->dataLen; - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_WMV_HANDLE *pWmvDec = NULL; - OMX_S32 wmvFormat = WMV_FORMAT_UNKNOWN; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: parameters are null, ret:%X", ret); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_WMV_DEC, componentName) != 0) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: SEC_OMX_VideoDecodeComponentInit error, ret: %X", ret); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_DEC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: componentName alloc error, ret: %X", ret); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pWmvDec = SEC_OSAL_Malloc(sizeof(SEC_WMV_HANDLE)); - if (pWmvDec == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_ComponentInit: SEC_WMV_HANDLE alloc error, ret: %X", ret); - goto EXIT; - } - SEC_OSAL_Memset(pWmvDec, 0, sizeof(SEC_WMV_HANDLE)); - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec; - pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat; - - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_WMV_DEC); - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/wmv"); - - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pWmvDec->WmvComponent[i], OMX_VIDEO_PARAM_WMVTYPE); - pWmvDec->WmvComponent[i].nPortIndex = i; - pWmvDec->WmvComponent[i].eFormat = OMX_VIDEO_WMVFormat9; - } - - pOMXComponent->GetParameter = &SEC_MFC_WmvDec_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_WmvDec_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_WmvDec_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_WmvDec_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_WmvDec_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_WmvDec_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_WmvDec_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_WmvDec_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_WmvDec_bufferProcess; - pSECComponent->sec_checkInputFrame = &Check_Wmv_Frame; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_WMV_HANDLE *pWmvDec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pWmvDec = (SEC_WMV_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pWmvDec != NULL) { - SEC_OSAL_Free(pWmvDec); - pWmvDec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.h deleted file mode 100644 index 0634465..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/SEC_OMX_Wmvdec.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Wmvdec.h - * @brief - * @author HyeYeon Chung (hyeon.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.8.20 : Create - */ - -#ifndef SEC_OMX_WMV_DEC_COMPONENT -#define SEC_OMX_WMV_DEC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" - -#define BITMAPINFOHEADER_SIZE 40 -#define BITMAPINFOHEADER_ASFBINDING_SIZE 41 -#define COMPRESSION_POS 16 - -typedef enum WMV_FORMAT { - WMV_FORMAT_VC1, - WMV_FORMAT_WMV3, - WMV_FORMAT_UNKNOWN -} WMV_FORMAT; - -/* - * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file - */ -typedef struct _BitmapInfoHhr -{ - OMX_U32 BiSize; - OMX_U32 BiWidth; - OMX_U32 BiHeight; - OMX_U16 BiPlanes; - OMX_U16 BiBitCount; - OMX_U32 BiCompression; - OMX_U32 BiSizeImage; - OMX_U32 BiXPelsPerMeter; - OMX_U32 BiYPelsPerMeter; - OMX_U32 BiClrUsed; - OMX_U32 BiClrImportant; -} BitmapInfoHhr; - -typedef struct _SEC_MFC_WMV_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - OMX_PTR pMFCStreamBuffer; - OMX_PTR pMFCStreamPhyBuffer; - OMX_U32 indexTimestamp; - OMX_U32 outputIndexTimestamp; - OMX_BOOL bConfiguredMFC; - WMV_FORMAT wmvFormat; - OMX_S32 returnCodec; -} SEC_MFC_WMV_HANDLE; - -typedef struct _SEC_WMV_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_WMVTYPE WmvComponent[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_WMV_HANDLE hMFCWmvHandle; -} SEC_WMV_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); - OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.c deleted file mode 100644 index ce04f18..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author HyeYeon Chung (hyeon.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.8.20 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_WMV_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) -{ - FunctionIn(); - - if (ppSECComponent == NULL) { - goto EXIT; - } - - /* component 1 - video decoder WMV */ - SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_WMV_DEC); - SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_WMV_DEC_ROLE); - ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - return MAX_COMPONENT_NUM; -} \ No newline at end of file diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.h deleted file mode 100644 index adac586..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vc1/library_register.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author HyeYeon Chung (hyeon.chung.chung@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_WMV_DEC_REG -#define SEC_OMX_WMV_DEC_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 1 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* WMV */ -#define SEC_OMX_COMPONENT_WMV_DEC "OMX.SEC.WMV.Decoder" -#define SEC_OMX_COMPONENT_WMV_DEC_ROLE "video_decoder.wmv" - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); - -#ifdef __cplusplus -}; -#endif - -#endif \ No newline at end of file diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/Android.mk deleted file mode 100644 index 1ced382..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/Android.mk +++ /dev/null @@ -1,65 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Vp8dec.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.VP8.Decoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_ANB), true) -LOCAL_CFLAGS += -DUSE_ANB -ifeq ($(BOARD_USE_CSC_FIMC), true) -ifeq ($(BOARD_USE_V4L2_ION), false) -LOCAL_CFLAGS += -DUSE_CSC_FIMC -endif -endif - -ifeq ($(BOARD_USE_CSC_GSCALER), true) -LOCAL_CFLAGS += -DUSE_CSC_GSCALER -endif -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libfimc libhwconverter -endif - -ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) -LOCAL_SHARED_LIBRARIES += libexynosgscaler -endif - -#ifeq ($(BOARD_USE_V4L2_ION),true) -#LOCAL_SHARED_LIBRARIES += libion -#endif - -ifeq ($(BOARD_USES_MFC_FPS),true) -LOCAL_CFLAGS += -DCONFIG_MFC_FPS -endif - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) \ - $(BOARD_HAL_PATH)/include - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.c deleted file mode 100644 index 5ac91d5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.c +++ /dev/null @@ -1,1665 +0,0 @@ -/* - * - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Vp8dec.c - * @brief - * @author Satish Kumar Reddy (palli.satish@samsung.com) - * @version 1.1.0 - * @history - * 2011.11.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Vdec.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "library_register.h" -#include "SEC_OMX_Vp8dec.h" -#include "SsbSipMfcApi.h" - -#ifdef USE_ANB -#include "SEC_OSAL_Android.h" -#endif - -/* To use CSC_METHOD_PREFER_HW or CSC_METHOD_HW in SEC OMX, gralloc should allocate physical memory using FIMC */ -/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_VP8_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -#define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7 - -//#define FULL_FRAME_SEARCH /* Full frame search not support*/ - -static int Check_VP8_Frame(OMX_U8 *pInputStream, int buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) -{ - /* Uncompressed data Chunk comprises a common - (for key frames and interframes) 3-byte frame tag that - contains four fields - - 1-bit frame type (0 - key frame, 1 - inter frame) - - 3-bit version number (0 - 3 are defined as four different - profiles with different decoding complexity) - - 1-bit show_frame flag ( 0 - current frame not for display, - 1 - current frame is for dispaly) - - 19-bit field - size of the first data partition in bytes - - Key Frames : frame tag followed by 7 bytes of uncompressed - data - 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a) - Next 4-bytes: Width & height, Horizontal and vertical scale information - 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) - 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) - */ - int width, height; - int horizSscale, vertScale; - - FunctionIn(); - - *pbEndOfFrame = OMX_TRUE; - - /*Check for Key frame*/ - if (!(pInputStream[0] & 0x01)){ - /* Key Frame Start code*/ - if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { - SEC_OSAL_Log(SEC_LOG_ERROR, " VP8 Key Frame Start Code not Found"); - *pbEndOfFrame = OMX_FALSE; - } - SEC_OSAL_Log(SEC_LOG_TRACE, " VP8 Found Key Frame Start Code"); - width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff; - horizSscale = pInputStream[7] >> 6; - height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff; - vertScale = pInputStream[9] >> 6; - SEC_OSAL_Log(SEC_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale); - } - - FunctionOut(); - return buffSize; -} - -OMX_BOOL Check_VP8_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize) -{ - SEC_OSAL_Log(SEC_LOG_TRACE, "streamSize: %d",streamSize); - if (streamSize < 3) { - return OMX_FALSE; - } - - if (!(pInputStream[0] & 0x01)){ - /* Key Frame Start code*/ - if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { - SEC_OSAL_Log(SEC_LOG_ERROR, " VP8 Key Frame Start Code not Found"); - return OMX_FALSE; - } - SEC_OSAL_Log(SEC_LOG_TRACE, " VP8 Found Key Frame Start Code"); - } - - return OMX_TRUE; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE); - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE)) { - pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; - OMX_U32 portIndex = pPortDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - OMX_U32 width, height, size; - OMX_U32 realWidth, realHeight; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); - - realWidth = pSECPort->portDefinition.format.video.nFrameWidth; - realHeight = pSECPort->portDefinition.format.video.nFrameHeight; - width = ((realWidth + 15) & (~15)); - height = ((realHeight + 15) & (~15)); - size = (width * height * 3) / 2; - pSECPort->portDefinition.format.video.nStride = width; - pSECPort->portDefinition.format.video.nSliceHeight = height; - pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; - - if (portIndex == INPUT_PORT_INDEX) { - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; - pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; - pSECOutputPort->portDefinition.format.video.nStride = width; - pSECOutputPort->portDefinition.format.video.nSliceHeight = height; - - switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12Tiled: - pSECOutputPort->portDefinition.nBufferSize = - ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); - break; - default: - SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); - ret = OMX_ErrorUnsupportedSetting; - break; - } - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_GetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_SetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { - SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - *pIndexType = OMX_IndexVendorThumbnailMode; - - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_VP8_DEC_ROLE); - ret = OMX_ErrorNone; - } else { - ret = OMX_ErrorNoMore; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); - - if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_DEC); -#endif - pVp8Dec->hMFCVp8Handle.returnCodec = SsbSipMfcDecExe(pVp8Dec->hMFCVp8Handle.hMFCHandle, pVideoDec->NBDecThread.oneFrameSize); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_DEC); -#endif - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); - } - } - -EXIT: - SEC_OSAL_ThreadExit(NULL); - FunctionOut(); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - OMX_PTR hMFCHandle = NULL; - OMX_PTR pStreamBuffer = NULL; - OMX_PTR pStreamPhyBuffer = NULL; - CSC_METHOD csc_method = CSC_METHOD_SW; - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfInit(PERF_ID_DEC); - SEC_OSAL_PerfInit(PERF_ID_CSC); -#endif - - pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); - } else { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpenExt(&buf_type); - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVp8Dec->hMFCVp8Handle.hMFCHandle = hMFCHandle; - - /* Allocate decoder's input buffer */ - /* Get first input buffer */ - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[0].dataSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - /* Get second input buffer */ - pStreamBuffer = NULL; - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE / 2); - if (pStreamBuffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoDec->MFCDecInputBuffer[1].VirAddr = pStreamBuffer; - pVideoDec->MFCDecInputBuffer[1].PhyAddr = pStreamPhyBuffer; - pVideoDec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; - pVideoDec->MFCDecInputBuffer[1].dataSize = 0; - pVideoDec->indexInputBuffer = 0; - - pVideoDec->bFirstFrame = OMX_TRUE; - - pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - pVideoDec->NBDecThread.oneFrameSize = 0; - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, - SEC_MFC_DecodeThread, - pOMXComponent)) { - pVp8Dec->hMFCVp8Handle.returnCodec = MFC_RET_OK; - } -#endif - - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; - - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pVp8Dec->hMFCVp8Handle.indexTimestamp = 0; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0; - - pSECComponent->getAllDelayBuffer = OMX_FALSE; - -#ifdef USE_ANB -#if defined(USE_CSC_FIMC) || defined(USE_CSC_GSCALER) - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - csc_method = CSC_METHOD_PREFER_HW; - } -#endif -#endif - pVideoDec->csc_handle = csc_init(&csc_method); - pVideoDec->csc_set_format = OMX_FALSE; - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - OMX_PTR hMFCHandle = NULL; - - FunctionIn(); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfPrint("[DEC]", PERF_ID_DEC); - SEC_OSAL_PerfPrint("[CSC]", PERF_ID_CSC); -#endif - - pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; - - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = NULL; - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; - -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { - pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - SEC_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); - pVideoDec->NBDecThread.hNBDecodeThread = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.hDecFrameEnd = NULL; - } - - if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.hDecFrameStart = NULL; - } -#endif - - if (hMFCHandle != NULL) { - SsbSipMfcDecClose(hMFCHandle); - hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL; - } - - if (pVideoDec->csc_handle != NULL) { - csc_deinit(pVideoDec->csc_handle); - pVideoDec->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8_Decode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 setConfVal = 0; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize = 0; - OMX_U32 FrameBufferUVSize = 0; - OMX_BOOL outputDataValid = OMX_FALSE; - - FunctionIn(); - - if (pVp8Dec->hMFCVp8Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE eCodecType = VP8_DEC; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Default number in the driver is optimized */ - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - setConfVal = 0; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } else { - setConfVal = VP8_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); - - setConfVal = 8; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } - - SsbSipMfcDecSetInBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer, - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pVp8Dec->hMFCVp8Handle.returnCodec = SsbSipMfcDecInit(pVp8Dec->hMFCVp8Handle.hMFCHandle, eCodecType, oneFrameSize); - if (pVp8Dec->hMFCVp8Handle.returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); - SEC_OSAL_Log(SEC_LOG_ERROR, "set width height information : %d, %d", - pSECInputPort->portDefinition.format.video.nFrameWidth, - pSECInputPort->portDefinition.format.video.nFrameHeight); - SEC_OSAL_Log(SEC_LOG_ERROR, "mfc width height information : %d, %d", - imgResol.width, imgResol.height); - - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); - - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send Port Settings changed call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - - pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_TRUE; - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorInputDataDecodeYet; - goto EXIT; - } else { - ret = OMX_ErrorMFCInit; - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->nFlags; - - if ((pVp8Dec->hMFCVp8Handle.returnCodec == MFC_RET_OK) && - (pVideoDec->bFirstFrame == OMX_FALSE)) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - /* wait for mfc decode done */ - if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { - SEC_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); - pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - status = SsbSipMfcDecGetOutBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if ((SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - outputDataValid = OMX_TRUE; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - outputDataValid = OMX_FALSE; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - outputDataValid = OMX_FALSE; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && - ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { - pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - - outputDataValid = OMX_FALSE; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - } - - if (ret == OMX_ErrorInputDataDecodeYet) { - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; - //pInputData->dataLen = oneFrameSize; - //pInputData->remainDataLen = oneFrameSize; - } - - if ((Check_VP8_StartCode(pInputData->dataBuffer, oneFrameSize) == OMX_TRUE) && - ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { - if ((ret != OMX_ErrorInputDataDecodeYet) || (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pVp8Dec->hMFCVp8Handle.indexTimestamp)); - pVp8Dec->hMFCVp8Handle.indexTimestamp++; - pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - SsbSipMfcDecSetInBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer, - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, - pSECComponent->processData[INPUT_PORT_INDEX].allocSize); - - pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; - pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; - - /* mfc decode start */ - SEC_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); - pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; - pVp8Dec->hMFCVp8Handle.returnCodec = MFC_RET_OK; - - SEC_OSAL_SleepMillisec(0); - - pVideoDec->indexInputBuffer++; - pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; - - if ((pVideoDec->bFirstFrame == OMX_TRUE) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE) && - (outputDataValid == OMX_FALSE)) { - ret = OMX_ErrorInputDataDecodeYet; - } - - pVideoDec->bFirstFrame = OMX_FALSE; - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - } - - /** Fill Output Buffer **/ - if (outputDataValid == OMX_TRUE) { - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - unsigned int stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (width * height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 SP/P Output mode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - } else { - pOutputData->dataLen = 0; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_VP8_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 oneFrameSize = pInputData->dataLen; - SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 setConfVal = 0; - OMX_S32 returnCodec = 0; - int bufWidth = 0; - int bufHeight = 0; - OMX_U32 FrameBufferYSize; - OMX_U32 FrameBufferUVSize; - - FunctionIn(); - - if (pVp8Dec->hMFCVp8Handle.bConfiguredMFC == OMX_FALSE) { - SSBSIP_MFC_CODEC_TYPE eCodecType = VP8_DEC; - - if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - ret = OMX_ErrorNone; - goto EXIT; - } - - /* Default number in the driver is optimized */ - if (pVideoDec->bThumbnailMode == OMX_TRUE) { - setConfVal = 0; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); - } else { - setConfVal = VP8_DEC_NUM_OF_EXTRA_BUFFERS; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); - } - - returnCodec = SsbSipMfcDecInit(pVp8Dec->hMFCVp8Handle.hMFCHandle, eCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_IMG_RESOLUTION imgResol; - - SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); - SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", - pSECInputPort->portDefinition.format.video.nFrameWidth, - pSECInputPort->portDefinition.format.video.nFrameHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", - imgResol.width, imgResol.height); - - /** Update Frame Size **/ - if ((pSECInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || - (pSECInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { - SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); - /* change width and height information */ - pSECInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; - pSECInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; - pSECInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); - pSECInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); - - SEC_UpdateFrameSize(pOMXComponent); - - /** Send Port Settings changed call back **/ - (*(pSECComponent->pCallbacks->EventHandler)) - (pOMXComponent, - pSECComponent->callbackData, - OMX_EventPortSettingsChanged, /* The command was completed */ - OMX_DirOutput, /* This is the port index */ - 0, - NULL); - } - - pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_TRUE; - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorInputDataDecodeYet; - goto EXIT; - } else { - ret = OMX_ErrorMFCInit; - goto EXIT; - } - } - -#ifndef FULL_FRAME_SEARCH - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; -#endif - - if (Check_VP8_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { - pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pVp8Dec->hMFCVp8Handle.indexTimestamp)); - - returnCodec = SsbSipMfcDecExe(pVp8Dec->hMFCVp8Handle.hMFCHandle, oneFrameSize); - } else { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; - - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { - SSBSIP_MFC_DEC_OUTBUF_STATUS status; - OMX_S32 indexTimestamp = 0; - - status = SsbSipMfcDecGetOutBuf(pVp8Dec->hMFCVp8Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); - FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height)); - FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputInfo.img_width) * ALIGN_TO_32B(outputInfo.img_height/2)); - - if (status != MFC_GETOUTBUF_DISPLAY_ONLY) { - pVp8Dec->hMFCVp8Handle.indexTimestamp++; - pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; - } - - if ((SsbSipMfcDecGetConfig(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - /* For timestamp correction. if mfc support frametype detect */ - SEC_OSAL_Log(SEC_LOG_TRACE, "disp_pic_frame_type: %d", outputInfo.disp_pic_frame_type); -#ifdef NEED_TIMESTAMP_REORDER - if (outputInfo.disp_pic_frame_type == MFC_FRAME_TYPE_I_FRAME) { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; - } -#else - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); - } - - if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || - (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - /** Fill Output Buffer **/ - void *pOutputBuf = (void *)pOutputData->dataBuffer; - void *pSrcBuf[3] = {NULL, }; - void *pYUVBuf[3] = {NULL, }; - unsigned int csc_src_color_format, csc_dst_color_format; - CSC_METHOD csc_method = CSC_METHOD_SW; - unsigned int cacheable = 1; - - int frameSize = bufWidth * bufHeight; - int width = outputInfo.img_width; - int height = outputInfo.img_height; - int imageSize = outputInfo.img_width * outputInfo.img_height; - - pSrcBuf[0] = outputInfo.YVirAddr; - pSrcBuf[1] = outputInfo.CVirAddr; - - pYUVBuf[0] = (unsigned char *)pOutputBuf; - pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; - pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; - pOutputData->dataLen = (imageSize * 3) / 2; - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - unsigned int stride; - SEC_OSAL_LockANB(pOutputData->dataBuffer, width, height, pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); - width = stride; - pOutputData->dataLen = sizeof(void *); - } -#endif - if ((pVideoDec->bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { - /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pYUVBuf[0], &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); - pOutputData->dataLen = (width * height * 3) / 2; - } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 SP/P Output mode"); -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStart(PERF_ID_CSC); -#endif - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12Tiled: - SEC_OSAL_Memcpy(pOutputBuf, outputInfo.YVirAddr, FrameBufferYSize); - SEC_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputInfo.CVirAddr, FrameBufferUVSize); - pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420Planar: - default: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - break; - } - - csc_get_method(pVideoDec->csc_handle, &csc_method); -#ifdef USE_CSC_FIMC - if ((pSECOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { - SEC_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); - pSrcBuf[0] = outputInfo.YPhyAddr; - pSrcBuf[1] = outputInfo.CPhyAddr; - } -#endif - if (pVideoDec->csc_set_format == OMX_FALSE) { - csc_set_src_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoDec->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - pVideoDec->csc_set_format = OMX_TRUE; - } - csc_set_src_buffer( - pVideoDec->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoDec->csc_handle, - pYUVBuf[0], /* y addr */ - pYUVBuf[1], /* u addr or uv addr */ - pYUVBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoDec->csc_handle); - -#ifdef CONFIG_MFC_FPS - SEC_OSAL_PerfStop(PERF_ID_CSC); -#endif - } - -#ifdef USE_ANB - if (pSECOutputPort->bIsANBEnabled == OMX_TRUE) { - SEC_OSAL_UnlockANB(pOutputData->dataBuffer); - } -#endif - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; - pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; - } - if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; - - if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) - ret = OMX_ErrorInputDataDecodeYet; - - if (status == MFC_GETOUTBUF_DECODING_ONLY) { - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE))) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else { - ret = OMX_ErrorNone; - } - goto EXIT; - } - -#ifdef FULL_FRAME_SEARCH - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && - (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - pInputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else -#endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataDecodeYet; - } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - ret = OMX_ErrorNone; - } - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE) || - (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { - pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; - pSECComponent->getAllDelayBuffer = OMX_FALSE; - } - pOutputData->dataLen = 0; - - /* ret = OMX_ErrorUndefined; */ - ret = OMX_ErrorNone; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Decode */ -OMX_ERRORTYPE SEC_MFC_VP8Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_VP8DEC_HANDLE *pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_BOOL endOfFrame = OMX_FALSE; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || - (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { - ret = OMX_ErrorNone; - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - ret = OMX_ErrorNone; - goto EXIT; - } - -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_VP8_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_VP8_Decode_Block(pOMXComponent, pInputData, pOutputData); -#endif - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataDecodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->previousDataLen = pInputData->dataLen; - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - //OMX_BOOL bFlashPlayerMode = OMX_FALSE; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_VP8_DEC, componentName) != 0) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_DEC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pVp8Dec = SEC_OSAL_Malloc(sizeof(SEC_VP8DEC_HANDLE)); - if (pVp8Dec == NULL) { - SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pVp8Dec, 0, sizeof(SEC_VP8DEC_HANDLE)); - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec; - - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_VP8_DEC); - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /*for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); - pH264Dec->AVCComponent[i].nPortIndex = i; - pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; - pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; - }*/ - - pOMXComponent->GetParameter = &SEC_MFC_VP8Dec_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_VP8Dec_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_VP8Dec_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_VP8Dec_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_VP8Dec_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_VP8Dec_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_VP8Dec_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_VP8Dec_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_VP8Dec_bufferProcess; - pSECComponent->sec_checkInputFrame = &Check_VP8_Frame; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_VP8DEC_HANDLE *pVp8Dec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pVp8Dec = (SEC_VP8DEC_HANDLE *)((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pVp8Dec != NULL) { - SEC_OSAL_Free(pVp8Dec); - pVp8Dec = ((SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.h deleted file mode 100644 index 40ce20c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/SEC_OMX_Vp8dec.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Vp8dec.h - * @brief - * @author Satish Kumar Reddy (palli.satish@samsung.com) - * @version 1.1.0 - * @history - * 2011.10.10 : Create - */ - -#ifndef SEC_OMX_VP8_DEC_COMPONENT -#define SEC_OMX_VP8_DEC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "OMX_Video.h" - - -typedef struct _SEC_MFC_VP8DEC_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - OMX_PTR pMFCStreamBuffer; - OMX_PTR pMFCStreamPhyBuffer; - OMX_U32 indexTimestamp; - OMX_U32 outputIndexTimestamp; - OMX_BOOL bConfiguredMFC; - OMX_S32 returnCodec; -} SEC_MFC_VP8DEC_HANDLE; - -typedef struct _SEC_VP8DEC_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_VP8DEC_HANDLE hMFCVp8Handle; -} SEC_VP8DEC_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.c deleted file mode 100644 index 13f7f4a..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author Satish Kumar Reddy (palli.satish@samsung.com) - * @version 1.1.0 - * @history - * 2011.11.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_VP8_DEC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) -{ - FunctionIn(); - - if (ppSECComponent == NULL) - goto EXIT; - - /* component 1 - video decoder VP8 */ - SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_VP8_DEC); - SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_VP8_DEC_ROLE); - ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.h deleted file mode 100644 index 5e17150..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/dec/vp8/library_register.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author Satish Kumar Reddy (palli.satish@samsung.com) - * @version 1.1.0 - * @history - * 2011.11.15 : Create - */ - -#ifndef SEC_OMX_VP8_DEC_REG -#define SEC_OMX_VP8_DEC_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 1 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* VP8 */ -#define SEC_OMX_COMPONENT_VP8_DEC "OMX.SEC.VP8.Decoder" -#define SEC_OMX_COMPONENT_VP8_DEC_ROLE "video_decoder.vpx" - - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/enc/Android.mk deleted file mode 100644 index 1c842f2..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - SEC_OMX_Venc.c - -LOCAL_MODULE := libSEC_OMX_Venc -LOCAL_ARM_MODE := arm -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) - -ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) -LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE -endif - -ifeq ($(BOARD_USE_STOREMETADATA), true) -LOCAL_CFLAGS += -DUSE_STOREMETADATA -endif - -ifeq ($(BOARD_USE_V4L2), true) -ifeq ($(TARGET_SOC), exynos5250) -LOCAL_CFLAGS += -DUSE_SLICE_OUTPUT_MODE -endif -else -LOCAL_CFLAGS += -DUSE_SLICE_OUTPUT_MODE -endif - -LOCAL_SHARED_LIBRARIES := libcsc - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.c b/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.c deleted file mode 100644 index e4b6cc2..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.c +++ /dev/null @@ -1,1856 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Venc.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include "SEC_OMX_Macros.h" -#include "SEC_OSAL_Event.h" -#include "SEC_OMX_Venc.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_ETC.h" -#include "csc.h" - -#ifdef USE_STOREMETADATA -#include "SEC_OSAL_Android.h" -#endif - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_VIDEO_ENC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) -{ - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - if ((secOutputPort->portDefinition.format.video.nFrameWidth != - secInputPort->portDefinition.format.video.nFrameWidth) || - (secOutputPort->portDefinition.format.video.nFrameHeight != - secInputPort->portDefinition.format.video.nFrameHeight)) { - OMX_U32 width = 0, height = 0; - - secOutputPort->portDefinition.format.video.nFrameWidth = - secInputPort->portDefinition.format.video.nFrameWidth; - secOutputPort->portDefinition.format.video.nFrameHeight = - secInputPort->portDefinition.format.video.nFrameHeight; - width = secOutputPort->portDefinition.format.video.nStride = - secInputPort->portDefinition.format.video.nStride; - height = secOutputPort->portDefinition.format.video.nSliceHeight = - secInputPort->portDefinition.format.video.nSliceHeight; - - if (width && height) - secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - } - - return ; -} - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - if (pSECPort->portState != OMX_StateIdle) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = pBuffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBufferHdr = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - if (nPortIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } -/* - if (pSECPort->portState != OMX_StateIdle ) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } -*/ - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); - if (temp_buffer == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - SEC_OSAL_Free(temp_buffer); - temp_buffer = NULL; - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = temp_buffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBuffer = temp_bufferHeader; - ret = OMX_ErrorNone; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - SEC_OSAL_Free(temp_buffer); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECPort = &pSECComponent->pSECPort[nPortIndex]; - - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { - (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, - pSECComponent->callbackData, - (OMX_U32)OMX_EventError, - (OMX_U32)OMX_ErrorPortUnpopulated, - nPortIndex, NULL); - } - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { - if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { - if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { - SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); - pSECPort->bufferHeader[i]->pBuffer = NULL; - pBufferHdr->pBuffer = NULL; - } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { - ; /* None*/ - } - pSECPort->assignedBufferNum--; - if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { - SEC_OSAL_Free(pSECPort->bufferHeader[i]); - pSECPort->bufferHeader[i] = NULL; - pBufferHdr = NULL; - } - pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; - ret = OMX_ErrorNone; - goto EXIT; - } - } - } - -EXIT: - if (ret == OMX_ErrorNone) { - if (pSECPort->assignedBufferNum == 0) { - SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - pSECPort->portDefinition.bPopulated = OMX_FALSE; - } - } - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - OMX_PARAM_PORTDEFINITIONTYPE portDefinition; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT* pSECPort = NULL; - OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; - OMX_U8 *temp_buffer = NULL; - OMX_U32 bufferSize = 0; - OMX_PARAM_PORTDEFINITIONTYPE portDefinition; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - ret = OMX_ErrorTunnelingUnsupported; -EXIT: - return ret; -} - -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - if ((pSECComponent->currentState == OMX_StateExecuting) && - (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) - return OMX_TRUE; - else - return OMX_FALSE; -} - -static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { - bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; - bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; - secOMXInputPort->markType.hMarkTargetComponent = NULL; - secOMXInputPort->markType.pMarkData = NULL; - } - - if (bufferHeader->hMarkTargetComponent != NULL) { - if (bufferHeader->hMarkTargetComponent == pOMXComponent) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventMark, - 0, 0, bufferHeader->pMarkData); - } else { - pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; - pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; - } - } - - if (CHECK_PORT_TUNNELED(secOMXInputPort)) { - OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); - } else { - bufferHeader->nFilledLen = 0; - pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE* message = NULL; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; - dataBuffer->dataValid = OMX_TRUE; - dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; - dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; - SEC_OSAL_Free(message); - } - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; -} - -static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; - - FunctionIn(); - - if (bufferHeader != NULL) { - bufferHeader->nFilledLen = dataBuffer->remainDataLen; - bufferHeader->nOffset = 0; - bufferHeader->nFlags = dataBuffer->nFlags; - bufferHeader->nTimeStamp = dataBuffer->timeStamp; - - if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { - bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; - bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; - pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; - pSECComponent->propagateMarkType.pMarkData = NULL; - } - - if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { - pSECComponent->pCallbacks->EventHandler(pOMXComponent, - pSECComponent->callbackData, - OMX_EventBufferFlag, - OUTPUT_PORT_INDEX, - bufferHeader->nFlags, NULL); - } - - if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { - OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); - } else { - pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); - } - } - - if ((pSECComponent->currentState == OMX_StatePause) && - ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - /* reset dataBuffer */ - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_DATABUFFER *dataBuffer = NULL; - SEC_OMX_MESSAGE *message = NULL; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - FunctionIn(); - - pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - - if (pSECComponent->currentState != OMX_StateExecuting) { - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if (dataBuffer->dataValid != OMX_TRUE) { - message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); - if (message == NULL) { - ret = OMX_ErrorUndefined; - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - goto EXIT; - } - - dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); - dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; - dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; - dataBuffer->remainDataLen = dataBuffer->dataLen; - dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; - dataBuffer->dataValid =OMX_TRUE; - /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ - /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ - SEC_OSAL_Free(message); - } - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = OMX_ErrorNone; - } -EXIT: - FunctionOut(); - - return ret; - -} - -static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - - dataBuffer->dataValid = OMX_FALSE; - dataBuffer->dataLen = 0; - dataBuffer->remainDataLen = 0; - dataBuffer->usedDataLen = 0; - dataBuffer->bufferHeader = NULL; - dataBuffer->nFlags = 0; - dataBuffer->timeStamp = 0; - - return ret; -} - -static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ - /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ - /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ - SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; - - processData->dataLen = 0; - processData->remainDataLen = 0; - processData->usedDataLen = 0; - processData->nFlags = 0; - processData->timeStamp = 0; - - return ret; -} - -OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - OMX_BYTE checkInputStream = NULL; - OMX_U32 checkInputStreamLen = 0; - OMX_U32 checkedSize = 0; - OMX_BOOL flagEOS = OMX_FALSE; - OMX_BOOL flagEOF = OMX_FALSE; - OMX_BOOL previousFrameEOF = OMX_FALSE; - - if (inputUseBuffer->dataValid == OMX_TRUE) { - checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; - checkInputStreamLen = inputUseBuffer->remainDataLen; - - if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) { - pSECComponent->bUseFlagEOF = OMX_TRUE; - } - - if (inputData->dataLen == 0) { - previousFrameEOF = OMX_TRUE; - } else { - previousFrameEOF = OMX_FALSE; - } - if (pSECComponent->bUseFlagEOF == OMX_TRUE) { - flagEOF = OMX_TRUE; - checkedSize = checkInputStreamLen; - if (checkedSize == 0) { - SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - int width = pSECPort->portDefinition.format.video.nFrameWidth; - int height = pSECPort->portDefinition.format.video.nFrameHeight; - inputUseBuffer->remainDataLen = inputUseBuffer->dataLen = (width * height * 3) / 2; - checkedSize = checkInputStreamLen = inputUseBuffer->remainDataLen; - inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS; - } - if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) { - flagEOS = OMX_TRUE; - } - } else { - SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - int width = pSECPort->portDefinition.format.video.nFrameWidth; - int height = pSECPort->portDefinition.format.video.nFrameHeight; - unsigned int oneFrameSize = 0; - - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12Tiled: - case OMX_SEC_COLOR_FormatNV21Linear: - oneFrameSize = (width * height * 3) / 2; - break; - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - oneFrameSize = ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048); - break; - default: - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_Preprocessor_InputData: eColorFormat is wrong"); - break; - } - - if (previousFrameEOF == OMX_TRUE) { - if (checkInputStreamLen >= oneFrameSize) { - checkedSize = oneFrameSize; - flagEOF = OMX_TRUE; - } else { - flagEOF = OMX_FALSE; - } - } else { - if (checkInputStreamLen >= (oneFrameSize - inputData->dataLen)) { - checkedSize = oneFrameSize - inputData->dataLen; - flagEOF = OMX_TRUE; - } else { - flagEOF = OMX_FALSE; - } - } - - if ((flagEOF == OMX_FALSE) && (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { - flagEOF = OMX_TRUE; - flagEOS = OMX_TRUE; - } - } - - if (flagEOF == OMX_TRUE) { - copySize = checkedSize; - SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); - } else { - copySize = checkInputStreamLen; - SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); - } - - if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) - pSECComponent->bSaveFlagEOS = OMX_TRUE; - - if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { - SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - if ((pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12TPhysicalAddress) && - (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LPhysicalAddress) && - (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LVirtualAddress) && - (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV21LPhysicalAddress)) { - if (flagEOF == OMX_TRUE) { - OMX_U32 width, height; - unsigned int csc_src_color_format, csc_dst_color_format; - unsigned int cacheable = 1; - unsigned char *pSrcBuf[3] = {NULL, }; - unsigned char *pDstBuf[3] = {NULL, }; - OMX_PTR ppBuf[3]; - - width = pSECPort->portDefinition.format.video.nFrameWidth; - height = pSECPort->portDefinition.format.video.nFrameHeight; - - pDstBuf[0] = (unsigned char *)pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pDstBuf[1] = (unsigned char *)pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - - SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->MFCEncInputBuffer[%d].YVirAddr : 0x%x", pVideoEnc->indexInputBuffer, pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr); - SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->MFCEncInputBuffer[%d].CVirAddr : 0x%x", pVideoEnc->indexInputBuffer, pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr); - - SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Ysize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); - SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Csize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); - - if (pSECPort->bStoreMetaData == OMX_FALSE) { - pSrcBuf[0] = checkInputStream; - pSrcBuf[1] = checkInputStream + (width * height); - pSrcBuf[2] = checkInputStream + (((width * height) * 5) / 4); - - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - /* YUV420Planar case it needed changed interleave UV plane (MFC spec.)*/ - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_SEC_COLOR_FormatNV12Tiled: - case OMX_SEC_COLOR_FormatNV21Linear: - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - break; - default: - break; - } - } -#ifdef USE_METADATABUFFERTYPE - else { - if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { - OMX_PTR pOutBuffer; - csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888); - csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); - - SEC_OSAL_GetInfoFromMetaData(inputData, ppBuf); - SEC_OSAL_LockANBHandle((OMX_U32)ppBuf[0], width, height, OMX_COLOR_FormatAndroidOpaque, &pOutBuffer); - pSrcBuf[0] = (unsigned char *)pOutBuffer; - pSrcBuf[1] = NULL; - pSrcBuf[2] = NULL; - } - } -#endif - - csc_set_src_format( - pVideoEnc->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_src_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_dst_format( - pVideoEnc->csc_handle, /* handle */ - width, /* width */ - height, /* height */ - 0, /* crop_left */ - 0, /* crop_right */ - width, /* crop_width */ - height, /* crop_height */ - csc_dst_color_format, /* color_format */ - cacheable); /* cacheable */ - csc_set_src_buffer( - pVideoEnc->csc_handle, /* handle */ - pSrcBuf[0], /* y addr */ - pSrcBuf[1], /* u addr or uv addr */ - pSrcBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_set_dst_buffer( - pVideoEnc->csc_handle, /* handle */ - pDstBuf[0], /* y addr */ - pDstBuf[1], /* u addr or uv addr */ - pDstBuf[2], /* v addr or none */ - 0); /* ion fd */ - csc_convert(pVideoEnc->csc_handle); - -#ifdef USE_METADATABUFFERTYPE - if (pSECPort->bStoreMetaData == OMX_TRUE) { - SEC_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]); - } -#endif - } - } - - inputUseBuffer->dataLen -= copySize; /* ???????????? do not need ?????????????? */ - inputUseBuffer->remainDataLen -= copySize; - inputUseBuffer->usedDataLen += copySize; - - inputData->dataLen += copySize; - inputData->remainDataLen += copySize; - - if (previousFrameEOF == OMX_TRUE) { - inputData->timeStamp = inputUseBuffer->timeStamp; - inputData->nFlags = inputUseBuffer->nFlags; - } - - if (pSECComponent->bUseFlagEOF == OMX_TRUE) { - if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } - } else { - if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { - inputData->nFlags |= OMX_BUFFERFLAG_EOS; - flagEOF = OMX_TRUE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - } else { - inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); - } - } - } else { - /*????????????????????????????????? Error ?????????????????????????????????*/ - SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); - flagEOF = OMX_FALSE; - } - - if (inputUseBuffer->remainDataLen == 0) { - if(flagEOF == OMX_FALSE) - SEC_InputBufferReturn(pOMXComponent); - } else { - inputUseBuffer->dataValid = OMX_TRUE; - } - } - - if (flagEOF == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; - pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; - pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - } - - ret = OMX_TRUE; - } else { - ret = OMX_FALSE; - } - return ret; -} - -OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_BOOL ret = OMX_FALSE; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - if (outputUseBuffer->dataValid == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { - if (pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp){ - pSECComponent->checkTimeStamp.startTimeStamp = -19761123; - pSECComponent->checkTimeStamp.nStartFlags = 0x0; - pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; - pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; - } else { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - - ret = OMX_TRUE; - goto EXIT; - } - } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - - ret = OMX_TRUE; - goto EXIT; - } - - if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { - copySize = outputData->remainDataLen; - if (copySize > 0) - SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), - (outputData->dataBuffer + outputData->usedDataLen), - copySize); - - outputUseBuffer->dataLen += copySize; - outputUseBuffer->remainDataLen += copySize; - outputUseBuffer->nFlags = outputData->nFlags; - outputUseBuffer->timeStamp = outputData->timeStamp; - - ret = OMX_TRUE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - - if ((outputUseBuffer->remainDataLen > 0) || - (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) - SEC_OutputBufferReturn(pOMXComponent); - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than encoded data size Out Length"); - - ret = OMX_FALSE; - - /* reset outputData */ - SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); - } - } else { - ret = OMX_FALSE; - } - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; - SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; - SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; - SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; - OMX_U32 copySize = 0; - - pSECComponent->remainOutputData = OMX_FALSE; - pSECComponent->reInputData = OMX_FALSE; - - FunctionIn(); - - while (!pSECComponent->bExitBufferProcessThread) { - SEC_OSAL_SleepMillisec(0); - - if (((pSECComponent->currentState == OMX_StatePause) || - (pSECComponent->currentState == OMX_StateIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || - (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && - (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& - ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { - SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); - SEC_OSAL_SignalReset(pSECComponent->pauseEvent); - } - - while (SEC_Check_BufferProcess_State(pSECComponent) && !pSECComponent->bExitBufferProcessThread) { - SEC_OSAL_SleepMillisec(0); - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - if ((outputUseBuffer->dataValid != OMX_TRUE) && - (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - ret = SEC_OutputBufferGetQueue(pSECComponent); - if ((ret == OMX_ErrorUndefined) || - (secInputPort->portState != OMX_StateIdle) || - (secOutputPort->portState != OMX_StateIdle)) { - break; - } - } else { - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - - if (pSECComponent->remainOutputData == OMX_FALSE) { - if (pSECComponent->reInputData == OMX_FALSE) { - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && - (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - ret = SEC_InputBufferGetQueue(pSECComponent); - break; - } - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - } - - SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); - - if (inputUseBuffer->remainDataLen == 0) - SEC_InputBufferReturn(pOMXComponent); - else - inputUseBuffer->dataValid = OMX_TRUE; - - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); - - if (ret == OMX_ErrorInputDataEncodeYet) - pSECComponent->reInputData = OMX_TRUE; - else - pSECComponent->reInputData = OMX_FALSE; - } - - SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); - - if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) - pSECComponent->remainOutputData = OMX_TRUE; - else - pSECComponent->remainOutputData = OMX_FALSE; - - SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); - } - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - portParam->nPorts = pSECComponent->portParam.nPorts; - portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - - if (portIndex == INPUT_PORT_INDEX) { - supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - switch (index) { - case supportFormat_0: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_1: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_2: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12LPhysicalAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_3: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_4: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_5: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12LVirtualAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_6: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV21LPhysicalAddress; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_7: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV21Linear; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - case supportFormat_8: - portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_COLOR_FormatAndroidOpaque; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - break; - } - } else if (portIndex == OUTPUT_PORT_INDEX) { - supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; - if (index > supportFormatNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - portDefinition = &pSECPort->portDefinition; - - portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; - portFormat->eColorFormat = portDefinition->format.video.eColorFormat; - portFormat->xFramerate = portDefinition->format.video.xFramerate; - } - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; - OMX_U32 portIndex = videoRateControl->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - videoRateControl->eControlRate = pVideoEnc->eControlRate[portIndex]; - videoRateControl->nTargetBitrate = portDefinition->format.video.nBitrate; - } - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamVideoQuantization: - { - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = videoQuantizationControl->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - videoQuantizationControl->nQpI = pVideoEnc->quantization.nQpI; - videoQuantizationControl->nQpP = pVideoEnc->quantization.nQpP; - videoQuantizationControl->nQpB = pVideoEnc->quantization.nQpB; - } - ret = OMX_ErrorNone; - - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize); - -#ifdef USE_STOREMETADATA - if ((portIndex == 0) && - (pSECPort->bStoreMetaData == OMX_TRUE) && - (pSECPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12LVirtualAddress)) { - portDefinition->nBufferSize = MAX_INPUT_METADATA_BUFFER_SIZE; - } -#endif - } - break; - default: - { - ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} -OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = portFormat->nPortIndex; - OMX_U32 index = portFormat->nIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - OMX_U32 supportFormatNum = 0; - - ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((portIndex >= pSECComponent->portParam.nPorts)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - portDefinition->format.video.eColorFormat = portFormat->eColorFormat; - portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; - portDefinition->format.video.xFramerate = portFormat->xFramerate; - } - } - break; - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; - OMX_U32 portIndex = videoRateControl->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - pVideoEnc->eControlRate[portIndex] = videoRateControl->eControlRate; - portDefinition->format.video.nBitrate = videoRateControl->nTargetBitrate; - } - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamVideoQuantization: - { - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = videoQuantizationControl->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pSECPort = &pSECComponent->pSECPort[portIndex]; - portDefinition = &pSECPort->portDefinition; - - pVideoEnc->quantization.nQpI = videoQuantizationControl->nQpI; - pVideoEnc->quantization.nQpP = videoQuantizationControl->nQpP; - pVideoEnc->quantization.nQpB = videoQuantizationControl->nQpB; - } - ret = OMX_ErrorNone; - } - break; - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; - OMX_U32 portIndex = pPortDefinition->nPortIndex; - SEC_OMX_BASEPORT *pSECPort; - OMX_U32 width, height, size; - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - } - if(pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); - if (portIndex == INPUT_PORT_INDEX) { - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - SEC_UpdateFrameSize(pOMXComponent); - SEC_OSAL_Log(SEC_LOG_TRACE, "pSECOutputPort->portDefinition.nBufferSize: %d", - pSECOutputPort->portDefinition.nBufferSize); - } - ret = OMX_ErrorNone; - } - break; -#ifdef USE_STOREMETADATA - case OMX_IndexParamStoreMetaDataBuffer: - { - ret = SEC_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure); - } - break; -#endif - default: - { - ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; - OMX_U32 portIndex = pEncodeBitrate->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - pEncodeBitrate->nEncodeBitrate = pSECPort->portDefinition.format.video.nBitrate; - } - } - break; - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; - OMX_U32 portIndex = pFramerate->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - pFramerate->xEncodeFramerate = pSECPort->portDefinition.format.video.xFramerate; - } - } - break; - default: - ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) - { - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; - OMX_U32 portIndex = pEncodeBitrate->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - pSECPort->portDefinition.format.video.nBitrate = pEncodeBitrate->nEncodeBitrate; - } - } - break; - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; - OMX_U32 portIndex = pFramerate->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pSECPort = &pSECComponent->pSECPort[portIndex]; - pSECPort->portDefinition.format.video.xFramerate = pFramerate->xEncodeFramerate; - } - } - break; - case OMX_IndexConfigVideoIntraVOPRefresh: - { - OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure; - SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - OMX_U32 portIndex = pIntraRefreshVOP->nPortIndex; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pVEncBase->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP; - } - } - break; - default: - ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - -#ifdef USE_STOREMETADATA - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) { - *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer; - } else { - ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); - } -#else - ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); -#endif - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = SEC_OMX_Port_Constructor(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pVideoEnc = SEC_OSAL_Malloc(sizeof(SEC_OMX_VIDEOENC_COMPONENT)); - if (pVideoEnc == NULL) { - SEC_OMX_BaseComponent_Destructor(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - - SEC_OSAL_Memset(pVideoEnc, 0, sizeof(SEC_OMX_VIDEOENC_COMPONENT)); - pSECComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; - - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - pVideoEnc->configChange = OMX_FALSE; - pVideoEnc->quantization.nQpI = 20; - pVideoEnc->quantization.nQpP = 20; - pVideoEnc->quantization.nQpB = 20; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = 0; - pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; - - pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - pSECPort->portDefinition.format.video.nFrameWidth = 0; - pSECPort->portDefinition.format.video.nFrameHeight= 0; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate = (15 << 16); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.format.video.pNativeWindow = NULL; - pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; - - pSECPort->bStoreMetaData = OMX_FALSE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; - - pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - pSECPort->portDefinition.format.video.nFrameWidth = 0; - pSECPort->portDefinition.format.video.nFrameHeight= 0; - pSECPort->portDefinition.format.video.nStride = 0; - pSECPort->portDefinition.format.video.nSliceHeight = 0; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate = (15 << 16); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.format.video.pNativeWindow = NULL; - pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; - - pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; - pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; - pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; - pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; - - pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; - pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; - pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; - pSECComponent->sec_BufferReset = &SEC_BufferReset; - pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; - pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - int i = 0; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OSAL_Free(pVideoEnc); - pSECComponent->hComponentHandle = pVideoEnc = NULL; - - for(i = 0; i < ALL_PORT_NUM; i++) { - pSECPort = &pSECComponent->pSECPort[i]; - SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); - pSECPort->portDefinition.format.video.cMIMEType = NULL; - } - - ret = SEC_OMX_Port_Destructor(pOMXComponent); - - ret = SEC_OMX_BaseComponent_Destructor(hComponent); - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.h b/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.h deleted file mode 100644 index 6225fd3..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/SEC_OMX_Venc.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Venc.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_VIDEO_ENCODE -#define SEC_OMX_VIDEO_ENCODE - -#include "OMX_Component.h" -#include "SEC_OMX_Def.h" -#include "SEC_OSAL_Queue.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" - -#define MAX_VIDEO_INPUTBUFFER_NUM 5 -#define MAX_VIDEO_OUTPUTBUFFER_NUM 4 - -#define DEFAULT_FRAME_WIDTH 176 -#define DEFAULT_FRAME_HEIGHT 144 - -#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT)) \ - + ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT / 2)) - /* (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 */ -#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE DEFAULT_VIDEO_INPUT_BUFFER_SIZE - -#define MFC_INPUT_BUFFER_NUM_MAX 2 - -#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 9 -#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 - -#ifdef USE_STOREMETADATA -// The largest metadata buffer size advertised -// when metadata buffer mode is used for video encoding -#define MAX_INPUT_METADATA_BUFFER_SIZE (64) -#endif - -typedef struct -{ - void *pAddrY; - void *pAddrC; -} MFC_ENC_ADDR_INFO; - -typedef struct _SEC_MFC_NBENC_THREAD -{ - OMX_HANDLETYPE hNBEncodeThread; - OMX_HANDLETYPE hEncFrameStart; - OMX_HANDLETYPE hEncFrameEnd; - OMX_BOOL bExitEncodeThread; - OMX_BOOL bEncoderRun; -} SEC_MFC_NBENC_THREAD; - -typedef struct _MFC_ENC_INPUT_BUFFER -{ - void *YPhyAddr; // physical address of Y - void *CPhyAddr; // physical address of CbCr - void *YVirAddr; // virtual address of Y - void *CVirAddr; // virtual address of CbCr - int YBufferSize; // input buffer alloc size of Y - int CBufferSize; // input buffer alloc size of CbCr - int YDataSize; // input size of Y data - int CDataSize; // input size of CbCr data -} MFC_ENC_INPUT_BUFFER; - -typedef struct _SEC_OMX_VIDEOENC_COMPONENT -{ - OMX_HANDLETYPE hCodecHandle; - SEC_MFC_NBENC_THREAD NBEncThread; - - OMX_BOOL configChange; - OMX_BOOL IntraRefreshVOP; - OMX_VIDEO_CONTROLRATETYPE eControlRate[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_QUANTIZATIONTYPE quantization; - OMX_BOOL bFirstFrame; - MFC_ENC_INPUT_BUFFER MFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; - OMX_U32 indexInputBuffer; - - /* CSC handle */ - OMX_PTR csc_handle; -} SEC_OMX_VIDEOENC_COMPONENT; - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OMX_UseBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8 *pBuffer); -OMX_ERRORTYPE SEC_OMX_AllocateBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes); -OMX_ERRORTYPE SEC_OMX_FreeBuffer( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); -OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( - SEC_OMX_BASEPORT *pOMXBasePort, - OMX_U32 nPortIndex); -OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); -OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure); -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_VideoEncodeSetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure); -OMX_ERRORTYPE SEC_OMX_VideoEncodeGetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType); -OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); -OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent); -inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/Android.mk deleted file mode 100644 index d8c7b06..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_H264enc.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.AVC.Encoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) -LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/enc \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.c b/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.c deleted file mode 100644 index df4241b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.c +++ /dev/null @@ -1,1605 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_H264enc.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Venc.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_Android.h" -#include "library_register.h" -#include "SEC_OMX_H264enc.h" -#include "SsbSipMfcApi.h" -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_H264_ENC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -/* H.264 Encoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, - - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, - - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; - - -OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile) -{ - OMX_U32 ret = 0; //default OMX_VIDEO_AVCProfileMain - - if (profile == OMX_VIDEO_AVCProfileMain) - ret = 0; - else if (profile == OMX_VIDEO_AVCProfileHigh) - ret = 1; - else if (profile == OMX_VIDEO_AVCProfileBaseline) - ret = 2; - - return ret; -} - -OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level) -{ - OMX_U32 ret = 40; //default OMX_VIDEO_AVCLevel4 - - if (level == OMX_VIDEO_AVCLevel1) - ret = 10; - else if (level == OMX_VIDEO_AVCLevel1b) - ret = 9; - else if (level == OMX_VIDEO_AVCLevel11) - ret = 11; - else if (level == OMX_VIDEO_AVCLevel12) - ret = 12; - else if (level == OMX_VIDEO_AVCLevel13) - ret = 13; - else if (level == OMX_VIDEO_AVCLevel2) - ret = 20; - else if (level == OMX_VIDEO_AVCLevel21) - ret = 21; - else if (level == OMX_VIDEO_AVCLevel22) - ret = 22; - else if (level == OMX_VIDEO_AVCLevel3) - ret = 30; - else if (level == OMX_VIDEO_AVCLevel31) - ret = 31; - else if (level == OMX_VIDEO_AVCLevel32) - ret = 32; - else if (level == OMX_VIDEO_AVCLevel4) - ret = 40; - - return ret; -} - -OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size) -{ - OMX_U32 i; - - for (i = 0; i < size - 3; i++) { - if ((pBuffer[i] == 0x00) && - (pBuffer[i + 1] == 0x00) && - (pBuffer[i + 2] == 0x00) && - (pBuffer[i + 3] == 0x01)) - return (pBuffer + i); - } - - return NULL; -} - -void H264PrintParams(SSBSIP_MFC_ENC_H264_PARAM *h264Arg) -{ - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", h264Arg->SourceWidth); - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", h264Arg->SourceHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", h264Arg->ProfileIDC); - SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", h264Arg->LevelIDC); - SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", h264Arg->IDRPeriod); - SEC_OSAL_Log(SEC_LOG_TRACE, "NumberReferenceFrames : %d\n", h264Arg->NumberReferenceFrames); - SEC_OSAL_Log(SEC_LOG_TRACE, "NumberRefForPframes : %d\n", h264Arg->NumberRefForPframes); - SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", h264Arg->SliceMode); - SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", h264Arg->SliceArgument); -#ifdef USE_SLICE_OUTPUT_MODE - SEC_OSAL_Log(SEC_LOG_TRACE, "OutputMode : %d\n", h264Arg->OutputMode); -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", h264Arg->NumberBFrames); - SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterDisable : %d\n", h264Arg->LoopFilterDisable); - SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterAlphaC0Offset : %d\n", h264Arg->LoopFilterAlphaC0Offset); - SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterBetaOffset : %d\n", h264Arg->LoopFilterBetaOffset); - SEC_OSAL_Log(SEC_LOG_TRACE, "SymbolMode : %d\n", h264Arg->SymbolMode); - SEC_OSAL_Log(SEC_LOG_TRACE, "PictureInterlace : %d\n", h264Arg->PictureInterlace); - SEC_OSAL_Log(SEC_LOG_TRACE, "Transform8x8Mode : %d\n", h264Arg->Transform8x8Mode); - SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", h264Arg->RandomIntraMBRefresh); - SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", h264Arg->PadControlOn); - SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", h264Arg->LumaPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", h264Arg->CbPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", h264Arg->CrPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", h264Arg->EnableFRMRateControl); - SEC_OSAL_Log(SEC_LOG_TRACE, "EnableMBRateControl : %d\n", h264Arg->EnableMBRateControl); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", h264Arg->FrameRate); - SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", h264Arg->Bitrate); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", h264Arg->FrameQp); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", h264Arg->QSCodeMax); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", h264Arg->QSCodeMin); - SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", h264Arg->CBRPeriodRf); - SEC_OSAL_Log(SEC_LOG_TRACE, "DarkDisable : %d\n", h264Arg->DarkDisable); - SEC_OSAL_Log(SEC_LOG_TRACE, "SmoothDisable : %d\n", h264Arg->SmoothDisable); - SEC_OSAL_Log(SEC_LOG_TRACE, "StaticDisable : %d\n", h264Arg->StaticDisable); - SEC_OSAL_Log(SEC_LOG_TRACE, "ActivityDisable : %d\n", h264Arg->ActivityDisable); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", h264Arg->FrameMap); -} - -void Set_H264Enc_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - pH264Arg->codecType = H264_ENC; - pH264Arg->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; - pH264Arg->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; - pH264Arg->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; - pH264Arg->SliceMode = 0; -#ifdef USE_SLICE_OUTPUT_MODE - pH264Arg->OutputMode = FRAME; -#endif - pH264Arg->RandomIntraMBRefresh = 0; - pH264Arg->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - pH264Arg->QSCodeMax = 51; - pH264Arg->QSCodeMin = 10; - pH264Arg->PadControlOn = 0; // 0: disable, 1: enable - pH264Arg->LumaPadVal = 0; - pH264Arg->CbPadVal = 0; - pH264Arg->CrPadVal = 0; - - pH264Arg->ProfileIDC = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile); //0; //(OMX_VIDEO_AVCProfileMain) - pH264Arg->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); //40; //(OMX_VIDEO_AVCLevel4) - pH264Arg->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - pH264Arg->SliceArgument = 0; // Slice mb/byte size number - pH264Arg->NumberBFrames = 0; // 0 ~ 2 - pH264Arg->NumberReferenceFrames = 1; - pH264Arg->NumberRefForPframes = 1; - pH264Arg->LoopFilterDisable = 1; // 1: Loop Filter Disable, 0: Filter Enable - pH264Arg->LoopFilterAlphaC0Offset = 0; - pH264Arg->LoopFilterBetaOffset = 0; - pH264Arg->SymbolMode = 1; // 0: CAVLC, 1: CABAC - pH264Arg->PictureInterlace = 0; - pH264Arg->Transform8x8Mode = 1; // 0: 4x4, 1: allow 8x8 - pH264Arg->DarkDisable = 1; - pH264Arg->SmoothDisable = 1; - pH264Arg->StaticDisable = 1; - pH264Arg->ActivityDisable = 1; - - pH264Arg->FrameQp = pVideoEnc->quantization.nQpI; - pH264Arg->FrameQp_P = pVideoEnc->quantization.nQpP; - pH264Arg->FrameQp_B = pVideoEnc->quantization.nQpB; - - SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); - switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { - case OMX_Video_ControlRateVariable: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pH264Arg->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC - pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC - pH264Arg->CBRPeriodRf = 100; - break; - case OMX_Video_ControlRateConstant: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); - pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC - pH264Arg->EnableMBRateControl = 1; // 0: Disable, 1:MB level RC - pH264Arg->CBRPeriodRf = 10; - break; - case OMX_Video_ControlRateDisable: - default: //Android default - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pH264Arg->EnableFRMRateControl = 0; - pH264Arg->EnableMBRateControl = 0; - pH264Arg->CBRPeriodRf = 100; - break; - } - - switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: -#ifdef USE_METADATABUFFERTYPE - case OMX_COLOR_FormatAndroidOpaque: -#endif - pH264Arg->FrameMap = NV12_LINEAR; - break; - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12Tiled: - pH264Arg->FrameMap = NV12_TILE; - break; - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21Linear: - pH264Arg->FrameMap = NV21_LINEAR; - break; - default: - pH264Arg->FrameMap = NV12_TILE; - break; - } - - H264PrintParams(pH264Arg); -} - -void Change_H264Enc_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { - int set_conf_IntraRefreshVOP = 1; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, - MFC_ENC_SETCONF_FRAME_TYPE, - &set_conf_IntraRefreshVOP); - pVideoEnc->IntraRefreshVOP = OMX_FALSE; - } - if (pH264Arg->IDRPeriod != (int)pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1) { - int set_conf_IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, - MFC_ENC_SETCONF_I_PERIOD, - &set_conf_IDRPeriod); - } - if (pH264Arg->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { - int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - &set_conf_bitrate); - } - if (pH264Arg->FrameRate != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { - int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - &set_conf_framerate); - } - - Set_H264Enc_Param(pH264Arg, pSECComponent); - H264PrintParams(pH264Arg); -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex]; - - SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE); - } - break; - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; - SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; - OMX_U32 maxProfileLevelNum = 0; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pProfileLevel = supportedAVCProfileLevels; - maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - - if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pProfileLevel += pDstProfileLevel->nProfileIndex; - pDstProfileLevel->eProfile = pProfileLevel->profile; - pDstProfileLevel->eLevel = pProfileLevel->level; - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex]; - - pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; - pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; - OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex]; - - SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE)) { - pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex]; - pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; - pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_GetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - switch (nIndex) { - case OMX_IndexConfigVideoAVCIntraPeriod: - { - OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure; - OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; - pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames; - } - } - break; - default: - ret = SEC_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_SetConfig( - OMX_HANDLETYPE hComponent, - OMX_INDEXTYPE nIndex, - OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - switch (nIndex) { - case OMX_IndexConfigVideoIntraPeriod: - { - SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1; - - pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames; - - ret = OMX_ErrorNone; - } - break; - case OMX_IndexConfigVideoAVCIntraPeriod: - { - OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure; - OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex; - - if ((portIndex != OUTPUT_PORT_INDEX)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } else { - if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1)) - pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames; - else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - } - break; - default: - ret = SEC_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - if (ret == OMX_ErrorNone) - pVideoEnc->configChange = OMX_TRUE; - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { - *pIndexType = OMX_IndexConfigVideoIntraPeriod; - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H264_ENC_ROLE); - ret = OMX_ErrorNone; - } else { - ret = OMX_ErrorNoMore; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - while (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameStart); - - if (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { - pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameEnd); - } - } - -EXIT: - FunctionOut(); - SEC_OSAL_ThreadExit(NULL); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - OMX_PTR hMFCHandle = NULL; - OMX_S32 returnCodec = 0; - CSC_METHOD csc_method = CSC_METHOD_SW; - - FunctionIn(); - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Function Codec) encoder and CMM(Codec Memory Management) driver open */ - switch (pSECInputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); - break; - default: { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcEncOpenExt(&buf_type); - break; - } - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pH264Enc->hMFCH264Handle.hMFCHandle = hMFCHandle; - - Set_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); - - returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pH264Enc->hMFCH264Handle.mfcVideoAvc)); - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - /* Allocate encoder's input buffer */ - returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->MFCEncInputBuffer[0].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; - pVideoEnc->MFCEncInputBuffer[0].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; - pVideoEnc->MFCEncInputBuffer[0].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; - pVideoEnc->MFCEncInputBuffer[0].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; - pVideoEnc->MFCEncInputBuffer[0].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; - pVideoEnc->MFCEncInputBuffer[0].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; - pVideoEnc->MFCEncInputBuffer[0].YDataSize = 0; - pVideoEnc->MFCEncInputBuffer[0].CDataSize = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); - SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); - - returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->MFCEncInputBuffer[1].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; - pVideoEnc->MFCEncInputBuffer[1].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; - pVideoEnc->MFCEncInputBuffer[1].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; - pVideoEnc->MFCEncInputBuffer[1].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; - pVideoEnc->MFCEncInputBuffer[1].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; - pVideoEnc->MFCEncInputBuffer[1].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; - pVideoEnc->MFCEncInputBuffer[1].YDataSize = 0; - pVideoEnc->MFCEncInputBuffer[1].CDataSize = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); - SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); - - pVideoEnc->indexInputBuffer = 0; - - pVideoEnc->bFirstFrame = OMX_TRUE; - -#ifdef NONBLOCK_MODE_PROCESS - pVideoEnc->NBEncThread.bExitEncodeThread = OMX_FALSE; - pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; - SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoEnc->NBEncThread.hNBEncodeThread, - SEC_MFC_EncodeThread, - pOMXComponent)) { - pH264Enc->hMFCH264Handle.returnCodec = MFC_RET_OK; - } -#endif - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pH264Enc->hMFCH264Handle.indexTimestamp = 0; - - pVideoEnc->csc_handle = csc_init(&csc_method); - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_H264ENC_HANDLE *pH264Enc = NULL; - OMX_PTR hMFCHandle = NULL; - - FunctionIn(); - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoEnc->NBEncThread.hNBEncodeThread != NULL) { - pVideoEnc->NBEncThread.bExitEncodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); - SEC_OSAL_ThreadTerminate(pVideoEnc->NBEncThread.hNBEncodeThread); - pVideoEnc->NBEncThread.hNBEncodeThread = NULL; - } - - if(pVideoEnc->NBEncThread.hEncFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameEnd); - pVideoEnc->NBEncThread.hEncFrameEnd = NULL; - } - - if(pVideoEnc->NBEncThread.hEncFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameStart); - pVideoEnc->NBEncThread.hEncFrameStart = NULL; - } -#endif - - hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; - if (hMFCHandle != NULL) { - SsbSipMfcEncClose(hMFCHandle); - hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL; - } - - if (pVideoEnc->csc_handle != NULL) { - csc_deinit(pVideoEnc->csc_handle); - pVideoEnc->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264_Encode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo; - SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; - SEC_OMX_BASEPORT *pSECPort = NULL; - MFC_ENC_ADDR_INFO addrInfo; - OMX_U32 oneFrameSize = pInputData->dataLen; - - FunctionIn(); - - if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); - if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - OMX_U8 *p = NULL; - int iSpsSize = 0; - int iPpsSize = 0; - - p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4); - - iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr; - pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr; - pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; - - iPpsSize = outputInfo.headerSize - iSpsSize; - pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = (OMX_U8 *)outputInfo.StrmVirAddr + iSpsSize; - pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; - } - - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.headerSize; - pOutputData->dataLen = outputInfo.headerSize; - pOutputData->timeStamp = 0; - pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - - pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; - - ret = OMX_ErrorInputDataEncodeYet; - goto EXIT; - } - - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; - - if (oneFrameSize <= 0) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)){ - /* Dummy input data for get out encoded last frame */ - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - } else { - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: { -#ifndef USE_METADATABUFFERTYPE - /* USE_FIMC_FRAME_BUFFER */ - SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); -#else - OMX_PTR ppBuf[3]; - SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); - - SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); -#endif - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - } - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - addrInfo.pAddrY = *((void **)pInputData->dataBuffer); - addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); - - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - default: - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - break; - } - } - - pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - - if ((pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) && - (pVideoEnc->bFirstFrame == OMX_FALSE)) { - OMX_S32 indexTimestamp = 0; - - /* wait for mfc encode done */ - if (pVideoEnc->NBEncThread.bEncoderRun != OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameEnd); - pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); - if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - } - - if (pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) { - /** Fill Output Buffer **/ - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.dataSize; - pOutputData->dataLen = outputInfo.dataSize; - pOutputData->usedDataLen = 0; - - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) - pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; - - SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - - ret = OMX_ErrorNone; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pH264Enc->hMFCH264Handle.returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - if (pSECComponent->getAllDelayBuffer == OMX_TRUE) { - ret = OMX_ErrorInputDataEncodeYet; - } - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataEncodeYet; - } - if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pOutputData->dataLen = 0; - pOutputData->usedDataLen = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_BUFFERFLAG_EOS!!!"); - ret = OMX_ErrorNone; - } - } - if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe Failed!!!\n", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); - if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - pVideoEnc->indexInputBuffer++; - pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - } - - if (pVideoEnc->configChange == OMX_TRUE) { - Change_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); - pVideoEnc->configChange = OMX_FALSE; - } - - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); - - /* mfc encode start */ - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); - pVideoEnc->NBEncThread.bEncoderRun = OMX_TRUE; - pH264Enc->hMFCH264Handle.indexTimestamp++; - pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - pVideoEnc->bFirstFrame = OMX_FALSE; - SEC_OSAL_SleepMillisec(0); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_H264_Encode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo; - SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; - SEC_OMX_BASEPORT *pSECPort = NULL; - MFC_ENC_ADDR_INFO addrInfo; - OMX_U32 oneFrameSize = pInputData->dataLen; - OMX_S32 returnCodec = 0; - - FunctionIn(); - - if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { - returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); - if (returnCodec != MFC_RET_OK) - { - SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - OMX_U8 *p = NULL; - int iSpsSize = 0; - int iPpsSize = 0; - - p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4); - - iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr; - pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr; - pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; - - iPpsSize = outputInfo.headerSize - iSpsSize; - pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = (OMX_U8 *)outputInfo.StrmVirAddr + iSpsSize; - pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; - } - - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.headerSize; - pOutputData->dataLen = outputInfo.headerSize; - pOutputData->timeStamp = 0; - pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - - pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; - - ret = OMX_ErrorInputDataEncodeYet; - goto EXIT; - } - - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; - - if (oneFrameSize <= 0) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: { -#ifndef USE_METADATABUFFERTYPE - /* USE_FIMC_FRAME_BUFFER */ - SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); -#else - OMX_PTR ppBuf[3]; - SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); - - SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); -#endif - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - } - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - addrInfo.pAddrY = *((void **)pInputData->dataBuffer); - addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); - - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - default: - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - break; - } - - returnCodec = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); - if (returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - pVideoEnc->indexInputBuffer++; - pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - } - - if (pVideoEnc->configChange == OMX_TRUE) { - Change_H264Enc_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); - pVideoEnc->configChange = OMX_FALSE; - } - - pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); - - returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); - if (returnCodec == MFC_RET_OK) { - OMX_S32 indexTimestamp = 0; - - pH264Enc->hMFCH264Handle.indexTimestamp++; - pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - - returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); - if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - } - - if (returnCodec == MFC_RET_OK) { - /** Fill Output Buffer **/ - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.dataSize; - pOutputData->dataLen = outputInfo.dataSize; - pOutputData->usedDataLen = 0; - - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) - pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; - - SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - - ret = OMX_ErrorNone; - } - } - - if (returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe OR SsbSipMfcEncGetOutBuf Failed!!!\n", __func__); - ret = OMX_ErrorUndefined; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Encode */ -OMX_ERRORTYPE SEC_MFC_H264Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - OMX_BOOL endOfFrame = OMX_FALSE; - OMX_BOOL flagEOS = OMX_FALSE; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || - (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { - ret = OMX_ErrorNone; - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - ret = OMX_ErrorNone; - goto EXIT; - } - -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_H264_Encode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_H264_Encode_Block(pOMXComponent, pInputData, pOutputData); -#endif - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataEncodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - /* pOutputData->usedDataLen = 0; */ - pOutputData->remainDataLen = pOutputData->dataLen - pOutputData->usedDataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_ENC, componentName) != 0) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_ENC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pH264Enc = SEC_OSAL_Malloc(sizeof(SEC_H264ENC_HANDLE)); - if (pH264Enc == NULL) { - SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); - goto EXIT; - } - SEC_OSAL_Memset(pH264Enc, 0, sizeof(SEC_H264ENC_HANDLE)); - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc; - - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_ENC); - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); - pH264Enc->AVCComponent[i].nPortIndex = i; - pH264Enc->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileHigh; - pH264Enc->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; - - pH264Enc->AVCComponent[i].nPFrames = 20; - } - - pOMXComponent->GetParameter = &SEC_MFC_H264Enc_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_H264Enc_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_H264Enc_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_H264Enc_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Enc_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Enc_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Enc_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Enc_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Enc_bufferProcess; - pSECComponent->sec_checkInputFrame = NULL; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_H264ENC_HANDLE *pH264Enc = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pH264Enc = (SEC_H264ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pH264Enc != NULL) { - SEC_OSAL_Free(pH264Enc); - pH264Enc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.h b/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.h deleted file mode 100644 index cc0a94f..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/SEC_OMX_H264enc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_H264enc.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_H264_ENC_COMPONENT -#define SEC_OMX_H264_ENC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "OMX_Video.h" -#include "SsbSipMfcApi.h" - - -typedef struct _EXTRA_DATA -{ - OMX_PTR pHeaderSPS; - OMX_U32 SPSLen; - OMX_PTR pHeaderPPS; - OMX_U32 PPSLen; -} EXTRA_DATA; - -typedef struct _SEC_MFC_H264ENC_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - SSBSIP_MFC_ENC_H264_PARAM mfcVideoAvc; - SSBSIP_MFC_ENC_INPUT_INFO inputInfo; -/* SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; */ - OMX_U32 indexTimestamp; - OMX_BOOL bConfiguredMFC; - EXTRA_DATA headerData; - OMX_S32 returnCodec; -} SEC_MFC_H264ENC_HANDLE; - -typedef struct _SEC_H264ENC_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_H264ENC_HANDLE hMFCH264Handle; -} SEC_H264ENC_HANDLE; - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.c deleted file mode 100644 index e24e126..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) -{ - FunctionIn(); - - if (secComponents == NULL) - goto EXIT; - - /* component 1 - video decoder H.264 */ - SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPONENT_H264_ENC); - SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPONENT_H264_ENC_ROLE); - secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.h deleted file mode 100644 index 9511e3c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/h264/library_register.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_H264_REG -#define SEC_OMX_H264_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 1 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* H.264 */ -#define SEC_OMX_COMPONENT_H264_ENC "OMX.SEC.AVC.Encoder" -#define SEC_OMX_COMPONENT_H264_ENC_ROLE "video_encoder.avc" - - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); - -#ifdef __cplusplus -}; -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/Android.mk b/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/Android.mk deleted file mode 100644 index 441f5fb..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OMX_Mpeg4enc.c \ - library_register.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libOMX.SEC.M4V.Encoder -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx - -LOCAL_CFLAGS := - -ifeq ($(BOARD_NONBLOCK_MODE_PROCESS), true) -LOCAL_CFLAGS += -DNONBLOCK_MODE_PROCESS -endif - -ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) -LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE -endif - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc libsecosal libsecbasecomponent \ - libswconverter libsecmfcapi -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ - libSEC_OMX_Resourcemanager libcsc - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/core \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/enc \ - $(TARGET_OUT_HEADERS)/$(SEC_COPY_HEADERS_TO) - -include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c b/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c deleted file mode 100644 index 1fcc90e..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.c +++ /dev/null @@ -1,1803 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mpeg4enc.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - - -#include -#include -#include - -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Venc.h" -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OSAL_Thread.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Android.h" -#include "library_register.h" -#include "SEC_OMX_Mpeg4enc.h" -#include "SsbSipMfcApi.h" -#include "csc.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MPEG4_ENC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -/* MPEG4 Encoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, - {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, - {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; - -/* H.263 Encoder Supported Levels & profiles */ -SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, - {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}}; - -OMX_U32 OMXMpeg4ProfileToMFCProfile(OMX_VIDEO_MPEG4PROFILETYPE profile) -{ - OMX_U32 ret; - - switch (profile) { - case OMX_VIDEO_MPEG4ProfileSimple: - ret = 0; - break; - case OMX_VIDEO_MPEG4ProfileAdvancedSimple: - ret = 1; - break; - default: - ret = 0; - }; - - return ret; -} -OMX_U32 OMXMpeg4LevelToMFCLevel(OMX_VIDEO_MPEG4LEVELTYPE level) -{ - OMX_U32 ret; - - switch (level) { - case OMX_VIDEO_MPEG4Level0: - ret = 0; - break; - case OMX_VIDEO_MPEG4Level0b: - ret = 9; - break; - case OMX_VIDEO_MPEG4Level1: - ret = 1; - break; - case OMX_VIDEO_MPEG4Level2: - ret = 2; - break; - case OMX_VIDEO_MPEG4Level3: - ret = 3; - break; - case OMX_VIDEO_MPEG4Level4: - case OMX_VIDEO_MPEG4Level4a: - ret = 4; - break; - case OMX_VIDEO_MPEG4Level5: - ret = 5; - break; - default: - ret = 0; - }; - - return ret; -} - -void Mpeg4PrintParams(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param) -{ - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", pMpeg4Param->SourceWidth); - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", pMpeg4Param->SourceHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", pMpeg4Param->IDRPeriod); - SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", pMpeg4Param->SliceMode); -#ifdef USE_SLICE_OUTPUT_MODE - SEC_OSAL_Log(SEC_LOG_TRACE, "OutputMode : %d\n", pMpeg4Param->OutputMode); -#endif - SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", pMpeg4Param->RandomIntraMBRefresh); - SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", pMpeg4Param->EnableFRMRateControl); - SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", pMpeg4Param->Bitrate); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", pMpeg4Param->FrameQp); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", pMpeg4Param->FrameQp_P); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", pMpeg4Param->QSCodeMax); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", pMpeg4Param->QSCodeMin); - SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", pMpeg4Param->CBRPeriodRf); - SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", pMpeg4Param->PadControlOn); - SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", pMpeg4Param->LumaPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", pMpeg4Param->CbPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", pMpeg4Param->CrPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", pMpeg4Param->FrameMap); - - /* MPEG4 specific parameters */ - SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", pMpeg4Param->ProfileIDC); - SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", pMpeg4Param->LevelIDC); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_B : %d\n", pMpeg4Param->FrameQp_B); - SEC_OSAL_Log(SEC_LOG_TRACE, "TimeIncreamentRes : %d\n", pMpeg4Param->TimeIncreamentRes); - SEC_OSAL_Log(SEC_LOG_TRACE, "VopTimeIncreament : %d\n", pMpeg4Param->VopTimeIncreament); - SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", pMpeg4Param->SliceArgument); - SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", pMpeg4Param->NumberBFrames); - SEC_OSAL_Log(SEC_LOG_TRACE, "DisableQpelME : %d\n", pMpeg4Param->DisableQpelME); -} - -void H263PrintParams(SSBSIP_MFC_ENC_H263_PARAM *pH263Param) -{ - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", pH263Param->SourceWidth); - SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", pH263Param->SourceHeight); - SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", pH263Param->IDRPeriod); - SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", pH263Param->SliceMode); - SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", pH263Param->RandomIntraMBRefresh); - SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", pH263Param->EnableFRMRateControl); - SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", pH263Param->Bitrate); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", pH263Param->FrameQp); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", pH263Param->FrameQp_P); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", pH263Param->QSCodeMax); - SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", pH263Param->QSCodeMin); - SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", pH263Param->CBRPeriodRf); - SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", pH263Param->PadControlOn); - SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", pH263Param->LumaPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", pH263Param->CbPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", pH263Param->CrPadVal); - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameMap : %d\n", pH263Param->FrameMap); - - /* H.263 specific parameters */ - SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", pH263Param->FrameRate); -} - -void Set_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - pMpeg4Param->codecType = MPEG4_ENC; - pMpeg4Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; - pMpeg4Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; - pMpeg4Param->IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; - pMpeg4Param->SliceMode = 0; -#ifdef USE_SLICE_OUTPUT_MODE - pMpeg4Param->OutputMode = FRAME; -#endif - pMpeg4Param->RandomIntraMBRefresh = 0; - pMpeg4Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - pMpeg4Param->QSCodeMax = 30; - pMpeg4Param->QSCodeMin = 10; - pMpeg4Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ - pMpeg4Param->LumaPadVal = 0; - pMpeg4Param->CbPadVal = 0; - pMpeg4Param->CrPadVal = 0; - - pMpeg4Param->ProfileIDC = OMXMpeg4ProfileToMFCProfile(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eProfile); - pMpeg4Param->LevelIDC = OMXMpeg4LevelToMFCLevel(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eLevel); - pMpeg4Param->TimeIncreamentRes = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - pMpeg4Param->VopTimeIncreament = 1; - pMpeg4Param->SliceArgument = 0; /* MB number or byte number */ - pMpeg4Param->NumberBFrames = 0; /* 0(not used) ~ 2 */ - pMpeg4Param->DisableQpelME = 1; - - pMpeg4Param->FrameQp = pVideoEnc->quantization.nQpI; - pMpeg4Param->FrameQp_P = pVideoEnc->quantization.nQpP; - pMpeg4Param->FrameQp_B = pVideoEnc->quantization.nQpB; - - SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); - switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { - case OMX_Video_ControlRateVariable: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pMpeg4Param->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC - pMpeg4Param->CBRPeriodRf = 100; - break; - case OMX_Video_ControlRateConstant: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); - pMpeg4Param->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC - pMpeg4Param->CBRPeriodRf = 10; - break; - case OMX_Video_ControlRateDisable: - default: //Android default - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pMpeg4Param->EnableFRMRateControl = 0; - pMpeg4Param->CBRPeriodRf = 100; - break; - } - - switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_COLOR_FormatYUV420Planar: -#ifdef METADATABUFFERTYPE - case OMX_COLOR_FormatAndroidOpaque: -#endif - pMpeg4Param->FrameMap = NV12_LINEAR; - break; - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12Tiled: - pMpeg4Param->FrameMap = NV12_TILE; - break; - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21Linear: - pMpeg4Param->FrameMap = NV21_LINEAR; - break; - default: - pMpeg4Param->FrameMap = NV12_TILE; - break; - } - - Mpeg4PrintParams(pMpeg4Param); -} - -void Change_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { - int set_conf_IntraRefreshVOP = 1; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_FRAME_TYPE, - &set_conf_IntraRefreshVOP); - pVideoEnc->IntraRefreshVOP = OMX_FALSE; - } - - if (pMpeg4Param->IDRPeriod != (int)pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1) { - int set_conf_IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_I_PERIOD, - &set_conf_IDRPeriod); - } - if (pMpeg4Param->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { - int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - &set_conf_bitrate); - } - if (pMpeg4Param->TimeIncreamentRes != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { - int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - &set_conf_framerate); - } - - Set_Mpeg4Enc_Param(pMpeg4Param, pSECComponent); - Mpeg4PrintParams(pMpeg4Param); -} - -void Set_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - pH263Param->codecType = H263_ENC; - pH263Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; - pH263Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; - pH263Param->IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; - pH263Param->SliceMode = 0; - pH263Param->RandomIntraMBRefresh = 0; - pH263Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - pH263Param->QSCodeMax = 30; - pH263Param->QSCodeMin = 10; - pH263Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ - pH263Param->LumaPadVal = 0; - pH263Param->CbPadVal = 0; - pH263Param->CrPadVal = 0; - - pH263Param->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - - pH263Param->FrameQp = pVideoEnc->quantization.nQpI; - pH263Param->FrameQp_P = pVideoEnc->quantization.nQpP; - - SEC_OSAL_Log(SEC_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); - switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { - case OMX_Video_ControlRateVariable: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pH263Param->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC - pH263Param->CBRPeriodRf = 100; - break; - case OMX_Video_ControlRateConstant: - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); - pH263Param->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC - pH263Param->CBRPeriodRf = 10; - break; - case OMX_Video_ControlRateDisable: - default: //Android default - SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); - pH263Param->EnableFRMRateControl = 0; - pH263Param->CBRPeriodRf = 100; - break; - } - - switch ((SEC_OMX_COLOR_FORMATTYPE)pSECInputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - case OMX_COLOR_FormatYUV420SemiPlanar: - pH263Param->FrameMap = NV12_LINEAR; - break; - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12Tiled: - pH263Param->FrameMap = NV12_TILE; - break; - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21Linear: - pH263Param->FrameMap = NV21_LINEAR; - break; - default: - pH263Param->FrameMap = NV12_TILE; - break; - } - - H263PrintParams(pH263Param); -} - -void Change_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPONENT *pSECComponent) -{ - SEC_OMX_BASEPORT *pSECInputPort = NULL; - SEC_OMX_BASEPORT *pSECOutputPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { - int set_conf_IntraRefreshVOP = 1; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_FRAME_TYPE, - &set_conf_IntraRefreshVOP); - pVideoEnc->IntraRefreshVOP = OMX_FALSE; - } - if (pH263Param->IDRPeriod != (int)pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1) { - int set_conf_IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_I_PERIOD, - &set_conf_IDRPeriod); - } - if (pH263Param->Bitrate != (int)pSECOutputPort->portDefinition.format.video.nBitrate) { - int set_conf_bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_BIT_RATE, - &set_conf_bitrate); - } - if (pH263Param->FrameRate != (int)((pSECOutputPort->portDefinition.format.video.xFramerate) >> 16)) { - int set_conf_framerate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; - SsbSipMfcEncSetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, - MFC_ENC_SETCONF_CHANGE_FRAME_RATE, - &set_conf_framerate); - } - - Set_H263Enc_Param(pH263Param, pSECComponent); - H263PrintParams(pH263Param); -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nParamIndex) { - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstMpeg4Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - } - break; - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcH263Param = &pMpeg4Enc->h263Component[pDstH263Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_S32 codecType; - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); - else - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE); - } - break; - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; - OMX_U32 maxProfileLevelNum = 0; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - pProfileLevel = supportedMPEG4ProfileLevels; - maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - } else { - pProfileLevel = supportedH263ProfileLevels; - maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); - } - - if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - pProfileLevel += pDstProfileLevel->nProfileIndex; - pDstProfileLevel->eProfile = pProfileLevel->profile; - pDstProfileLevel->eLevel = pProfileLevel->level; - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstProfileLevel->nPortIndex]; - pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; - pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; - } else { - pSrcH263Param = &pMpeg4Enc->h263Component[pDstProfileLevel->nPortIndex]; - pDstProfileLevel->eProfile = pSrcH263Param->eProfile; - pDstProfileLevel->eLevel = pSrcH263Param->eLevel; - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pSrcErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; - OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcMpeg4Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); - } - break; - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstH263Param = &pMpeg4Enc->h263Component[pSrcH263Param->nPortIndex]; - - SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); - } - break; - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; - - ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE)) { - pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - //((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; - } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE)) { - pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - //((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; - } else { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; - OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - OMX_S32 codecType; - - ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) { - /* - * To do: Check validity of profile & level parameters - */ - - pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcProfileLevel->nPortIndex]; - pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; - pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; - } else { - /* - * To do: Check validity of profile & level parameters - */ - - pDstH263Param = &pMpeg4Enc->h263Component[pSrcProfileLevel->nPortIndex]; - pDstH263Param->eProfile = pSrcProfileLevel->eProfile; - pDstH263Param->eLevel = pSrcProfileLevel->eLevel; - } - } - break; - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pDstErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; - - pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; - pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; - pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; - pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; - pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; - } - break; - default: - ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); - break; - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - switch (nIndex) { - default: - ret = SEC_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetConfig( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - FunctionIn(); - - if (hComponent == NULL || pComponentConfigStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - - switch (nIndex) { - case OMX_IndexConfigVideoIntraPeriod: - { - SEC_OMX_VIDEOENC_COMPONENT *pVEncBase = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1; - - if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) - pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames; - else - pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames; - - ret = OMX_ErrorNone; - } - break; - default: - ret = SEC_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); - break; - } - -EXIT: - if (ret == OMX_ErrorNone) - pVideoEnc->configChange = OMX_TRUE; - - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetExtensionIndex( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE *pIndexType) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - if ((cParameterName == NULL) || (pIndexType == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECComponent->currentState == OMX_StateInvalid) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { - *pIndexType = OMX_IndexConfigVideoIntraPeriod; - ret = OMX_ErrorNone; - } else { - ret = SEC_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); - } -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_ComponentRoleEnum( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - OMX_S32 codecType; - - FunctionIn(); - - if ((hComponent == NULL) || (cRole == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - codecType = ((SEC_MPEG4ENC_HANDLE *)(((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); - else - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H263_ENC_ROLE); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - while (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameStart); - - if (pVideoEnc->NBEncThread.bExitEncodeThread == OMX_FALSE) { - pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncExe(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle); - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameEnd); - } - } - -EXIT: - FunctionOut(); - SEC_OSAL_ThreadExit(NULL); - - return ret; -} - -/* MFC Init */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - OMX_S32 returnCodec = 0; - CSC_METHOD csc_method = CSC_METHOD_SW; - - FunctionIn(); - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; - pSECComponent->bUseFlagEOF = OMX_FALSE; - pSECComponent->bSaveFlagEOS = OMX_FALSE; - - /* MFC(Multi Format Codec) encoder and CMM(Codec Memory Management) driver open */ - switch (pSECInputPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: - hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); - break; - default: { - SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; - hMFCHandle = (OMX_PTR)SsbSipMfcEncOpenExt(&buf_type); - break; - } - } - - if (hMFCHandle == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; - - /* set MFC ENC VIDEO PARAM and initialize MFC encoder instance */ - if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { - Set_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); - returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam)); - } else { - Set_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); - returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam)); - } - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - /* Allocate encoder's input buffer */ - returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->MFCEncInputBuffer[0].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; - pVideoEnc->MFCEncInputBuffer[0].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; - pVideoEnc->MFCEncInputBuffer[0].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; - pVideoEnc->MFCEncInputBuffer[0].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; - pVideoEnc->MFCEncInputBuffer[0].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; - pVideoEnc->MFCEncInputBuffer[0].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; - pVideoEnc->MFCEncInputBuffer[0].YDataSize = 0; - pVideoEnc->MFCEncInputBuffer[0].CDataSize = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); - SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); - - returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); - if (returnCodec != MFC_RET_OK) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pVideoEnc->MFCEncInputBuffer[1].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; - pVideoEnc->MFCEncInputBuffer[1].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; - pVideoEnc->MFCEncInputBuffer[1].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; - pVideoEnc->MFCEncInputBuffer[1].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; - pVideoEnc->MFCEncInputBuffer[1].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; - pVideoEnc->MFCEncInputBuffer[1].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; - pVideoEnc->MFCEncInputBuffer[1].YDataSize = 0; - pVideoEnc->MFCEncInputBuffer[1].CDataSize = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); - SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); - - pVideoEnc->indexInputBuffer = 0; - - pVideoEnc->bFirstFrame = OMX_TRUE; - -#ifdef NONBLOCK_MODE_PROCESS - pVideoEnc->NBEncThread.bExitEncodeThread = OMX_FALSE; - pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; - SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameStart)); - SEC_OSAL_SemaphoreCreate(&(pVideoEnc->NBEncThread.hEncFrameEnd)); - if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pVideoEnc->NBEncThread.hNBEncodeThread, - SEC_MFC_EncodeThread, - pOMXComponent)) { - pMpeg4Enc->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; - } -#endif - SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); - SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0; - - pVideoEnc->csc_handle = csc_init(&csc_method); - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Terminate */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - OMX_HANDLETYPE hMFCHandle = NULL; - - FunctionIn(); - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; -#ifdef NONBLOCK_MODE_PROCESS - if (pVideoEnc->NBEncThread.hNBEncodeThread != NULL) { - pVideoEnc->NBEncThread.bExitEncodeThread = OMX_TRUE; - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); - SEC_OSAL_ThreadTerminate(pVideoEnc->NBEncThread.hNBEncodeThread); - pVideoEnc->NBEncThread.hNBEncodeThread = NULL; - } - - if(pVideoEnc->NBEncThread.hEncFrameEnd != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameEnd); - pVideoEnc->NBEncThread.hEncFrameEnd = NULL; - } - - if(pVideoEnc->NBEncThread.hEncFrameStart != NULL) { - SEC_OSAL_SemaphoreTerminate(pVideoEnc->NBEncThread.hEncFrameStart); - pVideoEnc->NBEncThread.hEncFrameStart = NULL; - } -#endif - - hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - if (hMFCHandle != NULL) { - SsbSipMfcEncClose(hMFCHandle); - hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL; - } - - if (pVideoEnc->csc_handle != NULL) { - csc_deinit(pVideoEnc->csc_handle); - pVideoEnc->csc_handle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode_Nonblock(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_HANDLETYPE hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo); - SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; - SEC_OMX_BASEPORT *pSECPort = NULL; - MFC_ENC_ADDR_INFO addrInfo; - OMX_U32 oneFrameSize = pInputData->dataLen; - - FunctionIn(); - - if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { - pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); - if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) - { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.headerSize; - pOutputData->dataLen = outputInfo.headerSize; - pOutputData->timeStamp = 0; - pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - - pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; - - ret = OMX_ErrorInputDataEncodeYet; - goto EXIT; - } - - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; - - if (oneFrameSize <= 0) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)){ - /* Dummy input data for get out encoded last frame */ - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - } else { - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: { -#ifndef USE_METADATABUFFERTYPE - /* USE_FIMC_FRAME_BUFFER */ - SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); -#else - OMX_PTR ppBuf[3]; - SEC_OSAL_GetInfoFromMetaData(pInputData, ppBuf); - - SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); -#endif - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - } - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - addrInfo.pAddrY = *((void **)pInputData->dataBuffer); - addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); - - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - default: - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - break; - } - } - - pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - - if ((pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && - (pVideoEnc->bFirstFrame == OMX_FALSE)) { - OMX_S32 indexTimestamp = 0; - - /* wait for mfc encode done */ - if (pVideoEnc->NBEncThread.bEncoderRun != OMX_FALSE) { - SEC_OSAL_SemaphoreWait(pVideoEnc->NBEncThread.hEncFrameEnd); - pVideoEnc->NBEncThread.bEncoderRun = OMX_FALSE; - } - - SEC_OSAL_SleepMillisec(0); - pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &outputInfo); - if ((SsbSipMfcEncGetConfig(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - } - - if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { - /** Fill Output Buffer **/ - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.dataSize; - pOutputData->dataLen = outputInfo.dataSize; - pOutputData->usedDataLen = 0; - - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) - pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; - - SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - - ret = OMX_ErrorNone; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - if (pSECComponent->getAllDelayBuffer == OMX_TRUE) { - ret = OMX_ErrorInputDataEncodeYet; - } - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); - pSECComponent->getAllDelayBuffer = OMX_TRUE; - ret = OMX_ErrorInputDataEncodeYet; - } - if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { - pSECComponent->getAllDelayBuffer = OMX_FALSE; - pOutputData->dataLen = 0; - pOutputData->usedDataLen = 0; - SEC_OSAL_Log(SEC_LOG_TRACE, "OMX_BUFFERFLAG_EOS!!!"); - ret = OMX_ErrorNone; - } - } - if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe Failed!!!\n", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); - if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - pVideoEnc->indexInputBuffer++; - pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - } - - if (pVideoEnc->configChange == OMX_TRUE) { - if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) - Change_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); - else - Change_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); - pVideoEnc->configChange = OMX_FALSE; - } - - SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); - - /* mfc encode start */ - SEC_OSAL_SemaphorePost(pVideoEnc->NBEncThread.hEncFrameStart); - pVideoEnc->NBEncThread.bEncoderRun = OMX_TRUE; - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - pVideoEnc->bFirstFrame = OMX_FALSE; - SEC_OSAL_SleepMillisec(0); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode_Block(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle); - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - OMX_HANDLETYPE hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; - SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo); - SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; - SEC_OMX_BASEPORT *pSECPort = NULL; - MFC_ENC_ADDR_INFO addrInfo; - OMX_U32 oneFrameSize = pInputData->dataLen; - OMX_S32 returnCodec = 0; - - FunctionIn(); - - if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { - returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); - if (returnCodec != MFC_RET_OK) - { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.headerSize; - pOutputData->dataLen = outputInfo.headerSize; - pOutputData->timeStamp = 0; - pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - - pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; - - ret = OMX_ErrorInputDataEncodeYet; - goto EXIT; - } - - if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) - pSECComponent->bUseFlagEOF = OMX_TRUE; - - if (oneFrameSize <= 0) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - - ret = OMX_ErrorNone; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - switch (pSECPort->portDefinition.format.video.eColorFormat) { - case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: - case OMX_SEC_COLOR_FormatNV12LPhysicalAddress: - case OMX_SEC_COLOR_FormatNV21LPhysicalAddress: { -#ifndef USE_METADATABUFFERTYPE - /* USE_FIMC_FRAME_BUFFER */ - SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); -#else - OMX_PTR ppBuf[3]; - SEC_OSAL_GetInfoFromMetaData(pInputData,ppBuf); - - SEC_OSAL_Memcpy(&addrInfo.pAddrY, ppBuf[0], sizeof(addrInfo.pAddrY)); - SEC_OSAL_Memcpy(&addrInfo.pAddrC, ppBuf[1], sizeof(addrInfo.pAddrC)); -#endif - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - } - case OMX_SEC_COLOR_FormatNV12LVirtualAddress: - addrInfo.pAddrY = *((void **)pInputData->dataBuffer); - addrInfo.pAddrC = (void *)((char *)addrInfo.pAddrY + pInputInfo->YSize); - - pInputInfo->YPhyAddr = addrInfo.pAddrY; - pInputInfo->CPhyAddr = addrInfo.pAddrC; - break; - default: - pInputInfo->YPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YPhyAddr; - pInputInfo->CPhyAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CPhyAddr; - pInputInfo->YVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].YVirAddr; - pInputInfo->CVirAddr = pVideoEnc->MFCEncInputBuffer[pVideoEnc->indexInputBuffer].CVirAddr; - break; - } - - returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); - if (returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } else { - pVideoEnc->indexInputBuffer++; - pVideoEnc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; - } - - if (pVideoEnc->configChange == OMX_TRUE) { - if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) - Change_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); - else - Change_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); - pVideoEnc->configChange = OMX_FALSE; - } - - pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); - - returnCodec = SsbSipMfcEncExe(hMFCHandle); - if (returnCodec == MFC_RET_OK) { - OMX_S32 indexTimestamp = 0; - - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - - returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); - - if ((SsbSipMfcEncGetConfig(hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - } else { - pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; - pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; - } - - if (returnCodec == MFC_RET_OK) { - /** Fill Output Buffer **/ - pOutputData->dataBuffer = outputInfo.StrmVirAddr; - pOutputData->allocSize = outputInfo.dataSize; - pOutputData->dataLen = outputInfo.dataSize; - pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) - pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; - - ret = OMX_ErrorNone; - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); - ret = OMX_ErrorUndefined; - } - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, returnCodec); - ret = OMX_ErrorUndefined; - } - -EXIT: - FunctionOut(); - - return ret; -} - -/* MFC Encode */ -OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - - FunctionIn(); - - if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || - (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { - goto EXIT; - } - if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { - goto EXIT; - } - -#ifdef NONBLOCK_MODE_PROCESS - ret = SEC_MFC_Mpeg4_Encode_Nonblock(pOMXComponent, pInputData, pOutputData); -#else - ret = SEC_MFC_Mpeg4_Encode_Block(pOMXComponent, pInputData, pOutputData); -#endif - if (ret != OMX_ErrorNone) { - if (ret == OMX_ErrorInputDataEncodeYet) { - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } else { - pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, - pSECComponent->callbackData, - OMX_EventError, ret, 0, NULL); - } - } else { - pInputData->usedDataLen += pInputData->dataLen; - pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; - pInputData->dataLen -= pInputData->usedDataLen; - pInputData->usedDataLen = 0; - - pOutputData->usedDataLen = 0; - pOutputData->remainDataLen = pOutputData->dataLen; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_BASEPORT *pSECPort = NULL; - SEC_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - OMX_S32 codecType = -1; - int i = 0; - - FunctionIn(); - - if ((hComponent == NULL) || (componentName == NULL)) { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_MPEG4_ENC, componentName) == 0) { - codecType = CODEC_TYPE_MPEG4; - } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H263_ENC, componentName) == 0) { - codecType = CODEC_TYPE_H263; - } else { - ret = OMX_ErrorBadParameter; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - pSECComponent->codecType = HW_VIDEO_ENC_CODEC; - - pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); - if (pSECComponent->componentName == NULL) { - SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); - - pMpeg4Enc = SEC_OSAL_Malloc(sizeof(SEC_MPEG4ENC_HANDLE)); - if (pMpeg4Enc == NULL) { - SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4ENC_HANDLE alloc error, ret: %X", __FUNCTION__, ret); - goto EXIT; - } - SEC_OSAL_Memset(pMpeg4Enc, 0, sizeof(SEC_MPEG4ENC_HANDLE)); - pVideoEnc = (SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle; - pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Enc; - pMpeg4Enc->hMFCMpeg4Handle.codecType = codecType; - - if (codecType == CODEC_TYPE_MPEG4) - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_MPEG4_ENC); - else - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H263_ENC); - - /* Set componentVersion */ - pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->componentVersion.s.nStep = STEP_NUMBER; - /* Set specVersion */ - pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; - pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; - pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; - pSECComponent->specVersion.s.nStep = STEP_NUMBER; - - /* Android CapabilityFlags */ - pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; - pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; - pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; - - /* Input port */ - pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate= (15 << 16); - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - /* Output port */ - pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; - pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; - pSECPort->portDefinition.format.video.nBitrate = 64000; - pSECPort->portDefinition.format.video.xFramerate= (15 << 16); - if (codecType == CODEC_TYPE_MPEG4) { - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); - } else { - pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); - SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); - } - pSECPort->portDefinition.format.video.pNativeRender = 0; - pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; - pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; - pSECPort->portDefinition.bEnabled = OMX_TRUE; - - if (codecType == CODEC_TYPE_MPEG4) { - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pMpeg4Enc->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); - pMpeg4Enc->mpeg4Component[i].nPortIndex = i; - pMpeg4Enc->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; - pMpeg4Enc->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level4; - - pMpeg4Enc->mpeg4Component[i].nPFrames = 10; - pMpeg4Enc->mpeg4Component[i].nBFrames = 0; /* No support for B frames */ - pMpeg4Enc->mpeg4Component[i].nMaxPacketSize = 256; /* Default value */ - pMpeg4Enc->mpeg4Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; - pMpeg4Enc->mpeg4Component[i].bGov = OMX_FALSE; - - } - } else { - for(i = 0; i < ALL_PORT_NUM; i++) { - INIT_SET_SIZE_VERSION(&pMpeg4Enc->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); - pMpeg4Enc->h263Component[i].nPortIndex = i; - pMpeg4Enc->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline; - pMpeg4Enc->h263Component[i].eLevel = OMX_VIDEO_H263Level45; - - pMpeg4Enc->h263Component[i].nPFrames = 20; - pMpeg4Enc->h263Component[i].nBFrames = 0; /* No support for B frames */ - pMpeg4Enc->h263Component[i].bPLUSPTYPEAllowed = OMX_FALSE; - pMpeg4Enc->h263Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; - pMpeg4Enc->h263Component[i].bForceRoundingTypeToZero = OMX_TRUE; - pMpeg4Enc->h263Component[i].nPictureHeaderRepetition = 0; - pMpeg4Enc->h263Component[i].nGOBHeaderInterval = 0; - } - } - - pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Enc_GetParameter; - pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Enc_SetParameter; - pOMXComponent->GetConfig = &SEC_MFC_Mpeg4Enc_GetConfig; - pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Enc_SetConfig; - pOMXComponent->GetExtensionIndex = &SEC_MFC_Mpeg4Enc_GetExtensionIndex; - pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Enc_ComponentRoleEnum; - pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; - - pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Enc_Init; - pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Enc_Terminate; - pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Enc_bufferProcess; - pSECComponent->sec_checkInputFrame = NULL; - - pSECComponent->currentState = OMX_StateLoaded; - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - - SEC_OSAL_Free(pSECComponent->componentName); - pSECComponent->componentName = NULL; - - pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle; - if (pMpeg4Enc != NULL) { - SEC_OSAL_Free(pMpeg4Enc); - pMpeg4Enc = ((SEC_OMX_VIDEOENC_COMPONENT *)pSECComponent->hComponentHandle)->hCodecHandle = NULL; - } - - ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h b/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h deleted file mode 100644 index aa32c42..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/SEC_OMX_Mpeg4enc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Mpeg4enc.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_MPEG4_ENC_COMPONENT -#define SEC_OMX_MPEG4_ENC_COMPONENT - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SsbSipMfcApi.h" - - -typedef enum _CODEC_TYPE -{ - CODEC_TYPE_H263, - CODEC_TYPE_MPEG4 -} CODEC_TYPE; - -typedef struct _SEC_MFC_MPEG4ENC_HANDLE -{ - OMX_HANDLETYPE hMFCHandle; - SSBSIP_MFC_ENC_MPEG4_PARAM mpeg4MFCParam; - SSBSIP_MFC_ENC_H263_PARAM h263MFCParam; - SSBSIP_MFC_ENC_INPUT_INFO inputInfo; - OMX_U32 indexTimestamp; - OMX_BOOL bConfiguredMFC; - CODEC_TYPE codecType; - OMX_S32 returnCodec; -} SEC_MFC_MPEG4ENC_HANDLE; - -typedef struct _SEC_MPEG4ENC_HANDLE -{ - /* OMX Codec specific */ - OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; - - /* SEC MFC Codec specific */ - SEC_MFC_MPEG4ENC_HANDLE hMFCMpeg4Handle; -} SEC_MPEG4ENC_HANDLE; - - -#ifdef __cplusplus -extern "C" { -#endif - - -OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); - OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.c b/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.c deleted file mode 100644 index d43b2d7..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "library_register.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_MPEG4_ENC" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) -{ - FunctionIn(); - - if (ppSECComponent == NULL) - goto EXIT; - - /* component 1 - video encoder MPEG4 */ - SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPONENT_MPEG4_ENC); - SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPONENT_MPEG4_ENC_ROLE); - ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - - /* component 2 - video encoder H.263 */ - SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPONENT_H263_ENC); - SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPONENT_H263_ENC_ROLE); - ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; - -EXIT: - FunctionOut(); - return MAX_COMPONENT_NUM; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.h b/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.h deleted file mode 100644 index 42a168b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/component/video/enc/mpeg4/library_register.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file library_register.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_MPEG4_ENC_REG -#define SEC_OMX_MPEG4_ENC_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Component.h" -#include "SEC_OMX_Component_Register.h" - - -#define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 2 -#define MAX_COMPONENT_ROLE_NUM 1 - -/* MPEG4 */ -#define SEC_OMX_COMPONENT_MPEG4_ENC "OMX.SEC.MPEG4.Encoder" -#define SEC_OMX_COMPONENT_MPEG4_ENC_ROLE "video_encoder.mpeg4" - -/* H.263 */ -#define SEC_OMX_COMPONENT_H263_ENC "OMX.SEC.H263.Encoder" -#define SEC_OMX_COMPONENT_H263_ENC_ROLE "video_encoder.h263" - - -#ifdef __cplusplus -extern "C" { -#endif - -OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); - -#ifdef __cplusplus -}; -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/core/Android.mk b/exynos4/multimedia/openmax/sec_omx/core/Android.mk deleted file mode 100644 index 8922e4b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/core/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := SEC_OMX_Component_Register.c \ - SEC_OMX_Core.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libSEC_OMX_Core - -LOCAL_CFLAGS := - -LOCAL_ARM_MODE := arm - -LOCAL_STATIC_LIBRARIES := libsecosal libsecbasecomponent -LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils \ - libSEC_OMX_Resourcemanager - -LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_TOP)/component/common - -include $(BUILD_SHARED_LIBRARY) - diff --git a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.c b/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.c deleted file mode 100644 index 27a8805..0000000 --- a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Component_Register.c - * @brief SEC OpenMAX IL Component Register - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OMX_Component.h" -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Library.h" -#include "SEC_OMX_Component_Register.h" -#include "SEC_OMX_Macros.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_COMP_REGS" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - int componentNum = 0, roleNum = 0, totalCompNum = 0; - int read; - char *libName; - size_t len; - const char *errorMsg; - DIR *dir; - struct dirent *d; - - int (*SEC_OMX_COMPONENT_Library_Register)(SECRegisterComponentType **secComponents); - SECRegisterComponentType **secComponentsTemp; - SEC_OMX_COMPONENT_REGLIST *componentList; - - FunctionIn(); - - dir = opendir(SEC_OMX_INSTALL_PATH); - if (dir == NULL) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - componentList = (SEC_OMX_COMPONENT_REGLIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); - SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); - libName = SEC_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); - - while ((d = readdir(dir)) != NULL) { - OMX_HANDLETYPE soHandle; - SEC_OSAL_Log(SEC_LOG_ERROR, "%s", d->d_name); - - if (SEC_OSAL_Strncmp(d->d_name, "libOMX.SEC.", SEC_OSAL_Strlen("libOMX.SEC.")) == 0) { - SEC_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); - SEC_OSAL_Strcpy(libName, SEC_OMX_INSTALL_PATH); - SEC_OSAL_Strcat(libName, d->d_name); - SEC_OSAL_Log(SEC_LOG_ERROR, "Path & libName : %s", libName); - if ((soHandle = SEC_OSAL_dlopen(libName, RTLD_NOW)) != NULL) { - SEC_OSAL_dlerror(); /* clear error*/ - if ((SEC_OMX_COMPONENT_Library_Register = SEC_OSAL_dlsym(soHandle, "SEC_OMX_COMPONENT_Library_Register")) != NULL) { - int i = 0; - unsigned int j = 0; - - componentNum = (*SEC_OMX_COMPONENT_Library_Register)(NULL); - secComponentsTemp = (SECRegisterComponentType **)SEC_OSAL_Malloc(sizeof(SECRegisterComponentType*) * componentNum); - for (i = 0; i < componentNum; i++) { - secComponentsTemp[i] = SEC_OSAL_Malloc(sizeof(SECRegisterComponentType)); - SEC_OSAL_Memset(secComponentsTemp[i], 0, sizeof(SECRegisterComponentType)); - } - (*SEC_OMX_COMPONENT_Library_Register)(secComponentsTemp); - - for (i = 0; i < componentNum; i++) { - SEC_OSAL_Strcpy(componentList[totalCompNum].component.componentName, secComponentsTemp[i]->componentName); - for (j = 0; j < secComponentsTemp[i]->totalRoleNum; j++) - SEC_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], secComponentsTemp[i]->roles[j]); - componentList[totalCompNum].component.totalRoleNum = secComponentsTemp[i]->totalRoleNum; - - SEC_OSAL_Strcpy(componentList[totalCompNum].libName, libName); - - totalCompNum++; - } - for (i = 0; i < componentNum; i++) { - SEC_OSAL_Free(secComponentsTemp[i]); - } - - SEC_OSAL_Free(secComponentsTemp); - } else { - if ((errorMsg = SEC_OSAL_dlerror()) != NULL) - SEC_OSAL_Log(SEC_LOG_WARNING, "dlsym failed: %s", errorMsg); - } - SEC_OSAL_dlclose(soHandle); - } else { - SEC_OSAL_Log(SEC_LOG_WARNING, "dlopen failed: %s", SEC_OSAL_dlerror()); - } - } else { - /* not a component name line. skip */ - continue; - } - } - - SEC_OSAL_Free(libName); - - closedir(dir); - - *compList = componentList; - *compNum = totalCompNum; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); - SEC_OSAL_Free(componentList); - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentAPICheck(OMX_COMPONENTTYPE *component) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if ((NULL == component->GetComponentVersion) || - (NULL == component->SendCommand) || - (NULL == component->GetParameter) || - (NULL == component->SetParameter) || - (NULL == component->GetConfig) || - (NULL == component->SetConfig) || - (NULL == component->GetExtensionIndex) || - (NULL == component->GetState) || - (NULL == component->ComponentTunnelRequest) || - (NULL == component->UseBuffer) || - (NULL == component->AllocateBuffer) || - (NULL == component->FreeBuffer) || - (NULL == component->EmptyThisBuffer) || - (NULL == component->FillThisBuffer) || - (NULL == component->SetCallbacks) || - (NULL == component->ComponentDeInit) || - (NULL == component->UseEGLImage) || - (NULL == component->ComponentRoleEnum)) - ret = OMX_ErrorInvalidComponent; - else - ret = OMX_ErrorNone; - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_HANDLETYPE libHandle; - OMX_COMPONENTTYPE *pOMXComponent; - - FunctionIn(); - - OMX_ERRORTYPE (*SEC_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); - - libHandle = SEC_OSAL_dlopen((OMX_STRING)sec_component->libName, RTLD_NOW); - if (!libHandle) { - ret = OMX_ErrorInvalidComponentName; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); - goto EXIT; - } - - SEC_OMX_ComponentInit = SEC_OSAL_dlsym(libHandle, "SEC_OMX_ComponentInit"); - if (!SEC_OMX_ComponentInit) { - SEC_OSAL_dlclose(libHandle); - ret = OMX_ErrorInvalidComponent; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)SEC_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); - INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); - ret = (*SEC_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, (OMX_STRING)sec_component->componentName); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Free(pOMXComponent); - SEC_OSAL_dlclose(libHandle); - ret = OMX_ErrorInvalidComponent; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); - goto EXIT; - } else { - if (SEC_OMX_ComponentAPICheck(pOMXComponent) != OMX_ErrorNone) { - if (NULL != pOMXComponent->ComponentDeInit) - pOMXComponent->ComponentDeInit(pOMXComponent); - SEC_OSAL_Free(pOMXComponent); - SEC_OSAL_dlclose(libHandle); - ret = OMX_ErrorInvalidComponent; - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); - goto EXIT; - } - sec_component->libHandle = libHandle; - sec_component->pOMXComponent = pOMXComponent; - ret = OMX_ErrorNone; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - - FunctionIn(); - - if (!sec_component) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pOMXComponent = sec_component->pOMXComponent; - if (pOMXComponent != NULL) { - pOMXComponent->ComponentDeInit(pOMXComponent); - SEC_OSAL_Free(pOMXComponent); - sec_component->pOMXComponent = NULL; - } - - if (sec_component->libHandle != NULL) { - SEC_OSAL_dlclose(sec_component->libHandle); - sec_component->libHandle = NULL; - } - -EXIT: - FunctionOut(); - - return ret; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.h b/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.h deleted file mode 100644 index 75b8ac5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Component_Register.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Component_Register.h - * @brief SEC OpenMAX IL Component Register - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_COMPONENT_REG -#define SEC_OMX_COMPONENT_REG - -#include "SEC_OMX_Def.h" -#include "OMX_Types.h" -#include "OMX_Core.h" -#include "OMX_Component.h" - - -typedef struct _SECRegisterComponentType -{ - OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; - OMX_U8 roles[MAX_OMX_COMPONENT_ROLE_NUM][MAX_OMX_COMPONENT_ROLE_SIZE]; - OMX_U32 totalRoleNum; -} SECRegisterComponentType; - -typedef struct _SEC_OMX_COMPONENT_REGLIST -{ - SECRegisterComponentType component; - OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; -} SEC_OMX_COMPONENT_REGLIST; - -struct SEC_OMX_COMPONENT; -typedef struct _SEC_OMX_COMPONENT -{ - OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; - OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; - OMX_HANDLETYPE libHandle; - OMX_COMPONENTTYPE *pOMXComponent; - struct _SEC_OMX_COMPONENT *nextOMXComp; -} SEC_OMX_COMPONENT; - - -#ifdef __cplusplus -extern "C" { -#endif - - -OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum); -OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList); -OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component); -OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.c b/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.c deleted file mode 100644 index fa7477b..0000000 --- a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Core.c - * @brief SEC OpenMAX IL Core - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OMX_Core.h" -#include "SEC_OMX_Component_Register.h" -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OMX_Resourcemanager.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_OMX_CORE" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -static int gInitialized = 0; -static OMX_U32 gComponentNum = 0; - -static SEC_OMX_COMPONENT_REGLIST *gComponentList = NULL; -static SEC_OMX_COMPONENT *gLoadComponentList = NULL; -static OMX_HANDLETYPE ghLoadComponentListMutex = NULL; - - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - FunctionIn(); - - if (gInitialized == 0) { - if (SEC_OMX_Component_Register(&gComponentList, &gComponentNum)) { - ret = OMX_ErrorInsufficientResources; - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : %s", "OMX_ErrorInsufficientResources"); - goto EXIT; - } - - ret = SEC_OMX_ResourceManager_Init(); - if (OMX_ErrorNone != ret) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : SEC_OMX_ResourceManager_Init failed"); - goto EXIT; - } - - ret = SEC_OSAL_MutexCreate(&ghLoadComponentListMutex); - if (OMX_ErrorNone != ret) { - SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : SEC_OSAL_MutexCreate(&ghLoadComponentListMutex) failed"); - goto EXIT; - } - - gInitialized = 1; - SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_Init : %s", "OMX_ErrorNone"); - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - FunctionIn(); - - SEC_OSAL_MutexTerminate(ghLoadComponentListMutex); - ghLoadComponentListMutex = NULL; - - SEC_OMX_ResourceManager_Deinit(); - - if (OMX_ErrorNone != SEC_OMX_Component_Unregister(gComponentList)) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - gComponentList = NULL; - gComponentNum = 0; - gInitialized = 0; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( - OMX_OUT OMX_STRING cComponentName, - OMX_IN OMX_U32 nNameLength, - OMX_IN OMX_U32 nIndex) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - - FunctionIn(); - - if (nIndex >= gComponentNum) { - ret = OMX_ErrorNoMore; - goto EXIT; - } - - snprintf(cComponentName, nNameLength, "%s", gComponentList[nIndex].component.componentName); - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( - OMX_OUT OMX_HANDLETYPE *pHandle, - OMX_IN OMX_STRING cComponentName, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_CALLBACKTYPE *pCallBacks) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_COMPONENT *loadComponent; - SEC_OMX_COMPONENT *currentComponent; - unsigned int i = 0; - - FunctionIn(); - - if (gInitialized != 1) { - ret = OMX_ErrorNotReady; - goto EXIT; - } - - if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - SEC_OSAL_Log(SEC_LOG_TRACE, "ComponentName : %s", cComponentName); - - for (i = 0; i < gComponentNum; i++) { - if (SEC_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { - loadComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT)); - SEC_OSAL_Memset(loadComponent, 0, sizeof(SEC_OMX_COMPONENT)); - - SEC_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); - SEC_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); - ret = SEC_OMX_ComponentLoad(loadComponent); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Free(loadComponent); - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData); - if (ret != OMX_ErrorNone) { - SEC_OMX_ComponentUnload(loadComponent); - SEC_OSAL_Free(loadComponent); - SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); - goto EXIT; - } - - SEC_OSAL_MutexLock(ghLoadComponentListMutex); - if (gLoadComponentList == NULL) { - gLoadComponentList = loadComponent; - } else { - currentComponent = gLoadComponentList; - while (currentComponent->nextOMXComp != NULL) { - currentComponent = currentComponent->nextOMXComp; - } - currentComponent->nextOMXComp = loadComponent; - } - SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); - - *pHandle = loadComponent->pOMXComponent; - ret = OMX_ErrorNone; - SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_GetHandle : %s", "OMX_ErrorNone"); - goto EXIT; - } - } - - ret = OMX_ErrorComponentNotFound; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_OMX_COMPONENT *currentComponent; - SEC_OMX_COMPONENT *deleteComponent; - - FunctionIn(); - - if (gInitialized != 1) { - ret = OMX_ErrorNotReady; - goto EXIT; - } - - if (!hComponent) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - SEC_OSAL_MutexLock(ghLoadComponentListMutex); - currentComponent = gLoadComponentList; - if (gLoadComponentList->pOMXComponent == hComponent) { - deleteComponent = gLoadComponentList; - gLoadComponentList = gLoadComponentList->nextOMXComp; - } else { - while ((currentComponent != NULL) && (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) - currentComponent = currentComponent->nextOMXComp; - - if (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) { - deleteComponent = currentComponent->nextOMXComp; - currentComponent->nextOMXComp = deleteComponent->nextOMXComp; - } else if (currentComponent == NULL) { - ret = OMX_ErrorComponentNotFound; - SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); - goto EXIT; - } - } - SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); - - SEC_OMX_ComponentUnload(deleteComponent); - SEC_OSAL_Free(deleteComponent); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( - OMX_IN OMX_HANDLETYPE hOutput, - OMX_IN OMX_U32 nPortOutput, - OMX_IN OMX_HANDLETYPE hInput, - OMX_IN OMX_U32 nPortInput) -{ - OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; - -EXIT: - return ret; -} - -OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( - OMX_OUT OMX_HANDLETYPE *hPipe, - OMX_IN OMX_STRING szURI) -{ - OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; - -EXIT: - return ret; -} - -OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole ( - OMX_IN OMX_STRING role, - OMX_INOUT OMX_U32 *pNumComps, - OMX_INOUT OMX_U8 **compNames) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - int max_role_num = 0; - OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE]; - int i = 0, j = 0; - - FunctionIn(); - - if (gInitialized != 1) { - ret = OMX_ErrorNotReady; - goto EXIT; - } - - *pNumComps = 0; - - for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { - max_role_num = gComponentList[i].component.totalRoleNum; - - for (j = 0; j < max_role_num; j++) { - if (SEC_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { - if (compNames != NULL) { - SEC_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); - } - *pNumComps = (*pNumComps + 1); - } - } - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent ( - OMX_IN OMX_STRING compName, - OMX_INOUT OMX_U32 *pNumRoles, - OMX_OUT OMX_U8 **roles) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_BOOL detectComp = OMX_FALSE; - int compNum = 0, totalRoleNum = 0; - int i = 0; - - FunctionIn(); - - if (gInitialized != 1) { - ret = OMX_ErrorNotReady; - goto EXIT; - } - - for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { - if (gComponentList != NULL) { - if (SEC_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) { - *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum; - compNum = i; - detectComp = OMX_TRUE; - break; - } - } else { - ret = OMX_ErrorUndefined; - goto EXIT; - } - } - - if (detectComp == OMX_FALSE) { - *pNumRoles = 0; - ret = OMX_ErrorComponentNotFound; - goto EXIT; - } - - if (roles != NULL) { - for (i = 0; i < totalRoleNum; i++) { - SEC_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); - } - } - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.h b/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.h deleted file mode 100644 index c60cd52..0000000 --- a/exynos4/multimedia/openmax/sec_omx/core/SEC_OMX_Core.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Core.h - * @brief SEC OpenMAX IL Core - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * HyeYeon Chung (hyeon.chung@samsung.com) - * Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_CORE -#define SEC_OMX_CORE - -#include "SEC_OMX_Def.h" -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( - OMX_OUT OMX_STRING cComponentName, - OMX_IN OMX_U32 nNameLength, - OMX_IN OMX_U32 nIndex); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( - OMX_OUT OMX_HANDLETYPE *pHandle, - OMX_IN OMX_STRING cComponentName, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_CALLBACKTYPE *pCallBacks); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle( - OMX_IN OMX_HANDLETYPE hComponent); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( - OMX_IN OMX_HANDLETYPE hOutput, - OMX_IN OMX_U32 nPortOutput, - OMX_IN OMX_HANDLETYPE hInput, - OMX_IN OMX_U32 nPortInput); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( - OMX_OUT OMX_HANDLETYPE *hPipe, - OMX_IN OMX_STRING szURI); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole( - OMX_IN OMX_STRING role, - OMX_INOUT OMX_U32 *pNumComps, - OMX_INOUT OMX_U8 **compNames); -SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent( - OMX_IN OMX_STRING compName, - OMX_INOUT OMX_U32 *pNumRoles, - OMX_OUT OMX_U8 **roles); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Audio.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Audio.h deleted file mode 100644 index 04f1a99..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Audio.h +++ /dev/null @@ -1,1311 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** @file OMX_Audio.h - OpenMax IL version 1.1.2 - * The structures needed by Audio components to exchange - * parameters and configuration data with the componenmilts. - */ - -#ifndef OMX_Audio_h -#define OMX_Audio_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - -/** @defgroup midi MIDI - * @ingroup audio - */ - -/** @defgroup effects Audio effects - * @ingroup audio - */ - -/** @defgroup audio OpenMAX IL Audio Domain - * Structures for OpenMAX IL Audio domain - * @{ - */ - -/** Enumeration used to define the possible audio codings. - * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must - * be done in a vendor specific way. Since this is for an audio - * processing element this enum is relevant. However, for another - * type of component other enums would be in this area. - */ -typedef enum OMX_AUDIO_CODINGTYPE { - OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ - OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ - OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ - OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ - OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ - OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ - OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ - OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ - OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ - OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ - OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ - OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ - OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ - OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ - OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ - OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ - OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ - OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ - OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ - OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ - OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ - OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ - OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ - OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ - OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ - OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ - OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ - OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ - OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_CodingMax = 0x7FFFFFFF -} OMX_AUDIO_CODINGTYPE; - - -/** The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output audio - * path. If additional information is needed to define the parameters of the - * port (such as frequency), additional structures must be sent such as the - * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. - */ -typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; /**< MIME type of data for the port */ - OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference - for an output device, - otherwise this field is 0 */ - OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is - supported by the OMX component */ - OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this - port (e.g. PCM, AMR, MP3, etc) */ -} OMX_AUDIO_PORTDEFINITIONTYPE; - - -/** Port format parameter. This structure is used to enumerate - * the various data input/output format supported by the port. - */ -typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Indicates which port to set */ - OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ - OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ -} OMX_AUDIO_PARAM_PORTFORMATTYPE; - - -/** PCM mode type */ -typedef enum OMX_AUDIO_PCMMODETYPE { - OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ - OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ - OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ - OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_PCMModeMax = 0x7FFFFFFF -} OMX_AUDIO_PCMMODETYPE; - - -typedef enum OMX_AUDIO_CHANNELTYPE { - OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ - OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ - OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ - OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ - OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ - OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ - OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ - OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ - OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ - OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ - OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_ChannelMax = 0x7FFFFFFF -} OMX_AUDIO_CHANNELTYPE; - -#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ -#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ - -/** PCM format description */ -typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ - OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ - OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ - OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for - non-interleaved data (e.g. block data) */ - OMX_U32 nBitPerSample; /**< Bit per sample */ - OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ - OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ - -} OMX_AUDIO_PARAM_PCMMODETYPE; - - -/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate - * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. - */ -typedef enum OMX_AUDIO_CHANNELMODETYPE { - OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those - two channels changes accordingly to each channel information */ - OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between - 2 channels for higher compression gain */ - OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half - the bitrate of the overall bitrate */ - OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ - OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF -} OMX_AUDIO_CHANNELMODETYPE; - - -typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { - OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF -} OMX_AUDIO_MP3STREAMFORMATTYPE; - -/** MP3 params */ -typedef struct OMX_AUDIO_PARAM_MP3TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ - OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ -} OMX_AUDIO_PARAM_MP3TYPE; - - -typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { - OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ - OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ - OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ - OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ - OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ - OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ - OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ - OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF -} OMX_AUDIO_AACSTREAMFORMATTYPE; - - -/** AAC mode type. Note that the term profile is used with the MPEG-2 - * standard and the term object type and profile is used with MPEG-4 */ -typedef enum OMX_AUDIO_AACPROFILETYPE{ - OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ - OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ - OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ - OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ - OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ - OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ - OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ - OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ - OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ - OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ - OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AACObjectMax = 0x7FFFFFFF -} OMX_AUDIO_AACPROFILETYPE; - - -/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). - * Required for encoder configuration and optional as decoder info output. - * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ -#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ -#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ -#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ -#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ -#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ -#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ -#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ - -/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). - * Required for ER encoder configuration and optional as decoder info output */ -#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ -#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ -#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ -#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ -#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ - - -/** AAC params */ -typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. - Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). - Use 0 to let encoder decide */ - OMX_U32 nAACtools; /**< AAC tool usage */ - OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ - OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ - OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ -} OMX_AUDIO_PARAM_AACPROFILETYPE; - - -/** VORBIS params */ -typedef struct OMX_AUDIO_PARAM_VORBISTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable - rate or unknown bit rates. Encoding is set to the - bitrate closest to specified value (in bps) */ - OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ - OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ - - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). - In the default mode of operation, teh quality level is 3. - Normal quality range is 0 - 10. */ - OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the - normal VBR encoding, but allows hard or soft bitrate - constraints to be enforced by the encoder. This mode can - be slower, and may also be lower quality. It is - primarily useful for streaming. */ - OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on - non-stereo streams). Useful for lower-bitrate encoding. */ -} OMX_AUDIO_PARAM_VORBISTYPE; - - -/** WMA Version */ -typedef enum OMX_AUDIO_WMAFORMATTYPE { - OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ - OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ - OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ - OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ - OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF -} OMX_AUDIO_WMAFORMATTYPE; - - -/** WMA Profile */ -typedef enum OMX_AUDIO_WMAPROFILETYPE { - OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ - OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ - OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ - OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ - OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF -} OMX_AUDIO_WMAPROFILETYPE; - - -/** WMA params */ -typedef struct OMX_AUDIO_PARAM_WMATYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U16 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ - OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ - OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ - OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ - OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ - OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ -} OMX_AUDIO_PARAM_WMATYPE; - -/** - * RealAudio format - */ -typedef enum OMX_AUDIO_RAFORMATTYPE { - OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ - OMX_AUDIO_RA8, /**< RealAudio 8 codec */ - OMX_AUDIO_RA9, /**< RealAudio 9 codec */ - OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ - OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ - OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ - OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ - OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ - OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_RAFormatMax = 0x7FFFFFFF -} OMX_AUDIO_RAFORMATTYPE; - -/** RA (Real Audio) params */ -typedef struct OMX_AUDIO_PARAM_RATYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ - OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ - OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ - OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ - OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ - OMX_U32 nNumRegions; /**< is the number of regions value */ - OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ -} OMX_AUDIO_PARAM_RATYPE; - - -/** SBC Allocation Method Type */ -typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { - OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ - OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ - OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF -} OMX_AUDIO_SBCALLOCMETHODTYPE; - - -/** SBC params */ -typedef struct OMX_AUDIO_PARAM_SBCTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nBlocks; /**< Number of blocks */ - OMX_U32 nSubbands; /**< Number of subbands */ - OMX_U32 nBitPool; /**< Bitpool value */ - OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ - OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ -} OMX_AUDIO_PARAM_SBCTYPE; - - -/** ADPCM stream format parameters */ -typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ -} OMX_AUDIO_PARAM_ADPCMTYPE; - - -/** G723 rate */ -typedef enum OMX_AUDIO_G723RATE { - OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ - OMX_AUDIO_G723ModeLow, /**< 5300 bps */ - OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ - OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G723ModeMax = 0x7FFFFFFF -} OMX_AUDIO_G723RATE; - - -/** G723 - Sample rate must be 8 KHz */ -typedef struct OMX_AUDIO_PARAM_G723TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ - OMX_BOOL bPostFilter; /**< Enable Post Filter */ -} OMX_AUDIO_PARAM_G723TYPE; - - -/** ITU G726 (ADPCM) rate */ -typedef enum OMX_AUDIO_G726MODE { - OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ - OMX_AUDIO_G726Mode16, /**< 16 kbps */ - OMX_AUDIO_G726Mode24, /**< 24 kbps */ - OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ - OMX_AUDIO_G726Mode40, /**< 40 kbps */ - OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G726ModeMax = 0x7FFFFFFF -} OMX_AUDIO_G726MODE; - - -/** G.726 stream format parameters - must be at 8KHz */ -typedef struct OMX_AUDIO_PARAM_G726TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_G726MODE eG726Mode; -} OMX_AUDIO_PARAM_G726TYPE; - - -/** G729 coder type */ -typedef enum OMX_AUDIO_G729TYPE { - OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ - OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ - OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ - OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ - OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G729Max = 0x7FFFFFFF -} OMX_AUDIO_G729TYPE; - - -/** G729 stream format parameters - fixed 6KHz sample rate */ -typedef struct OMX_AUDIO_PARAM_G729TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_AUDIO_G729TYPE eBitType; -} OMX_AUDIO_PARAM_G729TYPE; - - -/** AMR Frame format */ -typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { - OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance - (Standard) Format */ - OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface - Format 1 */ - OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface - Format 2*/ - OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage - Format */ - OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time - Transport Protocol Payload Format */ - OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ - OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF -} OMX_AUDIO_AMRFRAMEFORMATTYPE; - - -/** AMR band mode */ -typedef enum OMX_AUDIO_AMRBANDMODETYPE { - OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ - OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ - OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ - OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ - OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ - OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ - OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ - OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ - OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ - OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ - OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ - OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ - OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ - OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ - OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ - OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ - OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ - OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ - OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF -} OMX_AUDIO_AMRBANDMODETYPE; - - -/** AMR Discontinuous Transmission mode */ -typedef enum OMX_AUDIO_AMRDTXMODETYPE { - OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ - OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using - Voice Activity Detector 1 (VAD1) is enabled */ - OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using - Voice Activity Detector 2 (VAD2) is enabled */ - OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between - Off, VAD1 or VAD2 modes */ - - OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ - - OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF -} OMX_AUDIO_AMRDTXMODETYPE; - - -/** AMR params */ -typedef struct OMX_AUDIO_PARAM_AMRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate read only field */ - OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ - OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ - OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ -} OMX_AUDIO_PARAM_AMRTYPE; - - -/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMFRTYPE; - - -/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMHRTYPE; - - -/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMEFRTYPE; - - -/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_TDMAFRTYPE; - - -/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_TDMAEFRTYPE; - - -/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCFRTYPE; - - -/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCEFRTYPE; - -/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCHRTYPE; - - -/** CDMA Rate types */ -typedef enum OMX_AUDIO_CDMARATETYPE { - OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ - OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ - OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ - OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ - OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ - OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ - OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_CDMARateMax = 0x7FFFFFFF -} OMX_AUDIO_CDMARATETYPE; - - -/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ -} OMX_AUDIO_PARAM_QCELP8TYPE; - - -/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ -} OMX_AUDIO_PARAM_QCELP13TYPE; - - -/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_EVRCTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ - OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ - OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ - OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ - OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ -} OMX_AUDIO_PARAM_EVRCTYPE; - - -/** SMV ( up to 8.55kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_SMVTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ - OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ - OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ - OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ -} OMX_AUDIO_PARAM_SMVTYPE; - - -/** MIDI Format - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDIFORMATTYPE -{ - OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ - OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ - OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ - OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ - OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ - OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ - OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ - OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ - OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF -} OMX_AUDIO_MIDIFORMATTYPE; - - -/** MIDI params - * @ingroup midi - */ -typedef struct OMX_AUDIO_PARAM_MIDITYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire - MIDI file passed in, otherwise if 0x0, the MIDI data - is merged and streamed (instead of passed as an - entire MIDI file) */ - OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic - voices. A value of zero indicates that the default - polyphony of the device is used */ - OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound - bank at initialization */ - OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ -} OMX_AUDIO_PARAM_MIDITYPE; - - -/** Type of the MIDI sound bank - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { - OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ - OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ - OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ - OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ - OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ - OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF -} OMX_AUDIO_MIDISOUNDBANKTYPE; - - -/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { - OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ - OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ - OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ - OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ - OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF -} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; - - -/** MIDI params to load/unload user soundbank - * @ingroup midi - */ -typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ - OMX_U32 nDLSSize; /**< Size in bytes */ - OMX_PTR pDLSData; /**< Pointer to DLS file data */ - OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ - OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ -} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; - - -/** Structure for Live MIDI events and MIP messages. - * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ - OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an - array for the MIP message buffer, where the size is - indicated by nMidiEventSize */ -} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; - - -/** MIDI sound bank/ program pair in a given channel - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ - OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ - OMX_U16 nIDSoundBank; /**< Sound bank ID */ - OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks - by index if multiple banks are present */ -} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; - - -/** MIDI control - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 - format based on JAVA MMAPI (JSR-135) requirement */ - OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point - number based on JSR-135 requirement */ - OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 - fixed-point number based on JSR-135 requirement */ - OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic - voices. A value of zero indicates that the default - polyphony of the device is used */ - OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ - OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback - will stop automatically. Set to zero if not used */ - OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ - OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ - OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ - OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ - OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ - OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ - -} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; - - -/** MIDI Playback States - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { - OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to - other defined states */ - OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. - The MIDI engine is currently processing - MIDI events. */ - OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being - primed. The MIDI engine is currently - processing MIDI events. */ - OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but - not playing. The MIDI engine is currently - processing MIDI events. The transition to - this state is only possible from the - OMX_AUDIO_MIDIPlayBackStatePlaying state, - when the 'playback head' reaches the end - of media data or the playback stops due - to stop time set.*/ - OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently - playing. The MIDI engine is currently - processing MIDI events.*/ - OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS - resource constraints */ - OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and - SP-MIDI content constraints, there is - no audible MIDI content during playback - currently. The situation may change if - resources are freed later.*/ - OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF -} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; - - -/** MIDI status - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. - NOTE: May not return a meaningful value until the entire - file is parsed and buffered. */ - OMX_U32 nDuration; /**< The length of the currently open MIDI resource - in milliseconds. NOTE: May not return a meaningful value - until the entire file is parsed and buffered. */ - OMX_U32 nPosition; /**< Current Position of the MIDI resource being played - in milliseconds */ - OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful - value until the entire file is parsed and buffered. */ - OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently - open MIDI resource. NOTE: May not return a meaningful value - until the entire file is parsed and buffered. */ - OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing - MIDI resource. NOTE: May not return a meaningful value until - the entire file is parsed and buffered. */ - OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ -} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; - - -/** MIDI Meta Event structure one per Meta Event. - * MIDI Meta Events are like audio metadata, except that they are interspersed - * with the MIDI content throughout the file and are not localized in the header. - * As such, it is necessary to retrieve information about these Meta Events from - * the engine, as it encounters these Meta Events within the MIDI content. - * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, - * author, default tempo, etc.) scattered throughout the file. - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nIndex; /**< Index of Meta Event */ - OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ - OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ - OMX_U32 nTrack; /**< track number for the meta event */ - OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ -} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; - - -/** MIDI Meta Event Data structure - one per Meta Event. - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nIndex; /**< Index of Meta Event */ - OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ - OMX_U8 nData[1]; /**< array of one or more bytes of meta data - as indicated by the nMetaEventSize field */ -} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; - - -/** Audio Volume adjustment for a port */ -typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's volume. Select the - output port to adjust the master - volume. */ - OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) - or logarithmic scale (mB) */ - OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR - Volume logarithmic setting for this port. The values - for volume are in mB (millibels = 1/100 dB) relative - to a gain of 1 (e.g. the output is the same as the - input level). Values are in mB from nMax - (maximum volume) to nMin mB (typically negative). - Since the volume is "voltage" - and not a "power", it takes a setting of - -600 mB to decrease the volume by 1/2. If - a component cannot accurately set the - volume to the requested value, it must - set the volume to the closest value BELOW - the requested value. When getting the - volume setting, the current actual volume - must be returned. */ -} OMX_AUDIO_CONFIG_VOLUMETYPE; - - -/** Audio Volume adjustment for a channel */ -typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's volume. Select the - output port to adjust the master - volume. */ - OMX_U32 nChannel; /**< channel to select from 0 to N-1, - using OMX_ALL to apply volume settings - to all channels */ - OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or - logarithmic scale (mB) */ - OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR - Volume logarithmic setting for this port. - The values for volume are in mB - (millibels = 1/100 dB) relative to a gain - of 1 (e.g. the output is the same as the - input level). Values are in mB from nMax - (maximum volume) to nMin mB (typically negative). - Since the volume is "voltage" - and not a "power", it takes a setting of - -600 mB to decrease the volume by 1/2. If - a component cannot accurately set the - volume to the requested value, it must - set the volume to the closest value BELOW - the requested value. When getting the - volume setting, the current actual volume - must be returned. */ - OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, - FALSE otherwise */ -} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; - - -/** Audio balance setting */ -typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's balance. Select the - output port to adjust the master - balance. */ - OMX_S32 nBalance; /**< balance setting for this port - (-100 to 100, where -100 indicates - all left, and no right */ -} OMX_AUDIO_CONFIG_BALANCETYPE; - - -/** Audio Port mute */ -typedef struct OMX_AUDIO_CONFIG_MUTETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's mute. Select the - output port to adjust the master - mute. */ - OMX_BOOL bMute; /**< Mute setting for this port */ -} OMX_AUDIO_CONFIG_MUTETYPE; - - -/** Audio Channel mute */ -typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannel; /**< channel to select from 0 to N-1, - using OMX_ALL to apply mute settings - to all channels */ - OMX_BOOL bMute; /**< Mute setting for this channel */ - OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, - FALSE otherwise */ -} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; - - - -/** Enable / Disable for loudness control, which boosts bass and to a - * smaller extent high end frequencies to compensate for hearing - * ability at the extreme ends of the audio spectrum - */ -typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bLoudness; /**< Enable/disable for loudness */ -} OMX_AUDIO_CONFIG_LOUDNESSTYPE; - - -/** Enable / Disable for bass, which controls low frequencies - */ -typedef struct OMX_AUDIO_CONFIG_BASSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for bass control */ - OMX_S32 nBass; /**< bass setting for the port, as a - continuous value from -100 to 100 - (0 means no change in bass level)*/ -} OMX_AUDIO_CONFIG_BASSTYPE; - - -/** Enable / Disable for treble, which controls high frequencies tones - */ -typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for treble control */ - OMX_S32 nTreble; /**< treble setting for the port, as a - continuous value from -100 to 100 - (0 means no change in treble level) */ -} OMX_AUDIO_CONFIG_TREBLETYPE; - - -/** An equalizer is typically used for two reasons: to compensate for an - * sub-optimal frequency response of a system to make it sound more natural - * or to create intentionally some unnatural coloring to the sound to create - * an effect. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for equalizer */ - OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is - N-1, where N is the number of bands, lower limit is 0 */ - OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a - read only element and is used to determine - the lower, center and upper frequency of - this band. */ - OMX_BS32 sBandLevel; /**< band level in millibels */ -} OMX_AUDIO_CONFIG_EQUALIZERTYPE; - - -/** Stereo widening mode type - * @ingroup effects - */ -typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { - OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ - OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ - OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF -} OMX_AUDIO_STEREOWIDENINGTYPE; - - -/** Control for stereo widening, which is a special 2-channel - * case of the audio virtualizer effect. For example, for 5.1-channel - * output, it translates to virtual surround sound. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ - OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ - OMX_U32 nStereoWidening; /**< stereo widening setting for the port, - as a continuous value from 0 to 100 */ -} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; - - -/** The chorus effect (or ``choralizer'') is any signal processor which makes - * one sound source (such as a voice) sound like many such sources singing - * (or playing) in unison. Since performance in unison is never exact, chorus - * effects simulate this by making independently modified copies of the input - * signal. Modifications may include (1) delay, (2) frequency shift, and - * (3) amplitude modulation. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for chorus */ - OMX_BU32 sDelay; /**< average delay in milliseconds */ - OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ - OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of - delay (i.e. 0 to 100) */ - OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ -} OMX_AUDIO_CONFIG_CHORUSTYPE; - - -/** Reverberation is part of the reflected sound that follows the early - * reflections. In a typical room, this consists of a dense succession of - * echoes whose energy decays exponentially. The reverberation effect structure - * as defined here includes both (early) reflections as well as (late) reverberations. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ - OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect - (i.e. both early reflections and late - reverberation) in millibels */ - OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies - relative to the intensity at low - frequencies in millibels */ - OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections - (relative to room value), in millibels */ - OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative - to the direct path, in milliseconds */ - OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation - relative to room level, in millibels */ - OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection - to the beginning of the late reverberation - section, in milliseconds */ - OMX_BU32 sDecayTime; /**< Late reverberation decay time at low - frequencies, in milliseconds */ - OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative - to low frequency decay time in percent */ - OMX_U32 nDensity; /**< Modal density in the late reverberation decay, - in percent (i.e. 0 - 100) */ - OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, - in percent (i.e. 0 - 100) */ - OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is - the frequency used as the reference for all - the high-frequency settings above */ - -} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; - - -/** Possible settings for the Echo Cancelation structure to use - * @ingroup effects - */ -typedef enum OMX_AUDIO_ECHOCANTYPE { - OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ - OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - - echo from plastics and face */ - OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for - Hands Free operation */ - OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for - Car Kit (longer echo) */ - OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_EchoCanMax = 0x7FFFFFFF -} OMX_AUDIO_ECHOCANTYPE; - - -/** Enable / Disable for echo cancelation, which removes undesired echo's - * from the audio - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ -} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; - - -/** Enable / Disable for noise reduction, which undesired noise from - * the audio - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ -} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Component.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Component.h deleted file mode 100644 index d595640..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Component.h +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Component.h - OpenMax IL version 1.1.2 - * The OMX_Component header file contains the definitions used to define - * the public interface of a component. This header file is intended to - * be used by both the application and the component. - */ - -#ifndef OMX_Component_h -#define OMX_Component_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include -#include -#include -#include - -/** @ingroup comp */ -typedef enum OMX_PORTDOMAINTYPE { - OMX_PortDomainAudio, - OMX_PortDomainVideo, - OMX_PortDomainImage, - OMX_PortDomainOther, - OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_PortDomainMax = 0x7ffffff -} OMX_PORTDOMAINTYPE; - -/** @ingroup comp */ -typedef struct OMX_PARAM_PORTDEFINITIONTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port number the structure applies to */ - OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ - OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ - OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ - OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ - OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by - OMX_CommandPortEnable/OMX_CommandPortDisable. - When disabled a port is unpopulated. A disabled port - is not populated with buffers on a transition to IDLE. */ - OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by - nBufferCountActual. A disabled port is always unpopulated. - An enabled port is populated on a transition to OMX_StateIdle - and unpopulated on a transition to loaded. */ - OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ - union { - OMX_AUDIO_PORTDEFINITIONTYPE audio; - OMX_VIDEO_PORTDEFINITIONTYPE video; - OMX_IMAGE_PORTDEFINITIONTYPE image; - OMX_OTHER_PORTDEFINITIONTYPE other; - } format; - OMX_BOOL bBuffersContiguous; - OMX_U32 nBufferAlignment; -} OMX_PARAM_PORTDEFINITIONTYPE; - -/** @ingroup comp */ -typedef struct OMX_PARAM_U32TYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nU32; /**< U32 value */ -} OMX_PARAM_U32TYPE; - -/** @ingroup rpm */ -typedef enum OMX_SUSPENSIONPOLICYTYPE { - OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ - OMX_SuspensionEnabled, /**< Suspension allowed */ - OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_SuspensionPolicyMax = 0x7fffffff -} OMX_SUSPENSIONPOLICYTYPE; - -/** @ingroup rpm */ -typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_SUSPENSIONPOLICYTYPE ePolicy; -} OMX_PARAM_SUSPENSIONPOLICYTYPE; - -/** @ingroup rpm */ -typedef enum OMX_SUSPENSIONTYPE { - OMX_NotSuspended, /**< component is not suspended */ - OMX_Suspended, /**< component is suspended */ - OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_SuspendMax = 0x7FFFFFFF -} OMX_SUSPENSIONTYPE; - -/** @ingroup rpm */ -typedef struct OMX_PARAM_SUSPENSIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_SUSPENSIONTYPE eType; -} OMX_PARAM_SUSPENSIONTYPE ; - -typedef struct OMX_CONFIG_BOOLEANTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bEnabled; -} OMX_CONFIG_BOOLEANTYPE; - -/* Parameter specifying the content uri to use. */ -/** @ingroup cp */ -typedef struct OMX_PARAM_CONTENTURITYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes, including - actual URI name */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8 contentURI[1]; /**< The URI name */ -} OMX_PARAM_CONTENTURITYPE; - -/* Parameter specifying the pipe to use. */ -/** @ingroup cp */ -typedef struct OMX_PARAM_CONTENTPIPETYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_HANDLETYPE hPipe; /**< The pipe handle*/ -} OMX_PARAM_CONTENTPIPETYPE; - -/** @ingroup rpm */ -typedef struct OMX_RESOURCECONCEALMENTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment - methods (like degrading algorithm quality to - lower resource consumption or functional bypass) - on a component as a resolution to resource conflicts. */ -} OMX_RESOURCECONCEALMENTTYPE; - - -/** @ingroup metadata */ -typedef enum OMX_METADATACHARSETTYPE { - OMX_MetadataCharsetUnknown = 0, - OMX_MetadataCharsetASCII, - OMX_MetadataCharsetBinary, - OMX_MetadataCharsetCodePage1252, - OMX_MetadataCharsetUTF8, - OMX_MetadataCharsetJavaConformantUTF8, - OMX_MetadataCharsetUTF7, - OMX_MetadataCharsetImapUTF7, - OMX_MetadataCharsetUTF16LE, - OMX_MetadataCharsetUTF16BE, - OMX_MetadataCharsetGB12345, - OMX_MetadataCharsetHZGB2312, - OMX_MetadataCharsetGB2312, - OMX_MetadataCharsetGB18030, - OMX_MetadataCharsetGBK, - OMX_MetadataCharsetBig5, - OMX_MetadataCharsetISO88591, - OMX_MetadataCharsetISO88592, - OMX_MetadataCharsetISO88593, - OMX_MetadataCharsetISO88594, - OMX_MetadataCharsetISO88595, - OMX_MetadataCharsetISO88596, - OMX_MetadataCharsetISO88597, - OMX_MetadataCharsetISO88598, - OMX_MetadataCharsetISO88599, - OMX_MetadataCharsetISO885910, - OMX_MetadataCharsetISO885913, - OMX_MetadataCharsetISO885914, - OMX_MetadataCharsetISO885915, - OMX_MetadataCharsetShiftJIS, - OMX_MetadataCharsetISO2022JP, - OMX_MetadataCharsetISO2022JP1, - OMX_MetadataCharsetISOEUCJP, - OMX_MetadataCharsetSMS7Bit, - OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataCharsetTypeMax= 0x7FFFFFFF -} OMX_METADATACHARSETTYPE; - -/** @ingroup metadata */ -typedef enum OMX_METADATASCOPETYPE -{ - OMX_MetadataScopeAllLevels, - OMX_MetadataScopeTopLevel, - OMX_MetadataScopePortLevel, - OMX_MetadataScopeNodeLevel, - OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataScopeTypeMax = 0x7fffffff -} OMX_METADATASCOPETYPE; - -/** @ingroup metadata */ -typedef enum OMX_METADATASEARCHMODETYPE -{ - OMX_MetadataSearchValueSizeByIndex, - OMX_MetadataSearchItemByIndex, - OMX_MetadataSearchNextItemByKey, - OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataSearchTypeMax = 0x7fffffff -} OMX_METADATASEARCHMODETYPE; -/** @ingroup metadata */ -typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_METADATASCOPETYPE eScopeMode; - OMX_U32 nScopeSpecifier; - OMX_U32 nMetadataItemCount; -} OMX_CONFIG_METADATAITEMCOUNTTYPE; - -/** @ingroup metadata */ -typedef struct OMX_CONFIG_METADATAITEMTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_METADATASCOPETYPE eScopeMode; - OMX_U32 nScopeSpecifier; - OMX_U32 nMetadataItemIndex; - OMX_METADATASEARCHMODETYPE eSearchMode; - OMX_METADATACHARSETTYPE eKeyCharset; - OMX_U8 nKeySizeUsed; - OMX_U8 nKey[128]; - OMX_METADATACHARSETTYPE eValueCharset; - OMX_STRING sLanguageCountry; - OMX_U32 nValueMaxSize; - OMX_U32 nValueSizeUsed; - OMX_U8 nValue[1]; -} OMX_CONFIG_METADATAITEMTYPE; - -/* @ingroup metadata */ -typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; - OMX_U32 nParentNodeID; - OMX_U32 nNumNodes; -} OMX_CONFIG_CONTAINERNODECOUNTTYPE; - -/** @ingroup metadata */ -typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; - OMX_U32 nParentNodeID; - OMX_U32 nNodeIndex; - OMX_U32 nNodeID; - OMX_STRING cNodeName; - OMX_BOOL bIsLeafType; -} OMX_CONFIG_CONTAINERNODEIDTYPE; - -/** @ingroup metadata */ -typedef struct OMX_PARAM_METADATAFILTERTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and - * the three key fields below are ignored */ - OMX_METADATACHARSETTYPE eKeyCharset; - OMX_U32 nKeySizeUsed; - OMX_U8 nKey [128]; - OMX_U32 nLanguageCountrySizeUsed; - OMX_U8 nLanguageCountry[128]; - OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. - * retained for query later). If false then - * key is not part of filter */ -} OMX_PARAM_METADATAFILTERTYPE; - -/** The OMX_HANDLETYPE structure defines the component handle. The component - * handle is used to access all of the component's public methods and also - * contains pointers to the component's private data area. The component - * handle is initialized by the OMX core (with help from the component) - * during the process of loading the component. After the component is - * successfully loaded, the application can safely access any of the - * component's public functions (although some may return an error because - * the state is inappropriate for the access). - * - * @ingroup comp - */ -typedef struct OMX_COMPONENTTYPE -{ - /** The size of this structure, in bytes. It is the responsibility - of the allocator of this structure to fill in this value. Since - this structure is allocated by the GetHandle function, this - function will fill in this value. */ - OMX_U32 nSize; - - /** nVersion is the version of the OMX specification that the structure - is built against. It is the responsibility of the creator of this - structure to initialize this value and every user of this structure - should verify that it knows how to use the exact version of - this structure found herein. */ - OMX_VERSIONTYPE nVersion; - - /** pComponentPrivate is a pointer to the component private data area. - This member is allocated and initialized by the component when the - component is first loaded. The application should not access this - data area. */ - OMX_PTR pComponentPrivate; - - /** pApplicationPrivate is a pointer that is a parameter to the - OMX_GetHandle method, and contains an application private value - provided by the IL client. This application private data is - returned to the IL Client by OMX in all callbacks */ - OMX_PTR pApplicationPrivate; - - /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL - specification for details on the GetComponentVersion method. - */ - OMX_ERRORTYPE (*GetComponentVersion)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STRING pComponentName, - OMX_OUT OMX_VERSIONTYPE* pComponentVersion, - OMX_OUT OMX_VERSIONTYPE* pSpecVersion, - OMX_OUT OMX_UUIDTYPE* pComponentUUID); - - /** refer to OMX_SendCommand in OMX_core.h or the OMX IL - specification for details on the SendCommand method. - */ - OMX_ERRORTYPE (*SendCommand)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_COMMANDTYPE Cmd, - OMX_IN OMX_U32 nParam1, - OMX_IN OMX_PTR pCmdData); - - /** refer to OMX_GetParameter in OMX_core.h or the OMX IL - specification for details on the GetParameter method. - */ - OMX_ERRORTYPE (*GetParameter)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure); - - - /** refer to OMX_SetParameter in OMX_core.h or the OMX IL - specification for details on the SetParameter method. - */ - OMX_ERRORTYPE (*SetParameter)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure); - - - /** refer to OMX_GetConfig in OMX_core.h or the OMX IL - specification for details on the GetConfig method. - */ - OMX_ERRORTYPE (*GetConfig)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR pComponentConfigStructure); - - - /** refer to OMX_SetConfig in OMX_core.h or the OMX IL - specification for details on the SetConfig method. - */ - OMX_ERRORTYPE (*SetConfig)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure); - - - /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL - specification for details on the GetExtensionIndex method. - */ - OMX_ERRORTYPE (*GetExtensionIndex)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE* pIndexType); - - - /** refer to OMX_GetState in OMX_core.h or the OMX IL - specification for details on the GetState method. - */ - OMX_ERRORTYPE (*GetState)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STATETYPE* pState); - - - /** The ComponentTunnelRequest method will interact with another OMX - component to determine if tunneling is possible and to setup the - tunneling. The return codes for this method can be used to - determine if tunneling is not possible, or if tunneling is not - supported. - - Base profile components (i.e. non-interop) do not support this - method and should return OMX_ErrorNotImplemented - - The interop profile component MUST support tunneling to another - interop profile component with a compatible port parameters. - A component may also support proprietary communication. - - If proprietary communication is supported the negotiation of - proprietary communication is done outside of OMX in a vendor - specific way. It is only required that the proper result be - returned and the details of how the setup is done is left - to the component implementation. - - When this method is invoked when nPort in an output port, the - component will: - 1. Populate the pTunnelSetup structure with the output port's - requirements and constraints for the tunnel. - - When this method is invoked when nPort in an input port, the - component will: - 1. Query the necessary parameters from the output port to - determine if the ports are compatible for tunneling - 2. If the ports are compatible, the component should store - the tunnel step provided by the output port - 3. Determine which port (either input or output) is the buffer - supplier, and call OMX_SetParameter on the output port to - indicate this selection. - - The component will return from this call within 5 msec. - - @param [in] hComp - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle method. - @param [in] nPort - nPort is used to select the port on the component to be used - for tunneling. - @param [in] hTunneledComp - Handle of the component to tunnel with. This is the component - handle returned by the call to the OMX_GetHandle method. When - this parameter is 0x0 the component should setup the port for - communication with the application / IL Client. - @param [in] nPortOutput - nPortOutput is used indicate the port the component should - tunnel with. - @param [in] pTunnelSetup - Pointer to the tunnel setup structure. When nPort is an output port - the component should populate the fields of this structure. When - When nPort is an input port the component should review the setup - provided by the component with the output port. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup tun - */ - - OMX_ERRORTYPE (*ComponentTunnelRequest)( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); - - /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL - specification for details on the UseBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*UseBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8* pBuffer); - - /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL - specification for details on the AllocateBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*AllocateBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes); - - /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL - specification for details on the FreeBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*FreeBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL - specification for details on the EmptyThisBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*EmptyThisBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL - specification for details on the FillThisBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*FillThisBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** The SetCallbacks method is used by the core to specify the callback - structure from the application to the component. This is a blocking - call. The component will return from this call within 5 msec. - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @param [in] pCallbacks - pointer to an OMX_CALLBACKTYPE structure used to provide the - callback information to the component - @param [in] pAppData - pointer to an application defined value. It is anticipated that - the application will pass a pointer to a data structure or a "this - pointer" in this area to allow the callback (in the application) - to determine the context of the call - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - */ - OMX_ERRORTYPE (*SetCallbacks)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_CALLBACKTYPE* pCallbacks, - OMX_IN OMX_PTR pAppData); - - /** ComponentDeInit method is used to deinitialize the component - providing a means to free any resources allocated at component - initialization. NOTE: After this call the component handle is - not valid for further use. - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - */ - OMX_ERRORTYPE (*ComponentDeInit)( - OMX_IN OMX_HANDLETYPE hComponent); - - /** @ingroup buf */ - OMX_ERRORTYPE (*UseEGLImage)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN void* eglImage); - - OMX_ERRORTYPE (*ComponentRoleEnum)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex); - -} OMX_COMPONENTTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_ContentPipe.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_ContentPipe.h deleted file mode 100644 index 5f6310c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_ContentPipe.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 - * The OMX_ContentPipe header file contains the definitions used to define - * the public interface for content piples. This header file is intended to - * be used by the component. - */ - -#ifndef OMX_CONTENTPIPE_H -#define OMX_CONTENTPIPE_H - -#ifndef KD_EACCES -/* OpenKODE error codes. CPResult values may be zero (indicating success - or one of the following values) */ -#define KD_EACCES (1) -#define KD_EADDRINUSE (2) -#define KD_EAGAIN (5) -#define KD_EBADF (7) -#define KD_EBUSY (8) -#define KD_ECONNREFUSED (9) -#define KD_ECONNRESET (10) -#define KD_EDEADLK (11) -#define KD_EDESTADDRREQ (12) -#define KD_ERANGE (35) -#define KD_EEXIST (13) -#define KD_EFBIG (14) -#define KD_EHOSTUNREACH (15) -#define KD_EINVAL (17) -#define KD_EIO (18) -#define KD_EISCONN (20) -#define KD_EISDIR (21) -#define KD_EMFILE (22) -#define KD_ENAMETOOLONG (23) -#define KD_ENOENT (24) -#define KD_ENOMEM (25) -#define KD_ENOSPC (26) -#define KD_ENOSYS (27) -#define KD_ENOTCONN (28) -#define KD_EPERM (33) -#define KD_ETIMEDOUT (36) -#define KD_EILSEQ (19) -#endif - -/** Map types from OMX standard types only here so interface is as generic as possible. */ -typedef OMX_U32 CPresult; -typedef char * CPstring; -typedef void * CPhandle; -typedef OMX_U32 CPuint; -typedef OMX_S32 CPint; -typedef char CPbyte; -typedef OMX_BOOL CPbool; - -/** enumeration of origin types used in the CP_PIPETYPE's Seek function - * @ingroup cp - */ -typedef enum CP_ORIGINTYPE { - CP_OriginBegin, - CP_OriginCur, - CP_OriginEnd, - CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_OriginMax = 0X7FFFFFFF -} CP_ORIGINTYPE; - -/** enumeration of contact access types used in the CP_PIPETYPE's Open function - * @ingroup cp - */ -typedef enum CP_ACCESSTYPE { - CP_AccessRead, - CP_AccessWrite, - CP_AccessReadWrite , - CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_AccessMax = 0X7FFFFFFF -} CP_ACCESSTYPE; - -/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function - * @ingroup cp - */ -typedef enum CP_CHECKBYTESRESULTTYPE -{ - CP_CheckBytesOk, /**< There are at least the request number - of bytes available */ - CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes - and presently lacks sufficient bytes. - Client will be called when they are - sufficient bytes are available. */ - CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes - but those available are less than those - requested */ - CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream - and no more bytes are available. */ - CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ - CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_CheckBytesMax = 0X7FFFFFFF -} CP_CHECKBYTESRESULTTYPE; - -/** enumeration of content pipe events sent to the client callback. - * @ingroup cp - */ -typedef enum CP_EVENTTYPE{ - CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ - CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ - CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/ - CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_EventMax = 0X7FFFFFFF -} CP_EVENTTYPE; - -/** content pipe definition - * @ingroup cp - */ -typedef struct CP_PIPETYPE -{ - /** Open a content stream for reading or writing. */ - CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); - - /** Close a content stream. */ - CPresult (*Close)( CPhandle hContent ); - - /** Create a content source and open it for writing. */ - CPresult (*Create)( CPhandle *hContent, CPstring szURI ); - - /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ - CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); - - /** Seek to certain position in the content relative to the specified origin. */ - CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); - - /** Retrieve the current position relative to the start of the content. */ - CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); - - /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). - Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ - CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); - - /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. - Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also - returns the size of the block actually read. Content pointer advances the by the returned size. - Note: pipe provides pointer. This function is appropriate for large reads. The client must call - ReleaseReadBuffer when done with buffer. - - In some cases the requested block may not reside in contiguous memory within the - pipe implementation. For instance if the pipe leverages a circular buffer then the requested - block may straddle the boundary of the circular buffer. By default a pipe implementation - performs a copy in this case to provide the block to the pipe client in one contiguous buffer. - If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory - boundary. Here the client may retrieve the data in segments over successive calls. */ - CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); - - /** Release a buffer obtained by ReadBuffer back to the pipe. */ - CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); - - /** Write data of the specified size to the content (advance content pointer by size of data). - Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ - CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); - - /** Retrieve a buffer allocated by the pipe used to write data to the content. - Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate - for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ - CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); - - /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the - the contents of the buffer to content and advance content pointer by the size of the buffer */ - CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); - - /** Register a per-handle client callback with the content pipe. */ - CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); - -} CP_PIPETYPE; - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Core.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Core.h deleted file mode 100644 index a076f2f..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Core.h +++ /dev/null @@ -1,1431 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Core.h - OpenMax IL version 1.1.2 - * The OMX_Core header file contains the definitions used by both the - * application and the component to access common items. - */ - -#ifndef OMX_Core_h -#define OMX_Core_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header shall include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - - -/** The OMX_COMMANDTYPE enumeration is used to specify the action in the - * OMX_SendCommand macro. - * @ingroup core - */ -typedef enum OMX_COMMANDTYPE -{ - OMX_CommandStateSet, /**< Change the component state */ - OMX_CommandFlush, /**< Flush the data queue(s) of a component */ - OMX_CommandPortDisable, /**< Disable a port on a component. */ - OMX_CommandPortEnable, /**< Enable a port on a component. */ - OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ - OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_CommandMax = 0X7FFFFFFF -} OMX_COMMANDTYPE; - - - -/** The OMX_STATETYPE enumeration is used to indicate or change the component - * state. This enumeration reflects the current state of the component when - * used with the OMX_GetState macro or becomes the parameter in a state change - * command when used with the OMX_SendCommand macro. - * - * The component will be in the Loaded state after the component is initially - * loaded into memory. In the Loaded state, the component is not allowed to - * allocate or hold resources other than to build it's internal parameter - * and configuration tables. The application will send one or more - * SetParameters/GetParameters and SetConfig/GetConfig commands to the - * component and the component will record each of these parameter and - * configuration changes for use later. When the application sends the - * Idle command, the component will acquire the resources needed for the - * specified configuration and will transition to the idle state if the - * allocation is successful. If the component cannot successfully - * transition to the idle state for any reason, the state of the component - * shall be fully rolled back to the Loaded state (e.g. all allocated - * resources shall be released). When the component receives the command - * to go to the Executing state, it shall begin processing buffers by - * sending all input buffers it holds to the application. While - * the component is in the Idle state, the application may also send the - * Pause command. If the component receives the pause command while in the - * Idle state, the component shall send all input buffers it holds to the - * application, but shall not begin processing buffers. This will allow the - * application to prefill buffers. - * - * @ingroup comp - */ - -typedef enum OMX_STATETYPE -{ - OMX_StateInvalid, /**< component has detected that it's internal data - structures are corrupted to the point that - it cannot determine it's state properly */ - OMX_StateLoaded, /**< component has been loaded but has not completed - initialization. The OMX_SetParameter macro - and the OMX_GetParameter macro are the only - valid macros allowed to be sent to the - component in this state. */ - OMX_StateIdle, /**< component initialization has been completed - successfully and the component is ready to - to start. */ - OMX_StateExecuting, /**< component has accepted the start command and - is processing data (if data is available) */ - OMX_StatePause, /**< component has received pause command */ - OMX_StateWaitForResources, /**< component is waiting for resources, either after - preemption or before it gets the resources requested. - See specification for complete details. */ - OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_StateMax = 0X7FFFFFFF -} OMX_STATETYPE; - -/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These - * errors should cover most of the common failure cases. However, - * vendors are free to add additional error messages of their own as - * long as they follow these rules: - * 1. Vendor error messages shall be in the range of 0x90000000 to - * 0x9000FFFF. - * 2. Vendor error messages shall be defined in a header file provided - * with the component. No error messages are allowed that are - * not defined. - */ -typedef enum OMX_ERRORTYPE -{ - OMX_ErrorNone = 0, - - /** There were insufficient resources to perform the requested operation */ - OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, - - /** There was an error, but the cause of the error could not be determined */ - OMX_ErrorUndefined = (OMX_S32) 0x80001001, - - /** The component name string was not valid */ - OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, - - /** No component with the specified name string was found */ - OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, - - /** The component specified did not have a "OMX_ComponentInit" or - "OMX_ComponentDeInit entry point */ - OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, - - /** One or more parameters were not valid */ - OMX_ErrorBadParameter = (OMX_S32) 0x80001005, - - /** The requested function is not implemented */ - OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, - - /** The buffer was emptied before the next buffer was ready */ - OMX_ErrorUnderflow = (OMX_S32) 0x80001007, - - /** The buffer was not available when it was needed */ - OMX_ErrorOverflow = (OMX_S32) 0x80001008, - - /** The hardware failed to respond as expected */ - OMX_ErrorHardware = (OMX_S32) 0x80001009, - - /** The component is in the state OMX_StateInvalid */ - OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, - - /** Stream is found to be corrupt */ - OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, - - /** Ports being connected are not compatible */ - OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, - - /** Resources allocated to an idle component have been - lost resulting in the component returning to the loaded state */ - OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, - - /** No more indicies can be enumerated */ - OMX_ErrorNoMore = (OMX_S32) 0x8000100E, - - /** The component detected a version mismatch */ - OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, - - /** The component is not ready to return data at this time */ - OMX_ErrorNotReady = (OMX_S32) 0x80001010, - - /** There was a timeout that occurred */ - OMX_ErrorTimeout = (OMX_S32) 0x80001011, - - /** This error occurs when trying to transition into the state you are already in */ - OMX_ErrorSameState = (OMX_S32) 0x80001012, - - /** Resources allocated to an executing or paused component have been - preempted, causing the component to return to the idle state */ - OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, - - /** A non-supplier port sends this error to the IL client (via the EventHandler callback) - during the allocation of buffers (on a transition from the LOADED to the IDLE state or - on a port restart) when it deems that it has waited an unusually long time for the supplier - to send it an allocated buffer via a UseBuffer call. */ - OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, - - /** A non-supplier port sends this error to the IL client (via the EventHandler callback) - during the deallocation of buffers (on a transition from the IDLE to LOADED state or - on a port stop) when it deems that it has waited an unusually long time for the supplier - to request the deallocation of a buffer header via a FreeBuffer call. */ - OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, - - /** A supplier port sends this error to the IL client (via the EventHandler callback) - during the stopping of a port (either on a transition from the IDLE to LOADED - state or a port stop) when it deems that it has waited an unusually long time for - the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ - OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, - - /** Attempting a state transtion that is not allowed */ - OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, - - /* Attempting a command that is not allowed during the present state. */ - OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, - - /** The values encapsulated in the parameter or config structure are not supported. */ - OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, - - /** The parameter or config indicated by the given index is not supported. */ - OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, - - /** The port index supplied is incorrect. */ - OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, - - /** The port has lost one or more of its buffers and it thus unpopulated. */ - OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, - - /** Component suspended due to temporary loss of resources */ - OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, - - /** Component suspended due to an inability to acquire dynamic resources */ - OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, - - /** When the macroblock error reporting is enabled the component returns new error - for every frame that has errors */ - OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, - - /** A component reports this error when it cannot parse or determine the format of an input stream. */ - OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, - - /** The content open operation failed. */ - OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, - - /** The content creation operation failed. */ - OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, - - /** Separate table information is being used */ - OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, - - /** Tunneling is unsupported by the component*/ - OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, - - OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ErrorMax = 0x7FFFFFFF -} OMX_ERRORTYPE; - -/** @ingroup core */ -typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); - -/** @ingroup core */ -typedef struct OMX_COMPONENTREGISTERTYPE -{ - const char * pName; /* Component name, 128 byte limit (including '\0') applies */ - OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ -} OMX_COMPONENTREGISTERTYPE; - -/** @ingroup core */ -extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; - -/** @ingroup rpm */ -typedef struct OMX_PRIORITYMGMTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nGroupPriority; /**< Priority of the component group */ - OMX_U32 nGroupID; /**< ID of the component group */ -} OMX_PRIORITYMGMTTYPE; - -/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ -#define OMX_MAX_STRINGNAME_SIZE 128 - -/** @ingroup comp */ -typedef struct OMX_PARAM_COMPONENTROLETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ -} OMX_PARAM_COMPONENTROLETYPE; - -/** End of Stream Buffer Flag: - * - * A component sets EOS when it has no more data to emit on a particular - * output port. Thus an output port shall set EOS on the last buffer it - * emits. A component's determination of when an output port should - * cease sending data is implemenation specific. - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_EOS 0x00000001 - -/** Start Time Buffer Flag: - * - * The source of a stream (e.g. a demux component) sets the STARTTIME - * flag on the buffer that contains the starting timestamp for the - * stream. The starting timestamp corresponds to the first data that - * should be displayed at startup or after a seek. - * The first timestamp of the stream is not necessarily the start time. - * For instance, in the case of a seek to a particular video frame, - * the target frame may be an interframe. Thus the first buffer of - * the stream will be the intra-frame preceding the target frame and - * the starttime will occur with the target frame (with any other - * required frames required to reconstruct the target intervening). - * - * The STARTTIME flag is directly associated with the buffer's - * timestamp ' thus its association to buffer data and its - * propagation is identical to the timestamp's. - * - * When a Sync Component client receives a buffer with the - * STARTTIME flag it shall perform a SetConfig on its sync port - * using OMX_ConfigTimeClientStartTime and passing the buffer's - * timestamp. - * - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_STARTTIME 0x00000002 - - - -/** Decode Only Buffer Flag: - * - * The source of a stream (e.g. a demux component) sets the DECODEONLY - * flag on any buffer that should shall be decoded but should not be - * displayed. This flag is used, for instance, when a source seeks to - * a target interframe that requires the decode of frames preceding the - * target to facilitate the target's reconstruction. In this case the - * source would emit the frames preceding the target downstream - * but mark them as decode only. - * - * The DECODEONLY is associated with buffer data and propagated in a - * manner identical to the buffer timestamp. - * - * A component that renders data should ignore all buffers with - * the DECODEONLY flag set. - * - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 - - -/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 - -/* End of Frame: The buffer contains exactly one end of frame and no data - * occurs after the end of frame. This flag is an optional hint. The absence - * of this flag does not imply the absence of an end of frame within the buffer. - * @ingroup buf -*/ -#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 - -/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' - * a frame that has no dependency on any other frame information - * @ingroup buf - */ -#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 - -/* Extra data present flag: there is extra data appended to the data stream - * residing in the buffer - * @ingroup buf - */ -#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 - -/** Codec Config Buffer Flag: -* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an -* output port when all bytes in the buffer form part or all of a set of -* codec specific configuration data. Examples include SPS/PPS nal units -* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for -* OMX_AUDIO_CodingAAC. Any component that for a given stream sets -* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes -* with frame data in the same buffer, and shall send all buffers -* containing codec configuration bytes before any buffers containing -* frame data that those configurations bytes describe. -* If the stream format for a particular codec has a frame specific -* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or -* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as -* normal without setting OMX_BUFFERFLAG_CODECCONFIG. - * @ingroup buf - */ -#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 - - - -/** @ingroup buf */ -typedef struct OMX_BUFFERHEADERTYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8* pBuffer; /**< Pointer to actual block of memory - that is acting as the buffer */ - OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ - OMX_U32 nFilledLen; /**< number of bytes currently in the - buffer */ - OMX_U32 nOffset; /**< start offset of valid data in bytes from - the start of the buffer */ - OMX_PTR pAppPrivate; /**< pointer to any data the application - wants to associate with this buffer */ - OMX_PTR pPlatformPrivate; /**< pointer to any data the platform - wants to associate with this buffer */ - OMX_PTR pInputPortPrivate; /**< pointer to any data the input port - wants to associate with this buffer */ - OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port - wants to associate with this buffer */ - OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a - mark event upon processing this buffer. */ - OMX_PTR pMarkData; /**< Application specific data associated with - the mark sent on a mark event to disambiguate - this mark from others. */ - OMX_U32 nTickCount; /**< Optional entry that the component and - application can update with a tick count - when they access the component. This - value should be in microseconds. Since - this is a value relative to an arbitrary - starting point, this value cannot be used - to determine absolute time. This is an - optional entry and not all components - will update it.*/ - OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample - starting at the first logical sample - boundary in the buffer. Timestamps of - successive samples within the buffer may - be inferred by adding the duration of the - of the preceding buffer to the timestamp - of the preceding buffer.*/ - OMX_U32 nFlags; /**< buffer specific flags */ - OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using - this buffer */ - OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using - this buffer */ -} OMX_BUFFERHEADERTYPE; - -/** The OMX_EXTRADATATYPE enumeration is used to define the - * possible extra data payload types. - * NB: this enum is binary backwards compatible with the previous - * OMX_EXTRADATA_QUANT define. This should be replaced with - * OMX_ExtraDataQuantization. - */ -typedef enum OMX_EXTRADATATYPE -{ - OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ - OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ - OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ExtraDataMax = 0x7FFFFFFF -} OMX_EXTRADATATYPE; - - -typedef struct OMX_OTHER_EXTRADATATYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_EXTRADATATYPE eType; /* Extra Data type */ - OMX_U32 nDataSize; /* Size of the supporting data to follow */ - OMX_U8 data[1]; /* Supporting data hint */ -} OMX_OTHER_EXTRADATATYPE; - -/** @ingroup comp */ -typedef struct OMX_PORT_PARAM_TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPorts; /**< The number of ports for this component */ - OMX_U32 nStartPortNumber; /** first port number for this type of port */ -} OMX_PORT_PARAM_TYPE; - -/** @ingroup comp */ -typedef enum OMX_EVENTTYPE -{ - OMX_EventCmdComplete, /**< component has sucessfully completed a command */ - OMX_EventError, /**< component has detected an error condition */ - OMX_EventMark, /**< component has detected a buffer mark */ - OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ - OMX_EventBufferFlag, /**< component has detected an EOS */ - OMX_EventResourcesAcquired, /**< component has been granted resources and is - automatically starting the state change from - OMX_StateWaitForResources to OMX_StateIdle. */ - OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ - OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ - OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ - OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_EventMax = 0x7FFFFFFF -} OMX_EVENTTYPE; - -typedef struct OMX_CALLBACKTYPE -{ - /** The EventHandler method is used to notify the application when an - event of interest occurs. Events are defined in the OMX_EVENTTYPE - enumeration. Please see that enumeration for details of what will - be returned for each type of event. Callbacks should not return - an error to the component, so if an error occurs, the application - shall handle it internally. This is a blocking call. - - The application should return from this call within 5 msec to avoid - blocking the component for an excessively long period of time. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param eEvent - Event that the component wants to notify the application about. - @param nData1 - nData will be the OMX_ERRORTYPE for an error event and will be - an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. - @param nData2 - nData2 will hold further information related to the event. Can be OMX_STATETYPE for - a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. - Default value is 0 if not used. ) - @param pEventData - Pointer to additional event-specific data (see spec for meaning). - */ - - OMX_ERRORTYPE (*EventHandler)( - 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); - - /** The EmptyBufferDone method is used to return emptied buffers from an - input port back to the application for reuse. This is a blocking call - so the application should not attempt to refill the buffers during this - call, but should queue them and refill them in another thread. There - is no error return, so the application shall handle any errors generated - internally. - - The application should return from this call within 5 msec. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer indicating the buffer that was emptied. - @ingroup buf - */ - OMX_ERRORTYPE (*EmptyBufferDone)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** The FillBufferDone method is used to return filled buffers from an - output port back to the application for emptying and then reuse. - This is a blocking call so the application should not attempt to - empty the buffers during this call, but should queue the buffers - and empty them in another thread. There is no error return, so - the application shall handle any errors generated internally. The - application shall also update the buffer header to indicate the - number of bytes placed into the buffer. - - The application should return from this call within 5 msec. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer indicating the buffer that was filled. - @ingroup buf - */ - OMX_ERRORTYPE (*FillBufferDone)( - OMX_OUT OMX_HANDLETYPE hComponent, - OMX_OUT OMX_PTR pAppData, - OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); - -} OMX_CALLBACKTYPE; - -/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier - preference when tunneling between two ports. - @ingroup tun buf -*/ -typedef enum OMX_BUFFERSUPPLIERTYPE -{ - OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, - or don't care */ - OMX_BufferSupplyInput, /**< input port supplies the buffers */ - OMX_BufferSupplyOutput, /**< output port supplies the buffers */ - OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_BufferSupplyMax = 0x7FFFFFFF -} OMX_BUFFERSUPPLIERTYPE; - - -/** buffer supplier parameter - * @ingroup tun - */ -typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ -} OMX_PARAM_BUFFERSUPPLIERTYPE; - - -/**< indicates that buffers received by an input port of a tunnel - may not modify the data in the buffers - @ingroup tun - */ -#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 - - -/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output - port to an input port as part the two ComponentTunnelRequest calls - resulting from a OMX_SetupTunnel call from the IL Client. - @ingroup tun - */ -typedef struct OMX_TUNNELSETUPTYPE -{ - OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ - OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ -} OMX_TUNNELSETUPTYPE; - -/* OMX Component headers is included to enable the core to use - macros for functions into the component for OMX release 1.0. - Developers should not access any structures or data from within - the component header directly */ -/* TO BE REMOVED - #include */ - -/** GetComponentVersion will return information about the component. - This is a blocking call. This macro will go directly from the - application to the component (via a core macro). The - component will return from this call within 5 msec. - @param [in] hComponent - handle of component to execute the command - @param [out] pComponentName - pointer to an empty string of length 128 bytes. The component - will write its name into this string. The name will be - terminated by a single zero byte. The name of a component will - be 127 bytes or less to leave room for the trailing zero byte. - An example of a valid component name is "OMX.ABC.ChannelMixer\0". - @param [out] pComponentVersion - pointer to an OMX Version structure that the component will fill - in. The component will fill in a value that indicates the - component version. NOTE: the component version is NOT the same - as the OMX Specification version (found in all structures). The - component version is defined by the vendor of the component and - its value is entirely up to the component vendor. - @param [out] pSpecVersion - pointer to an OMX Version structure that the component will fill - in. The SpecVersion is the version of the specification that the - component was built against. Please note that this value may or - may not match the structure's version. For example, if the - component was built against the 2.0 specification, but the - application (which creates the structure is built against the - 1.0 specification the versions would be different. - @param [out] pComponentUUID - pointer to the UUID of the component which will be filled in by - the component. The UUID is a unique identifier that is set at - RUN time for the component and is unique to each instantion of - the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetComponentVersion( \ - hComponent, \ - pComponentName, \ - pComponentVersion, \ - pSpecVersion, \ - pComponentUUID) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ - hComponent, \ - pComponentName, \ - pComponentVersion, \ - pSpecVersion, \ - pComponentUUID) /* Macro End */ - - -/** Send a command to the component. This call is a non-blocking call. - The component should check the parameters and then queue the command - to the component thread to be executed. The component thread shall - send the EventHandler() callback at the conclusion of the command. - This macro will go directly from the application to the component (via - a core macro). The component will return from this call within 5 msec. - - When the command is "OMX_CommandStateSet" the component will queue a - state transition to the new state idenfied in nParam. - - When the command is "OMX_CommandFlush", to flush a port's buffer queues, - the command will force the component to return all buffers NOT CURRENTLY - BEING PROCESSED to the application, in the order in which the buffers - were received. - - When the command is "OMX_CommandPortDisable" or - "OMX_CommandPortEnable", the component's port (given by the value of - nParam) will be stopped or restarted. - - When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the - pCmdData will point to a OMX_MARKTYPE structure containing the component - handle of the component to examine the buffer chain for the mark. nParam1 - contains the index of the port on which the buffer mark is applied. - - Specification text for more details. - - @param [in] hComponent - handle of component to execute the command - @param [in] Cmd - Command for the component to execute - @param [in] nParam - Parameter for the command to be executed. When Cmd has the value - OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has - the value OMX_CommandFlush, value of nParam indicates which port(s) - to flush. -1 is used to flush all ports a single port index will - only flush that port. When Cmd has the value "OMX_CommandPortDisable" - or "OMX_CommandPortEnable", the component's port is given by - the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" - the components pot is given by the value of nParam. - @param [in] pCmdData - Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value - "OMX_CommandMarkBuffer". - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SendCommand( \ - hComponent, \ - Cmd, \ - nParam, \ - pCmdData) \ - ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ - hComponent, \ - Cmd, \ - nParam, \ - pCmdData) /* Macro End */ - - -/** The OMX_GetParameter macro will get one of the current parameter - settings from the component. This macro cannot only be invoked when - the component is in the OMX_StateInvalid state. The nParamIndex - parameter is used to indicate which structure is being requested from - the component. The application shall allocate the correct structure - and shall fill in the structure size and version information before - invoking this macro. When the parameter applies to a port, the - caller shall fill in the appropriate nPortIndex value indicating the - port on which the parameter applies. If the component has not had - any settings changed, then the component should return a set of - valid DEFAULT parameters for the component. This is a blocking - call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nParamIndex - Index of the structure to be filled. This value is from the - OMX_INDEXTYPE enumeration. - @param [in,out] pComponentParameterStructure - Pointer to application allocated structure to be filled by the - component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) /* Macro End */ - - -/** The OMX_SetParameter macro will send an initialization parameter - structure to a component. Each structure shall be sent one at a time, - in a separate invocation of the macro. This macro can only be - invoked when the component is in the OMX_StateLoaded state, or the - port is disabled (when the parameter applies to a port). The - nParamIndex parameter is used to indicate which structure is being - passed to the component. The application shall allocate the - correct structure and shall fill in the structure size and version - information (as well as the actual data) before invoking this macro. - The application is free to dispose of this structure after the call - as the component is required to copy any data it shall retain. This - is a blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nIndex - Index of the structure to be sent. This value is from the - OMX_INDEXTYPE enumeration. - @param [in] pComponentParameterStructure - pointer to application allocated structure to be used for - initialization by the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) /* Macro End */ - - -/** The OMX_GetConfig macro will get one of the configuration structures - from a component. This macro can be invoked anytime after the - component has been loaded. The nParamIndex call parameter is used to - indicate which structure is being requested from the component. The - application shall allocate the correct structure and shall fill in the - structure size and version information before invoking this macro. - If the component has not had this configuration parameter sent before, - then the component should return a set of valid DEFAULT values for the - component. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nIndex - Index of the structure to be filled. This value is from the - OMX_INDEXTYPE enumeration. - @param [in,out] pComponentConfigStructure - pointer to application allocated structure to be filled by the - component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp -*/ -#define OMX_GetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) /* Macro End */ - - -/** The OMX_SetConfig macro will send one of the configuration - structures to a component. Each structure shall be sent one at a time, - each in a separate invocation of the macro. This macro can be invoked - anytime after the component has been loaded. The application shall - allocate the correct structure and shall fill in the structure size - and version information (as well as the actual data) before invoking - this macro. The application is free to dispose of this structure after - the call as the component is required to copy any data it shall retain. - This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nConfigIndex - Index of the structure to be sent. This value is from the - OMX_INDEXTYPE enumeration above. - @param [in] pComponentConfigStructure - pointer to application allocated structure to be used for - initialization by the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) /* Macro End */ - - -/** The OMX_GetExtensionIndex macro will invoke a component to translate - a vendor specific configuration or parameter string into an OMX - structure index. There is no requirement for the vendor to support - this command for the indexes already found in the OMX_INDEXTYPE - enumeration (this is done to save space in small components). The - component shall support all vendor supplied extension indexes not found - in the master OMX_INDEXTYPE enumeration. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @param [in] cParameterName - OMX_STRING that shall be less than 128 characters long including - the trailing null byte. This is the string that will get - translated by the component into a configuration index. - @param [out] pIndexType - a pointer to a OMX_INDEXTYPE to receive the index value. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetExtensionIndex( \ - hComponent, \ - cParameterName, \ - pIndexType) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ - hComponent, \ - cParameterName, \ - pIndexType) /* Macro End */ - - -/** The OMX_GetState macro will invoke the component to get the current - state of the component and place the state value into the location - pointed to by pState. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] pState - pointer to the location to receive the state. The value returned - is one of the OMX_STATETYPE members - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetState( \ - hComponent, \ - pState) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ - hComponent, \ - pState) /* Macro End */ - - -/** The OMX_UseBuffer macro will request that the component use - a buffer (and allocate its own buffer header) already allocated - by another component, or by the IL Client. This is a blocking - call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive the - pointer to the buffer header - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ - -#define OMX_UseBuffer( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes, \ - pBuffer) - - -/** The OMX_AllocateBuffer macro will request that the component allocate - a new buffer and buffer header. The component will allocate the - buffer and the buffer header and return a pointer to the buffer - header. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive - the pointer to the buffer header - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. The port can be found by using the nPortIndex - value as an index into the Port Definition array of the component. - @param [in] pAppPrivate - pAppPrivate is used to initialize the pAppPrivate member of the - buffer header structure. - @param [in] nSizeBytes - size of the buffer to allocate. Used when bAllocateNew is true. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_AllocateBuffer( \ - hComponent, \ - ppBuffer, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes) \ - ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ - hComponent, \ - ppBuffer, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes) /* Macro End */ - - -/** The OMX_FreeBuffer macro will release a buffer header from the component - which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If - the component allocated the buffer (see the OMX_UseBuffer macro) then - the component shall free the buffer and buffer header. This is a - blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_FreeBuffer( \ - hComponent, \ - nPortIndex, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ - hComponent, \ - nPortIndex, \ - pBuffer) /* Macro End */ - - -/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an - input port of a component. The buffer will be emptied by the component - and returned to the application via the EmptyBufferDone call back. - This is a non-blocking call in that the component will record the buffer - and return immediately and then empty the buffer, later, at the proper - time. As expected, this macro may be invoked only while the component - is in the OMX_StateExecuting. If nPortIndex does not specify an input - port, the component shall return an error. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_EmptyThisBuffer( \ - hComponent, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ - hComponent, \ - pBuffer) /* Macro End */ - - -/** The OMX_FillThisBuffer macro will send an empty buffer to an - output port of a component. The buffer will be filled by the component - and returned to the application via the FillBufferDone call back. - This is a non-blocking call in that the component will record the buffer - and return immediately and then fill the buffer, later, at the proper - time. As expected, this macro may be invoked only while the component - is in the OMX_ExecutingState. If nPortIndex does not specify an output - port, the component shall return an error. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_FillThisBuffer( \ - hComponent, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ - hComponent, \ - pBuffer) /* Macro End */ - - - -/** The OMX_UseEGLImage macro will request that the component use - a EGLImage provided by EGL (and allocate its own buffer header) - This is a blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive the - pointer to the buffer header. Note that the memory location used - for this buffer is NOT visible to the IL Client. - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. The port can be found by using the nPortIndex - value as an index into the Port Definition array of the component. - @param [in] pAppPrivate - pAppPrivate is used to initialize the pAppPrivate member of the - buffer header structure. - @param [in] eglImage - eglImage contains the handle of the EGLImage to use as a buffer on the - specified port. The component is expected to validate properties of - the EGLImage against the configuration of the port to ensure the component - can use the EGLImage as a buffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_UseEGLImage( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - eglImage) \ - ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - eglImage) - -/** The OMX_Init method is used to initialize the OMX core. It shall be the - first call made into OMX and it should only be executed one time without - an interviening OMX_Deinit call. - - The core should return from this call within 20 msec. - - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); - - -/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be - the last call made into OMX. In the event that the core determines that - thare are components loaded when this call is made, the core may return - with an error rather than try to unload the components. - - The core should return from this call within 20 msec. - - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); - - -/** The OMX_ComponentNameEnum method will enumerate through all the names of - recognised valid components in the system. This function is provided - as a means to detect all the components in the system run-time. There is - no strict ordering to the enumeration order of component names, although - each name will only be enumerated once. If the OMX core supports run-time - installation of new components, it is only requried to detect newly - installed components when the first call to enumerate component names - is made (i.e. when nIndex is 0x0). - - The core should return from this call in 20 msec. - - @param [out] cComponentName - pointer to a null terminated string with the component name. The - names of the components are strings less than 127 bytes in length - plus the trailing null for a maximum size of 128 bytes. An example - of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are - assigned by the vendor, but shall start with "OMX." and then have - the Vendor designation next. - @param [in] nNameLength - number of characters in the cComponentName string. With all - component name strings restricted to less than 128 characters - (including the trailing null) it is recomended that the caller - provide a input string for the cComponentName of 128 characters. - @param [in] nIndex - number containing the enumeration index for the component. - Multiple calls to OMX_ComponentNameEnum with increasing values - of nIndex will enumerate through the component names in the - system until OMX_ErrorNoMore is returned. The value of nIndex - is 0 to (N-1), where N is the number of valid installed components - in the system. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. When the value of nIndex exceeds the number of - components in the system minus 1, OMX_ErrorNoMore will be - returned. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( - OMX_OUT OMX_STRING cComponentName, - OMX_IN OMX_U32 nNameLength, - OMX_IN OMX_U32 nIndex); - - -/** The OMX_GetHandle method will locate the component specified by the - component name given, load that component into memory and then invoke - the component's methods to create an instance of the component. - - The core should return from this call within 20 msec. - - @param [out] pHandle - pointer to an OMX_HANDLETYPE pointer to be filled in by this method. - @param [in] cComponentName - pointer to a null terminated string with the component name. The - names of the components are strings less than 127 bytes in length - plus the trailing null for a maximum size of 128 bytes. An example - of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are - assigned by the vendor, but shall start with "OMX." and then have - the Vendor designation next. - @param [in] pAppData - pointer to an application defined value that will be returned - during callbacks so that the application can identify the source - of the callback. - @param [in] pCallBacks - pointer to a OMX_CALLBACKTYPE structure that will be passed to the - component to initialize it with. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( - OMX_OUT OMX_HANDLETYPE* pHandle, - OMX_IN OMX_STRING cComponentName, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_CALLBACKTYPE* pCallBacks); - - -/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle - method. If the component reference count goes to zero, the component will - be unloaded from memory. - - The core should return from this call within 20 msec when the component is - in the OMX_StateLoaded state. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( - OMX_IN OMX_HANDLETYPE hComponent); - - - -/** The OMX_SetupTunnel method will handle the necessary calls to the components - to setup the specified tunnel the two components. NOTE: This is - an actual method (not a #define macro). This method will make calls into - the component ComponentTunnelRequest method to do the actual tunnel - connection. - - The ComponentTunnelRequest method on both components will be called. - This method shall not be called unless the component is in the - OMX_StateLoaded state except when the ports used for the tunnel are - disabled. In this case, the component may be in the OMX_StateExecuting, - OMX_StatePause, or OMX_StateIdle states. - - The core should return from this call within 20 msec. - - @param [in] hOutput - Handle of the component to be accessed. Also this is the handle - of the component whose port, specified in the nPortOutput parameter - will be used the source for the tunnel. This is the component handle - returned by the call to the OMX_GetHandle function. There is a - requirement that hOutput be the source for the data when - tunelling (i.e. nPortOutput is an output port). If 0x0, the component - specified in hInput will have it's port specified in nPortInput - setup for communication with the application / IL client. - @param [in] nPortOutput - nPortOutput is used to select the source port on component to be - used in the tunnel. - @param [in] hInput - This is the component to setup the tunnel with. This is the handle - of the component whose port, specified in the nPortInput parameter - will be used the destination for the tunnel. This is the component handle - returned by the call to the OMX_GetHandle function. There is a - requirement that hInput be the destination for the data when - tunelling (i.e. nPortInut is an input port). If 0x0, the component - specified in hOutput will have it's port specified in nPortPOutput - setup for communication with the application / IL client. - @param [in] nPortInput - nPortInput is used to select the destination port on component to be - used in the tunnel. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - When OMX_ErrorNotImplemented is returned, one or both components is - a non-interop component and does not support tunneling. - - On failure, the ports of both components are setup for communication - with the application / IL Client. - @ingroup core tun - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( - OMX_IN OMX_HANDLETYPE hOutput, - OMX_IN OMX_U32 nPortOutput, - OMX_IN OMX_HANDLETYPE hInput, - OMX_IN OMX_U32 nPortInput); - -/** @ingroup cp */ -OMX_API OMX_ERRORTYPE OMX_GetContentPipe( - OMX_OUT OMX_HANDLETYPE *hPipe, - OMX_IN OMX_STRING szURI); - -/** The OMX_GetComponentsOfRole method will return the number of components that support the given - role and (if the compNames field is non-NULL) the names of those components. The call will fail if - an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the - client should: - * first call this function with the compNames field NULL to determine the number of component names - * second call this function with the compNames field pointing to an array of names allocated - according to the number returned by the first call. - - The core should return from this call within 5 msec. - - @param [in] role - This is generic standard component name consisting only of component class - name and the type within that class (e.g. 'audio_decoder.aac'). - @param [inout] pNumComps - This is used both as input and output. - - If compNames is NULL, the input is ignored and the output specifies how many components support - the given role. - - If compNames is not NULL, on input it bounds the size of the input structure and - on output, it specifies the number of components string names listed within the compNames parameter. - @param [inout] compNames - If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts - a list of the names of all physical components that implement the specified standard component name. - Each name is NULL terminated. numComps indicates the number of names. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( - OMX_IN OMX_STRING role, - OMX_INOUT OMX_U32 *pNumComps, - OMX_INOUT OMX_U8 **compNames); - -/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given - component and (if the roles field is non-NULL) the names of those roles. The call will fail if - an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the - client should: - * first call this function with the roles field NULL to determine the number of role names - * second call this function with the roles field pointing to an array of names allocated - according to the number returned by the first call. - - The core should return from this call within 5 msec. - - @param [in] compName - This is the name of the component being queried about. - @param [inout] pNumRoles - This is used both as input and output. - - If roles is NULL, the input is ignored and the output specifies how many roles the component supports. - - If compNames is not NULL, on input it bounds the size of the input structure and - on output, it specifies the number of roles string names listed within the roles parameter. - @param [out] roles - If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings - which accepts a list of the names of all standard components roles implemented on the - specified component name. numComps indicates the number of names. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( - OMX_IN OMX_STRING compName, - OMX_INOUT OMX_U32 *pNumRoles, - OMX_OUT OMX_U8 **roles); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_IVCommon.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_IVCommon.h deleted file mode 100644 index 4c4995c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_IVCommon.h +++ /dev/null @@ -1,920 +0,0 @@ -/** - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 - * The structures needed by Video and Image components to exchange - * parameters and configuration data with the components. - */ -#ifndef OMX_IVCommon_h -#define OMX_IVCommon_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * Each OMX header must include all required header files to allow the header - * to compile without errors. The includes below are required for this header - * file to compile successfully - */ - -#include - -/** @defgroup iv OpenMAX IL Imaging and Video Domain - * Common structures for OpenMAX IL Imaging and Video domains - * @{ - */ - - -/** - * Enumeration defining possible uncompressed image/video formats. - * - * ENUMS: - * Unused : Placeholder value when format is N/A - * Monochrome : black and white - * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 - * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 - * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 - * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 - * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 - * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 - * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 - * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 - * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 - * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 - * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 - * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 - * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 - * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 - * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 - * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally - * YUV411PackedPlanar : packed per payload in planar slices - * YUV420Planar : Three arrays Y,U,V. - * YUV420PackedPlanar : packed per payload in planar slices - * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V - * YUV422Planar : Three arrays Y,U,V. - * YUV422PackedPlanar : packed per payload in planar slices - * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V - * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) - * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) - * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) - * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) - * YUV444Interleaved : Each pixel contains equal parts YUV - * RawBayer8bit : SMIA camera output format - * RawBayer10bit : SMIA camera output format - * RawBayer8bitcompressed : SMIA camera output format - */ -typedef enum OMX_COLOR_FORMATTYPE { - OMX_COLOR_FormatUnused, - OMX_COLOR_FormatMonochrome, - OMX_COLOR_Format8bitRGB332, - OMX_COLOR_Format12bitRGB444, - OMX_COLOR_Format16bitARGB4444, - OMX_COLOR_Format16bitARGB1555, - OMX_COLOR_Format16bitRGB565, - OMX_COLOR_Format16bitBGR565, - OMX_COLOR_Format18bitRGB666, - OMX_COLOR_Format18bitARGB1665, - OMX_COLOR_Format19bitARGB1666, - OMX_COLOR_Format24bitRGB888, - OMX_COLOR_Format24bitBGR888, - OMX_COLOR_Format24bitARGB1887, - OMX_COLOR_Format25bitARGB1888, - OMX_COLOR_Format32bitBGRA8888, - OMX_COLOR_Format32bitARGB8888, - OMX_COLOR_FormatYUV411Planar, - OMX_COLOR_FormatYUV411PackedPlanar, - OMX_COLOR_FormatYUV420Planar, - OMX_COLOR_FormatYUV420PackedPlanar, - OMX_COLOR_FormatYUV420SemiPlanar, - OMX_COLOR_FormatYUV422Planar, - OMX_COLOR_FormatYUV422PackedPlanar, - OMX_COLOR_FormatYUV422SemiPlanar, - OMX_COLOR_FormatYCbYCr, - OMX_COLOR_FormatYCrYCb, - OMX_COLOR_FormatCbYCrY, - OMX_COLOR_FormatCrYCbY, - OMX_COLOR_FormatYUV444Interleaved, - OMX_COLOR_FormatRawBayer8bit, - OMX_COLOR_FormatRawBayer10bit, - OMX_COLOR_FormatRawBayer8bitcompressed, - OMX_COLOR_FormatL2, - OMX_COLOR_FormatL4, - OMX_COLOR_FormatL8, - OMX_COLOR_FormatL16, - OMX_COLOR_FormatL24, - OMX_COLOR_FormatL32, - OMX_COLOR_FormatYUV420PackedSemiPlanar, - OMX_COLOR_FormatYUV422PackedSemiPlanar, - OMX_COLOR_Format18BitBGR666, - OMX_COLOR_Format24BitARGB6666, - OMX_COLOR_Format24BitABGR6666, - OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_COLOR_FormatMax = 0x7FFFFFFF -} OMX_COLOR_FORMATTYPE; - - -/** - * Defines the matrix for conversion from RGB to YUV or vice versa. - * iColorMatrix should be initialized with the fixed point values - * used in converting between formats. - */ -typedef struct OMX_CONFIG_COLORCONVERSIONTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ - OMX_U32 nPortIndex; /**< Port that this struct applies to */ - OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */ - OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */ -}OMX_CONFIG_COLORCONVERSIONTYPE; - - -/** - * Structure defining percent to scale each frame dimension. For example: - * To make the width 50% larger, use fWidth = 1.5 and to make the width - * 1/2 the original size, use fWidth = 0.5 - */ -typedef struct OMX_CONFIG_SCALEFACTORTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ - OMX_U32 nPortIndex; /**< Port that this struct applies to */ - OMX_S32 xWidth; /**< Fixed point value stored as Q16 */ - OMX_S32 xHeight; /**< Fixed point value stored as Q16 */ -}OMX_CONFIG_SCALEFACTORTYPE; - - -/** - * Enumeration of possible image filter types - */ -typedef enum OMX_IMAGEFILTERTYPE { - OMX_ImageFilterNone, - OMX_ImageFilterNoise, - OMX_ImageFilterEmboss, - OMX_ImageFilterNegative, - OMX_ImageFilterSketch, - OMX_ImageFilterOilPaint, - OMX_ImageFilterHatch, - OMX_ImageFilterGpen, - OMX_ImageFilterAntialias, - OMX_ImageFilterDeRing, - OMX_ImageFilterSolarize, - OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ImageFilterMax = 0x7FFFFFFF -} OMX_IMAGEFILTERTYPE; - - -/** - * Image filter configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eImageFilter : Image filter type enumeration - */ -typedef struct OMX_CONFIG_IMAGEFILTERTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGEFILTERTYPE eImageFilter; -} OMX_CONFIG_IMAGEFILTERTYPE; - - -/** - * Customized U and V for color enhancement - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bColorEnhancement : Enable/disable color enhancement - * nCustomizedU : Practical values: 16-240, range: 0-255, value set for - * U component - * nCustomizedV : Practical values: 16-240, range: 0-255, value set for - * V component - */ -typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bColorEnhancement; - OMX_U8 nCustomizedU; - OMX_U8 nCustomizedV; -} OMX_CONFIG_COLORENHANCEMENTTYPE; - - -/** - * Define color key and color key mask - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nARGBColor : 32bit Alpha, Red, Green, Blue Color - * nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels - */ -typedef struct OMX_CONFIG_COLORKEYTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nARGBColor; - OMX_U32 nARGBMask; -} OMX_CONFIG_COLORKEYTYPE; - - -/** - * List of color blend types for pre/post processing - * - * ENUMS: - * None : No color blending present - * AlphaConstant : Function is (alpha_constant * src) + - * (1 - alpha_constant) * dst) - * AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst) - * Alternate : Function is alternating pixels from src and dst - * And : Function is (src & dst) - * Or : Function is (src | dst) - * Invert : Function is ~src - */ -typedef enum OMX_COLORBLENDTYPE { - OMX_ColorBlendNone, - OMX_ColorBlendAlphaConstant, - OMX_ColorBlendAlphaPerPixel, - OMX_ColorBlendAlternate, - OMX_ColorBlendAnd, - OMX_ColorBlendOr, - OMX_ColorBlendInvert, - OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ColorBlendMax = 0x7FFFFFFF -} OMX_COLORBLENDTYPE; - - -/** - * Color blend configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nRGBAlphaConstant : Constant global alpha values when global alpha is used - * eColorBlend : Color blend type enumeration - */ -typedef struct OMX_CONFIG_COLORBLENDTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nRGBAlphaConstant; - OMX_COLORBLENDTYPE eColorBlend; -} OMX_CONFIG_COLORBLENDTYPE; - - -/** - * Hold frame dimension - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nWidth : Frame width in pixels - * nHeight : Frame height in pixels - */ -typedef struct OMX_FRAMESIZETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nWidth; - OMX_U32 nHeight; -} OMX_FRAMESIZETYPE; - - -/** - * Rotation configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nRotation : +/- integer rotation value - */ -typedef struct OMX_CONFIG_ROTATIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nRotation; -} OMX_CONFIG_ROTATIONTYPE; - - -/** - * Possible mirroring directions for pre/post processing - * - * ENUMS: - * None : No mirroring - * Vertical : Vertical mirroring, flip on X axis - * Horizontal : Horizontal mirroring, flip on Y axis - * Both : Both vertical and horizontal mirroring - */ -typedef enum OMX_MIRRORTYPE { - OMX_MirrorNone = 0, - OMX_MirrorVertical, - OMX_MirrorHorizontal, - OMX_MirrorBoth, - OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MirrorMax = 0x7FFFFFFF -} OMX_MIRRORTYPE; - - -/** - * Mirroring configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eMirror : Mirror type enumeration - */ -typedef struct OMX_CONFIG_MIRRORTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_MIRRORTYPE eMirror; -} OMX_CONFIG_MIRRORTYPE; - - -/** - * Position information only - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nX : X coordinate for the point - * nY : Y coordinate for the point - */ -typedef struct OMX_CONFIG_POINTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nX; - OMX_S32 nY; -} OMX_CONFIG_POINTTYPE; - - -/** - * Frame size plus position - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nLeft : X Coordinate of the top left corner of the rectangle - * nTop : Y Coordinate of the top left corner of the rectangle - * nWidth : Width of the rectangle - * nHeight : Height of the rectangle - */ -typedef struct OMX_CONFIG_RECTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nLeft; - OMX_S32 nTop; - OMX_U32 nWidth; - OMX_U32 nHeight; -} OMX_CONFIG_RECTTYPE; - - -/** - * Deblocking state; it is required to be set up before starting the codec - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bDeblocking : Enable/disable deblocking mode - */ -typedef struct OMX_PARAM_DEBLOCKINGTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bDeblocking; -} OMX_PARAM_DEBLOCKINGTYPE; - - -/** - * Stabilization state - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bStab : Enable/disable frame stabilization state - */ -typedef struct OMX_CONFIG_FRAMESTABTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bStab; -} OMX_CONFIG_FRAMESTABTYPE; - - -/** - * White Balance control type - * - * STRUCT MEMBERS: - * SunLight : Referenced in JSR-234 - * Flash : Optimal for device's integrated flash - */ -typedef enum OMX_WHITEBALCONTROLTYPE { - OMX_WhiteBalControlOff = 0, - OMX_WhiteBalControlAuto, - OMX_WhiteBalControlSunLight, - OMX_WhiteBalControlCloudy, - OMX_WhiteBalControlShade, - OMX_WhiteBalControlTungsten, - OMX_WhiteBalControlFluorescent, - OMX_WhiteBalControlIncandescent, - OMX_WhiteBalControlFlash, - OMX_WhiteBalControlHorizon, - OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_WhiteBalControlMax = 0x7FFFFFFF -} OMX_WHITEBALCONTROLTYPE; - - -/** - * White Balance control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eWhiteBalControl : White balance enumeration - */ -typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_WHITEBALCONTROLTYPE eWhiteBalControl; -} OMX_CONFIG_WHITEBALCONTROLTYPE; - - -/** - * Exposure control type - */ -typedef enum OMX_EXPOSURECONTROLTYPE { - OMX_ExposureControlOff = 0, - OMX_ExposureControlAuto, - OMX_ExposureControlNight, - OMX_ExposureControlBackLight, - OMX_ExposureControlSpotLight, - OMX_ExposureControlSports, - OMX_ExposureControlSnow, - OMX_ExposureControlBeach, - OMX_ExposureControlLargeAperture, - OMX_ExposureControlSmallApperture, - OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ExposureControlMax = 0x7FFFFFFF -} OMX_EXPOSURECONTROLTYPE; - - -/** - * White Balance control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eExposureControl : Exposure control enumeration - */ -typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_EXPOSURECONTROLTYPE eExposureControl; -} OMX_CONFIG_EXPOSURECONTROLTYPE; - - -/** - * Defines sensor supported mode. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nFrameRate : Single shot mode is indicated by a 0 - * bOneShot : Enable for single shot, disable for streaming - * sFrameSize : Framesize - */ -typedef struct OMX_PARAM_SENSORMODETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nFrameRate; - OMX_BOOL bOneShot; - OMX_FRAMESIZETYPE sFrameSize; -} OMX_PARAM_SENSORMODETYPE; - - -/** - * Defines contrast level - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nContrast : Values allowed for contrast -100 to 100, zero means no change - */ -typedef struct OMX_CONFIG_CONTRASTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nContrast; -} OMX_CONFIG_CONTRASTTYPE; - - -/** - * Defines brightness level - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nBrightness : 0-100% - */ -typedef struct OMX_CONFIG_BRIGHTNESSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nBrightness; -} OMX_CONFIG_BRIGHTNESSTYPE; - - -/** - * Defines backlight level configuration for a video sink, e.g. LCD panel - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nBacklight : Values allowed for backlight 0-100% - * nTimeout : Number of milliseconds before backlight automatically turns - * off. A value of 0x0 disables backight timeout - */ -typedef struct OMX_CONFIG_BACKLIGHTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nBacklight; - OMX_U32 nTimeout; -} OMX_CONFIG_BACKLIGHTTYPE; - - -/** - * Defines setting for Gamma - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nGamma : Values allowed for gamma -100 to 100, zero means no change - */ -typedef struct OMX_CONFIG_GAMMATYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nGamma; -} OMX_CONFIG_GAMMATYPE; - - -/** - * Define for setting saturation - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nSaturation : Values allowed for saturation -100 to 100, zero means - * no change - */ -typedef struct OMX_CONFIG_SATURATIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nSaturation; -} OMX_CONFIG_SATURATIONTYPE; - - -/** - * Define for setting Lightness - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nLightness : Values allowed for lightness -100 to 100, zero means no - * change - */ -typedef struct OMX_CONFIG_LIGHTNESSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nLightness; -} OMX_CONFIG_LIGHTNESSTYPE; - - -/** - * Plane blend configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Index of input port associated with the plane. - * nDepth : Depth of the plane in relation to the screen. Higher - * numbered depths are "behind" lower number depths. - * This number defaults to the Port Index number. - * nAlpha : Transparency blending component for the entire plane. - * See blending modes for more detail. - */ -typedef struct OMX_CONFIG_PLANEBLENDTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nDepth; - OMX_U32 nAlpha; -} OMX_CONFIG_PLANEBLENDTYPE; - - -/** - * Define interlace type - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bEnable : Enable control variable for this functionality - * (see below) - * nInterleavePortIndex : Index of input or output port associated with - * the interleaved plane. - * pPlanarPortIndexes[4] : Index of input or output planar ports. - */ -typedef struct OMX_PARAM_INTERLEAVETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; - OMX_U32 nInterleavePortIndex; -} OMX_PARAM_INTERLEAVETYPE; - - -/** - * Defines the picture effect used for an input picture - */ -typedef enum OMX_TRANSITIONEFFECTTYPE { - OMX_EffectNone, - OMX_EffectFadeFromBlack, - OMX_EffectFadeToBlack, - OMX_EffectUnspecifiedThroughConstantColor, - OMX_EffectDissolve, - OMX_EffectWipe, - OMX_EffectUnspecifiedMixOfTwoScenes, - OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_EffectMax = 0x7FFFFFFF -} OMX_TRANSITIONEFFECTTYPE; - - -/** - * Structure used to configure current transition effect - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eEffect : Effect to enable - */ -typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_TRANSITIONEFFECTTYPE eEffect; -} OMX_CONFIG_TRANSITIONEFFECTTYPE; - - -/** - * Defines possible data unit types for encoded video data. The data unit - * types are used both for encoded video input for playback as well as - * encoded video output from recording. - */ -typedef enum OMX_DATAUNITTYPE { - OMX_DataUnitCodedPicture, - OMX_DataUnitVideoSegment, - OMX_DataUnitSeveralSegments, - OMX_DataUnitArbitraryStreamSection, - OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_DataUnitMax = 0x7FFFFFFF -} OMX_DATAUNITTYPE; - - -/** - * Defines possible encapsulation types for coded video data unit. The - * encapsulation information is used both for encoded video input for - * playback as well as encoded video output from recording. - */ -typedef enum OMX_DATAUNITENCAPSULATIONTYPE { - OMX_DataEncapsulationElementaryStream, - OMX_DataEncapsulationGenericPayload, - OMX_DataEncapsulationRtpPayload, - OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_DataEncapsulationMax = 0x7FFFFFFF -} OMX_DATAUNITENCAPSULATIONTYPE; - - -/** - * Structure used to configure the type of being decoded/encoded - */ -typedef struct OMX_PARAM_DATAUNITTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_DATAUNITTYPE eUnitType; - OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType; -} OMX_PARAM_DATAUNITTYPE; - - -/** - * Defines dither types - */ -typedef enum OMX_DITHERTYPE { - OMX_DitherNone, - OMX_DitherOrdered, - OMX_DitherErrorDiffusion, - OMX_DitherOther, - OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_DitherMax = 0x7FFFFFFF -} OMX_DITHERTYPE; - - -/** - * Structure used to configure current type of dithering - */ -typedef struct OMX_CONFIG_DITHERTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_DITHERTYPE eDither; /**< Type of dithering to use */ -} OMX_CONFIG_DITHERTYPE; - -typedef struct OMX_CONFIG_CAPTUREMODETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture - * data as fast as possible (otherwise obey port's frame rate). */ - OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the - * specified number of frames (otherwise the port does not - * terminate the capture until instructed to do so by the client). - * Even if set, the client may manually terminate the capture prior - * to reaching the limit. */ - OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only - * valid if bFrameLimited is set). */ -} OMX_CONFIG_CAPTUREMODETYPE; - -typedef enum OMX_METERINGTYPE { - - OMX_MeteringModeAverage, /**< Center-weighted average metering. */ - OMX_MeteringModeSpot, /**< Spot (partial) metering. */ - OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */ - - OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_EVModeMax = 0x7fffffff -} OMX_METERINGTYPE; - -typedef struct OMX_CONFIG_EXPOSUREVALUETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_METERINGTYPE eMetering; - OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */ - OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */ - OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */ - OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */ - OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */ - OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */ - OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */ -} OMX_CONFIG_EXPOSUREVALUETYPE; - -/** - * Focus region configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bCenter : Use center region as focus region of interest - * bLeft : Use left region as focus region of interest - * bRight : Use right region as focus region of interest - * bTop : Use top region as focus region of interest - * bBottom : Use bottom region as focus region of interest - * bTopLeft : Use top left region as focus region of interest - * bTopRight : Use top right region as focus region of interest - * bBottomLeft : Use bottom left region as focus region of interest - * bBottomRight : Use bottom right region as focus region of interest - */ -typedef struct OMX_CONFIG_FOCUSREGIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bCenter; - OMX_BOOL bLeft; - OMX_BOOL bRight; - OMX_BOOL bTop; - OMX_BOOL bBottom; - OMX_BOOL bTopLeft; - OMX_BOOL bTopRight; - OMX_BOOL bBottomLeft; - OMX_BOOL bBottomRight; -} OMX_CONFIG_FOCUSREGIONTYPE; - -/** - * Focus Status type - */ -typedef enum OMX_FOCUSSTATUSTYPE { - OMX_FocusStatusOff = 0, - OMX_FocusStatusRequest, - OMX_FocusStatusReached, - OMX_FocusStatusUnableToReach, - OMX_FocusStatusLost, - OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_FocusStatusMax = 0x7FFFFFFF -} OMX_FOCUSSTATUSTYPE; - -/** - * Focus status configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFocusStatus : Specifies the focus status - * bCenterStatus : Use center region as focus region of interest - * bLeftStatus : Use left region as focus region of interest - * bRightStatus : Use right region as focus region of interest - * bTopStatus : Use top region as focus region of interest - * bBottomStatus : Use bottom region as focus region of interest - * bTopLeftStatus : Use top left region as focus region of interest - * bTopRightStatus : Use top right region as focus region of interest - * bBottomLeftStatus : Use bottom left region as focus region of interest - * bBottomRightStatus : Use bottom right region as focus region of interest - */ -typedef struct OMX_PARAM_FOCUSSTATUSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_FOCUSSTATUSTYPE eFocusStatus; - OMX_BOOL bCenterStatus; - OMX_BOOL bLeftStatus; - OMX_BOOL bRightStatus; - OMX_BOOL bTopStatus; - OMX_BOOL bBottomStatus; - OMX_BOOL bTopLeftStatus; - OMX_BOOL bTopRightStatus; - OMX_BOOL bBottomLeftStatus; - OMX_BOOL bBottomRightStatus; -} OMX_PARAM_FOCUSSTATUSTYPE; - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Image.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Image.h deleted file mode 100644 index a6d4666..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Image.h +++ /dev/null @@ -1,328 +0,0 @@ -/** - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file OMX_Image.h - OpenMax IL version 1.1.2 - * The structures needed by Image components to exchange parameters and - * configuration data with the components. - */ -#ifndef OMX_Image_h -#define OMX_Image_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - -/** @defgroup imaging OpenMAX IL Imaging Domain - * @ingroup iv - * Structures for OpenMAX IL Imaging domain - * @{ - */ - -/** - * Enumeration used to define the possible image compression coding. - */ -typedef enum OMX_IMAGE_CODINGTYPE { - OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ - OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ - OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ - OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ - OMX_IMAGE_CodingEXIF, /**< EXIF image format */ - OMX_IMAGE_CodingTIFF, /**< TIFF image format */ - OMX_IMAGE_CodingGIF, /**< Graphics image format */ - OMX_IMAGE_CodingPNG, /**< PNG image format */ - OMX_IMAGE_CodingLZW, /**< LZW image format */ - OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ - OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_CodingMax = 0x7FFFFFFF -} OMX_IMAGE_CODINGTYPE; - - -/** - * Data structure used to define an image path. The number of image paths - * for input and output will vary by type of the image component. - * - * Input (aka Source) : Zero Inputs, one Output, - * Splitter : One Input, 2 or more Outputs, - * Processing Element : One Input, one output, - * Mixer : 2 or more inputs, one output, - * Output (aka Sink) : One Input, zero outputs. - * - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output - * image path. If additional vendor specific data is required, it should - * be transmitted to the component using the CustomCommand function. - * Compliant components will prepopulate this structure with optimal - * values during the OMX_GetParameter() command. - * - * STRUCT MEMBERS: - * cMIMEType : MIME type of data for the port - * pNativeRender : Platform specific reference for a display if a - * sync, otherwise this field is 0 - * nFrameWidth : Width of frame to be used on port if - * uncompressed format is used. Use 0 for - * unknown, don't care or variable - * nFrameHeight : Height of frame to be used on port if - * uncompressed format is used. Use 0 for - * unknown, don't care or variable - * nStride : Number of bytes per span of an image (i.e. - * indicates the number of bytes to get from - * span N to span N+1, where negative stride - * indicates the image is bottom up - * nSliceHeight : Height used when encoding in slices - * bFlagErrorConcealment : Turns on error concealment if it is supported by - * the OMX component - * eCompressionFormat : Compression format used in this instance of - * the component. When OMX_IMAGE_CodingUnused is - * specified, eColorFormat is valid - * eColorFormat : Decompressed format used by this component - * pNativeWindow : Platform specific reference for a window object if a - * display sink , otherwise this field is 0x0. - */ -typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; - OMX_NATIVE_DEVICETYPE pNativeRender; - OMX_U32 nFrameWidth; - OMX_U32 nFrameHeight; - OMX_S32 nStride; - OMX_U32 nSliceHeight; - OMX_BOOL bFlagErrorConcealment; - OMX_IMAGE_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_NATIVE_WINDOWTYPE pNativeWindow; -} OMX_IMAGE_PORTDEFINITIONTYPE; - - -/** - * Port format parameter. This structure is used to enumerate the various - * data input/output format supported by the port. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Indicates which port to set - * nIndex : Indicates the enumeration index for the format from - * 0x0 to N-1 - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_IMAGE_CodingUnused is specified, - * eColorFormat is valid - * eColorFormat : Decompressed format used by this component - */ -typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_IMAGE_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; -} OMX_IMAGE_PARAM_PORTFORMATTYPE; - - -/** - * Flash control type - * - * ENUMS - * Torch : Flash forced constantly on - */ -typedef enum OMX_IMAGE_FLASHCONTROLTYPE { - OMX_IMAGE_FlashControlOn = 0, - OMX_IMAGE_FlashControlOff, - OMX_IMAGE_FlashControlAuto, - OMX_IMAGE_FlashControlRedEyeReduction, - OMX_IMAGE_FlashControlFillin, - OMX_IMAGE_FlashControlTorch, - OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_FlashControlMax = 0x7FFFFFFF -} OMX_IMAGE_FLASHCONTROLTYPE; - - -/** - * Flash control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFlashControl : Flash control type - */ -typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; -} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; - - -/** - * Focus control type - */ -typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { - OMX_IMAGE_FocusControlOn = 0, - OMX_IMAGE_FocusControlOff, - OMX_IMAGE_FocusControlAuto, - OMX_IMAGE_FocusControlAutoLock, - OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_FocusControlMax = 0x7FFFFFFF -} OMX_IMAGE_FOCUSCONTROLTYPE; - - -/** - * Focus control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFocusControl : Focus control - * nFocusSteps : Focus can take on values from 0 mm to infinity. - * Interest is only in number of steps over this range. - * nFocusStepIndex : Current focus step index - */ -typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; - OMX_U32 nFocusSteps; - OMX_U32 nFocusStepIndex; -} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; - - -/** - * Q Factor for JPEG compression, which controls the tradeoff between image - * quality and size. Q Factor provides a more simple means of controlling - * JPEG compression quality, without directly programming Quantization - * tables for chroma and luma - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 - * produces the smallest, worst quality images, and a factor - * of 100 produces the largest, best quality images. A - * typical default is 75 for small good quality images - */ -typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQFactor; -} OMX_IMAGE_PARAM_QFACTORTYPE; - -/** - * Quantization table type - */ - -typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { - OMX_IMAGE_QuantizationTableLuma = 0, - OMX_IMAGE_QuantizationTableChroma, - OMX_IMAGE_QuantizationTableChromaCb, - OMX_IMAGE_QuantizationTableChromaCr, - OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF -} OMX_IMAGE_QUANTIZATIONTABLETYPE; - -/** - * JPEG quantization tables are used to determine DCT compression for - * YUV data, as an alternative to specifying Q factor, providing exact - * control of compression - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eQuantizationTable : Quantization table type - * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored - * in increasing columns then by rows of data (i.e. - * row 1, ... row 8). Quantization values are in - * the range 0-255 and stored in linear order - * (i.e. the component will zig-zag the - * quantization table data if required internally) - */ -typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; - OMX_U8 nQuantizationMatrix[64]; -} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; - - -/** - * Huffman table type, the same Huffman table is applied for chroma and - * luma component - */ -typedef enum OMX_IMAGE_HUFFMANTABLETYPE { - OMX_IMAGE_HuffmanTableAC = 0, - OMX_IMAGE_HuffmanTableDC, - OMX_IMAGE_HuffmanTableACLuma, - OMX_IMAGE_HuffmanTableACChroma, - OMX_IMAGE_HuffmanTableDCLuma, - OMX_IMAGE_HuffmanTableDCChroma, - OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF -} OMX_IMAGE_HUFFMANTABLETYPE; - -/** - * JPEG Huffman table - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eHuffmanTable : Huffman table type - * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each - * possible length - * nHuffmanTable[256] : 0-255, the size used for AC and DC - * HuffmanTable are 16 and 162 - */ -typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; - OMX_U8 nNumberOfHuffmanCodeOfLength[16]; - OMX_U8 nHuffmanTable[256]; -}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; - -/** @} */ -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Index.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Index.h deleted file mode 100644 index 44d4ea7..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Index.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** @file OMX_Index.h - OpenMax IL version 1.1.2 - * The OMX_Index header file contains the definitions for both applications - * and components . - */ - - -#ifndef OMX_Index_h -#define OMX_Index_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ -#include - - -/** The OMX_INDEXTYPE enumeration is used to select a structure when either - * getting or setting parameters and/or configuration data. Each entry in - * this enumeration maps to an OMX specified structure. When the - * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods - * are used, the second parameter will always be an entry from this enumeration - * and the third entry will be the structure shown in the comments for the entry. - * For example, if the application is initializing a cropping function, the - * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter - * and would send a pointer to an initialized OMX_RECTTYPE structure as the - * third parameter. - * - * The enumeration entries named with the OMX_Config prefix are sent using - * the OMX_SetConfig command and the enumeration entries named with the - * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. - */ -typedef enum OMX_INDEXTYPE { - - OMX_IndexComponentStartUnused = 0x01000000, - OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ - OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ - OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ - OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ - OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ - OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ - OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ - OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ - OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ - OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ - OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ - - OMX_IndexPortStartUnused = 0x02000000, - OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ - OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ - OMX_IndexReservedStartUnused = 0x03000000, - - /* Audio parameters and configurations */ - OMX_IndexAudioStartUnused = 0x04000000, - OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ - OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ - OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ - OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ - OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ - OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ - OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ - OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ - OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ - OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ - OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ - OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ - OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ - OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ - OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ - OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ - OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ - OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ - OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ - OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ - OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ - OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ - OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ - OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ - OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ - OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ - OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ - - OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ - OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ - OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ - OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ - OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ - OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ - OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ - OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ - OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ - OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ - OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ - OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ - OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ - OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ - OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ - OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ - OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ - OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ - OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ - OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ - - /* Image specific parameters and configurations */ - OMX_IndexImageStartUnused = 0x05000000, - OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ - OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ - OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ - OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ - OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ - OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ - OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ - - /* Video specific parameters and configurations */ - OMX_IndexVideoStartUnused = 0x06000000, - OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ - OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ - OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ - OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ - OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ - OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ - OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ - OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ - OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ - OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ - OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ - OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ - OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ - OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ - OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ - OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ - OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ - OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ - OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ - OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ - OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ - OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ - OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ - OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ - - /* Image & Video common Configurations */ - OMX_IndexCommonStartUnused = 0x07000000, - OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ - OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ - OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ - OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ - OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ - OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ - OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ - OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ - OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ - OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ - OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ - OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ - OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ - OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ - OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ - OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ - OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ - OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ - OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ - OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ - OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ - OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ - OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ - OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ - OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ - OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ - OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ - OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ - OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ - - /* Reserved Configuration range */ - OMX_IndexOtherStartUnused = 0x08000000, - OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ - OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ - OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ - - - /* Reserved Time range */ - OMX_IndexTimeStartUnused = 0x09000000, - OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ - OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ - OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ - OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ - OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ - OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ - OMX_IndexConfigTimeClientStartTime, /** - - -/** - * Enumeration of possible data types which match to multiple domains or no - * domain at all. For types which are vendor specific, a value above - * OMX_OTHER_VENDORTSTART should be used. - */ -typedef enum OMX_OTHER_FORMATTYPE { - OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, - time deltas, etc */ - OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power - management, setting clocks? */ - OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames - dropped, etc */ - OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ - OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific - formats */ - - OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_OTHER_FormatMax = 0x7FFFFFFF -} OMX_OTHER_FORMATTYPE; - -/** - * Enumeration of seek modes. - */ -typedef enum OMX_TIME_SEEKMODETYPE { - OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation - * of the requested seek position over - * the actual seek position if it - * results in a faster seek. */ - OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek - * position over an approximation - * of the requested seek position even - * if it results in a slower seek. */ - OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_SeekModeMax = 0x7FFFFFFF -} OMX_TIME_SEEKMODETYPE; - -/* Structure representing the seekmode of the component */ -typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ -} OMX_TIME_CONFIG_SEEKMODETYPE; - -/** Structure representing a time stamp used with the following configs - * on the Clock Component (CC): - * - * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall - * time - * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media - * time - * OMX_IndexConfigTimeCurrentAudioReference and - * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference - * clock sending SC its reference time - * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends - * this structure to the Clock Component via a SetConfig on its - * client port when it receives a buffer with - * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp - * specified by that buffer for nStartTimestamp. - * - * It’s also used with the following config on components in general: - * - * OMX_IndexConfigTimePosition: IL client querying component position - * (GetConfig) or commanding a component to seek to the given location - * (SetConfig) - */ -typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version - * information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_TICKS nTimestamp; /**< timestamp .*/ -} OMX_TIME_CONFIG_TIMESTAMPTYPE; - -/** Enumeration of possible reference clocks to the media time. */ -typedef enum OMX_TIME_UPDATETYPE { - OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ - OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ - OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ - OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_UpdateMax = 0x7FFFFFFF -} OMX_TIME_UPDATETYPE; - -/** Enumeration of possible reference clocks to the media time. */ -typedef enum OMX_TIME_REFCLOCKTYPE { - OMX_TIME_RefClockNone, /**< Use no references. */ - OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ - OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ - OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_RefClockMax = 0x7FFFFFFF -} OMX_TIME_REFCLOCKTYPE; - -/** Enumeration of clock states. */ -typedef enum OMX_TIME_CLOCKSTATE { - OMX_TIME_ClockStateRunning, /**< Clock running. */ - OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the - * prescribed clients emit their - * start time. */ - OMX_TIME_ClockStateStopped, /**< Clock stopped. */ - OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_ClockStateMax = 0x7FFFFFFF -} OMX_TIME_CLOCKSTATE; - -/** Structure representing a media time request to the clock component. - * - * A client component sends this structure to the Clock Component via a SetConfig - * on its client port to specify a media timestamp the Clock Component - * should emit. The Clock Component should fulfill the request by sending a - * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested - * timestamp. - * - * The client may require a media time request be fulfilled slightly - * earlier than the media time specified. In this case the client specifies - * an offset which is equal to the difference between wall time corresponding - * to the requested media time and the wall time when it will be - * fulfilled. - * - * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to - * time events according to timestamps. If a client must perform an operation O at - * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a - * media time request at T (perhaps specifying an offset to ensure the request fulfillment - * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE - * structure back to the client component, the client may perform operation O (perhaps having - * to wait a slight amount more time itself as specified by the return values). - */ - -typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time - * from others (e.g. the number of the frame to deliver). - * Duplicated in the media time structure that fulfills - * this request. A value of zero is reserved for time scale - * updates. */ - OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ - OMX_TICKS nOffset; /**< Amount of wall clock time by which this - * request should be fulfilled early */ -} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; - -/**< Structure sent from the clock component client either when fulfilling - * a media time request or when the time scale has changed. - * - * In the former case the Clock Component fills this structure and times its emission - * to a client component (via the client port) according to the corresponding media - * time request sent by the client. The Clock Component should time the emission to occur - * when the requested timestamp matches the Clock Component's media time but also the - * prescribed offset early. - * - * Upon scale changes the clock component clears the nClientPrivate data, sends the current - * media time and sets the nScale to the new scale via the client port. It emits a - * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to - * alter processing to accomodate scaling. For instance a video component might skip inter-frames - * in the case of extreme fastforward. Likewise an audio component might add or remove samples - * from an audio frame to scale audio data. - * - * It is expected that some clock components may not be able to fulfill requests - * at exactly the prescribed time. This is acceptable so long as the request is - * fulfilled at least as early as described and not later. This structure provides - * fields the client may use to wait for the remaining time. - * - * The client may use either the nOffset or nWallTimeAtMedia fields to determine the - * wall time until the nMediaTimestamp actually occurs. In the latter case the - * client can get a more accurate value for offset by getting the current wall - * from the cloc component and subtracting it from nWallTimeAtMedia. - */ - -typedef struct OMX_TIME_MEDIATIMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time - * from others. Copied from the media time request. - * A value of zero is reserved for time scale updates. */ - OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ - OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was - * requested then this is the current media time. */ - OMX_TICKS nOffset; /**< Amount of wall clock time by which this - * request was actually fulfilled early */ - - OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. - * A client may compare this value to current - * media time obtained from the Clock Component to determine - * the wall time until the media timestamp is really - * current. */ - OMX_S32 xScale; /**< Current media time scale in Q16 format. */ - OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ - /**< State of the media time. */ -} OMX_TIME_MEDIATIMETYPE; - -/** Structure representing the current media time scale factor. Applicable only to clock - * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via - * the clock component client ports. Upon recieving this config the clock component changes - * the rate by which the media time increases or decreases effectively implementing trick modes. - */ -typedef struct OMX_TIME_CONFIG_SCALETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_S32 xScale; /**< This is a value in Q16 format which is used for - * scaling the media time */ -} OMX_TIME_CONFIG_SCALETYPE; - -/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */ -#define OMX_CLOCKPORT0 0x00000001 -#define OMX_CLOCKPORT1 0x00000002 -#define OMX_CLOCKPORT2 0x00000004 -#define OMX_CLOCKPORT3 0x00000008 -#define OMX_CLOCKPORT4 0x00000010 -#define OMX_CLOCKPORT5 0x00000020 -#define OMX_CLOCKPORT6 0x00000040 -#define OMX_CLOCKPORT7 0x00000080 - -/** Structure representing the current mode of the media clock. - * IL Client uses this config to change or query the mode of the - * media clock of the clock component. Applicable only to clock - * component. - * - * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time - * starts immediately at the prescribed start time. If - * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores - * the given nStartTime and waits for all clients specified in the - * nWaitMask to send starttimes (via - * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts - * the media clock using the earliest start time supplied. */ -typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version - * information */ - OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ - OMX_TICKS nStartTime; /**< Start time of the media time. */ - OMX_TICKS nOffset; /**< Time to offset the media time by - * (e.g. preroll). Media time will be - * reported to be nOffset ticks earlier. - */ - OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ -} OMX_TIME_CONFIG_CLOCKSTATETYPE; - -/** Structure representing the reference clock currently being used to - * compute media time. IL client uses this config to change or query the - * clock component's active reference clock */ -typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ -} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; - -/** Descriptor for setting specifics of power type. - * Note: this structure is listed for backwards compatibility. */ -typedef struct OMX_OTHER_CONFIG_POWERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ -} OMX_OTHER_CONFIG_POWERTYPE; - - -/** Descriptor for setting specifics of stats type. - * Note: this structure is listed for backwards compatibility. */ -typedef struct OMX_OTHER_CONFIG_STATSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - /* what goes here */ -} OMX_OTHER_CONFIG_STATSTYPE; - - -/** - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output other - * path. - */ -typedef struct OMX_OTHER_PORTDEFINITIONTYPE { - OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ -} OMX_OTHER_PORTDEFINITIONTYPE; - -/** Port format parameter. This structure is used to enumerate - * the various data input/output format supported by the port. - */ -typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Indicates which port to set */ - OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ - OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ -} OMX_OTHER_PARAM_PORTFORMATTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Types.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Types.h deleted file mode 100644 index 31be916..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Types.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Types.h - OpenMax IL version 1.1.2 - * The OMX_Types header file contains the primitive type definitions used by - * the core, the application and the component. This file may need to be - * modified to be used on systems that do not have "char" set to 8 bits, - * "short" set to 16 bits and "long" set to 32 bits. - */ - -#ifndef OMX_Types_h -#define OMX_Types_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** The OMX_API and OMX_APIENTRY are platform specific definitions used - * to declare OMX function prototypes. They are modified to meet the - * requirements for a particular platform */ -#ifdef __SYMBIAN32__ -# ifdef __OMX_EXPORTS -# define OMX_API __declspec(dllexport) -# else -# ifdef _WIN32 -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif -# endif -#else -# ifdef _WIN32 -# ifdef __OMX_EXPORTS -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif -# else -# ifdef __OMX_EXPORTS -# define OMX_API -# else -# define OMX_API extern -# endif -# endif -#endif - -#ifndef OMX_APIENTRY -#define OMX_APIENTRY -#endif - -/** OMX_IN is used to identify inputs to an OMX function. This designation - will also be used in the case of a pointer that points to a parameter - that is used as an output. */ -#ifndef OMX_IN -#define OMX_IN -#endif - -/** OMX_OUT is used to identify outputs from an OMX function. This - designation will also be used in the case of a pointer that points - to a parameter that is used as an input. */ -#ifndef OMX_OUT -#define OMX_OUT -#endif - - -/** OMX_INOUT is used to identify parameters that may be either inputs or - outputs from an OMX function at the same time. This designation will - also be used in the case of a pointer that points to a parameter that - is used both as an input and an output. */ -#ifndef OMX_INOUT -#define OMX_INOUT -#endif - -/** OMX_ALL is used to as a wildcard to select all entities of the same type - * when specifying the index, or referring to a object by an index. (i.e. - * use OMX_ALL to indicate all N channels). When used as a port index - * for a config or parameter this OMX_ALL denotes that the config or - * parameter applies to the entire component not just one port. */ -#define OMX_ALL 0xFFFFFFFF - -/** In the following we define groups that help building doxygen documentation */ - -/** @defgroup core OpenMAX IL core - * Functions and structure related to the OMX IL core - */ - - /** @defgroup comp OpenMAX IL component - * Functions and structure related to the OMX IL component - */ - -/** @defgroup rpm Resource and Policy Management - * Structures for resource and policy management of components - */ - -/** @defgroup buf Buffer Management - * Buffer handling functions and structures - */ - -/** @defgroup tun Tunneling - * @ingroup core comp - * Structures and functions to manage tunnels among component ports - */ - -/** @defgroup cp Content Pipes - * @ingroup core - */ - - /** @defgroup metadata Metadata handling - * - */ - -/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ -typedef unsigned char OMX_U8; - -/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ -typedef signed char OMX_S8; - -/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ -typedef unsigned short OMX_U16; - -/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ -typedef signed short OMX_S16; - -/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ -typedef unsigned long OMX_U32; - -/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ -typedef signed long OMX_S32; - - -/* Users with compilers that cannot accept the "long long" designation should - define the OMX_SKIP64BIT macro. It should be noted that this may cause - some components to fail to compile if the component was written to require - 64 bit integral types. However, these components would NOT compile anyway - since the compiler does not support the way the component was written. -*/ -#ifndef OMX_SKIP64BIT -#ifdef __SYMBIAN32__ -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned long long OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed long long OMX_S64; - -#elif defined(WIN32) - -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned __int64 OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed __int64 OMX_S64; - -#else /* WIN32 */ - -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned long long OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed long long OMX_S64; - -#endif /* WIN32 */ -#endif - - -/** The OMX_BOOL type is intended to be used to represent a true or a false - value when passing parameters to and from the OMX core and components. The - OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. - */ -typedef enum OMX_BOOL { - OMX_FALSE = 0, - OMX_TRUE = !OMX_FALSE, - OMX_BOOL_MAX = 0x7FFFFFFF -} OMX_BOOL; - -/** The OMX_PTR type is intended to be used to pass pointers between the OMX - applications and the OMX Core and components. This is a 32 bit pointer and - is aligned on a 32 bit boundary. - */ -typedef void* OMX_PTR; - -/** The OMX_STRING type is intended to be used to pass "C" type strings between - the application and the core and component. The OMX_STRING type is a 32 - bit pointer to a zero terminated string. The pointer is word aligned and - the string is byte aligned. - */ -typedef char* OMX_STRING; - -/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as - buffers between the application and the component and core. The OMX_BYTE - type is a 32 bit pointer to a zero terminated string. The pointer is word - aligned and the string is byte aligned. - */ -typedef unsigned char* OMX_BYTE; - -/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify - at runtime. This identifier should be generated by a component in a way - that guarantees that every instance of the identifier running on the system - is unique. */ -typedef unsigned char OMX_UUIDTYPE[128]; - -/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or - an output port. This enumeration is common across all component types. - */ -typedef enum OMX_DIRTYPE -{ - OMX_DirInput, /**< Port is an input port */ - OMX_DirOutput, /**< Port is an output port */ - OMX_DirMax = 0x7FFFFFFF -} OMX_DIRTYPE; - -/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering - for numerical data (i.e. big endian, or little endian). - */ -typedef enum OMX_ENDIANTYPE -{ - OMX_EndianBig, /**< big endian */ - OMX_EndianLittle, /**< little endian */ - OMX_EndianMax = 0x7FFFFFFF -} OMX_ENDIANTYPE; - - -/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data - is signed or unsigned - */ -typedef enum OMX_NUMERICALDATATYPE -{ - OMX_NumericalDataSigned, /**< signed data */ - OMX_NumericalDataUnsigned, /**< unsigned data */ - OMX_NumercialDataMax = 0x7FFFFFFF -} OMX_NUMERICALDATATYPE; - - -/** Unsigned bounded value type */ -typedef struct OMX_BU32 { - OMX_U32 nValue; /**< actual value */ - OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ - OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ -} OMX_BU32; - - -/** Signed bounded value type */ -typedef struct OMX_BS32 { - OMX_S32 nValue; /**< actual value */ - OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ - OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ -} OMX_BS32; - - -/** Structure representing some time or duration in microseconds. This structure - * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate - * negative deltas and preroll scenarios. The quantity is represented in microseconds - * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based - * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. - * individual audio samples delivered at 192 kHz). The quantity is 64 bit to - * accommodate a large dynamic range (signed 32 bit values would allow only for plus - * or minus 35 minutes). - * - * Implementations with limited precision may convert the signed 64 bit value to - * a signed 32 bit value internally but risk loss of precision. - */ -#ifndef OMX_SKIP64BIT -typedef OMX_S64 OMX_TICKS; -#else -typedef struct OMX_TICKS -{ - OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ - OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ -} OMX_TICKS; -#endif -#define OMX_TICKS_PER_SECOND 1000000 - -/** Define the public interface for the OMX Handle. The core will not use - this value internally, but the application should only use this value. - */ -typedef void* OMX_HANDLETYPE; - -typedef struct OMX_MARKTYPE -{ - OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will - generate a mark event upon - processing the mark. */ - OMX_PTR pMarkData; /**< Application specific data associated with - the mark sent on a mark event to disambiguate - this mark from others. */ -} OMX_MARKTYPE; - - -/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the - * platform & operating specific object used to reference the display - * or can be used by a audio port for native audio rendering */ -typedef void* OMX_NATIVE_DEVICETYPE; - -/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the - * platform & operating specific object used to reference the window */ -typedef void* OMX_NATIVE_WINDOWTYPE; - -/** The OMX_VERSIONTYPE union is used to specify the version for - a structure or component. For a component, the version is entirely - specified by the component vendor. Components doing the same function - from different vendors may or may not have the same version. For - structures, the version shall be set by the entity that allocates the - structure. For structures specified in the OMX 1.1 specification, the - value of the version shall be set to 1.1.0.0 in all cases. Access to the - OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or - by accessing one of the structure elements to, for example, check only - the Major revision. - */ -typedef union OMX_VERSIONTYPE -{ - struct - { - OMX_U8 nVersionMajor; /**< Major version accessor element */ - OMX_U8 nVersionMinor; /**< Minor version accessor element */ - OMX_U8 nRevision; /**< Revision version accessor element */ - OMX_U8 nStep; /**< Step version accessor element */ - } s; - OMX_U32 nVersion; /**< 32 bit value to make accessing the - version easily done in a single word - size copy/compare operation */ -} OMX_VERSIONTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Video.h b/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Video.h deleted file mode 100644 index 163e450..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/khronos/OMX_Video.h +++ /dev/null @@ -1,1060 +0,0 @@ -/** - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * @file OMX_Video.h - OpenMax IL version 1.1.2 - * The structures is needed by Video components to exchange parameters - * and configuration data with OMX components. - */ -#ifndef OMX_Video_h -#define OMX_Video_h - -/** @defgroup video OpenMAX IL Video Domain - * @ingroup iv - * Structures for OpenMAX IL Video domain - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - - -/** - * Enumeration used to define the possible video compression codings. - * NOTE: This essentially refers to file extensions. If the coding is - * being used to specify the ENCODE type, then additional work - * must be done to configure the exact flavor of the compression - * to be used. For decode cases where the user application can - * not differentiate between MPEG-4 and H.264 bit streams, it is - * up to the codec to handle this. - */ -typedef enum OMX_VIDEO_CODINGTYPE { - OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ - OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ - OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ - OMX_VIDEO_CodingH263, /**< H.263 */ - OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ - OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ - OMX_VIDEO_CodingRV, /**< all versions of Real Video */ - OMX_VIDEO_CodingAVC, /**< H.264/AVC */ - OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ - OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_CodingMax = 0x7FFFFFFF -} OMX_VIDEO_CODINGTYPE; - - -/** - * Data structure used to define a video path. The number of Video paths for - * input and output will vary by type of the Video component. - * - * Input (aka Source) : zero Inputs, one Output, - * Splitter : one Input, 2 or more Outputs, - * Processing Element : one Input, one output, - * Mixer : 2 or more inputs, one output, - * Output (aka Sink) : one Input, zero outputs. - * - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output video - * path. If additional vendor specific data is required, it should be - * transmitted to the component using the CustomCommand function. Compliant - * components will prepopulate this structure with optimal values during the - * GetDefaultInitParams command. - * - * STRUCT MEMBERS: - * cMIMEType : MIME type of data for the port - * pNativeRender : Platform specific reference for a display if a - * sync, otherwise this field is 0 - * nFrameWidth : Width of frame to be used on channel if - * uncompressed format is used. Use 0 for unknown, - * don't care or variable - * nFrameHeight : Height of frame to be used on channel if - * uncompressed format is used. Use 0 for unknown, - * don't care or variable - * nStride : Number of bytes per span of an image - * (i.e. indicates the number of bytes to get - * from span N to span N+1, where negative stride - * indicates the image is bottom up - * nSliceHeight : Height used when encoding in slices - * nBitrate : Bit rate of frame to be used on channel if - * compressed format is used. Use 0 for unknown, - * don't care or variable - * xFramerate : Frame rate to be used on channel if uncompressed - * format is used. Use 0 for unknown, don't care or - * variable. Units are Q16 frames per second. - * bFlagErrorConcealment : Turns on error concealment if it is supported by - * the OMX component - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_VIDEO_CodingUnused is - * specified, eColorFormat is used - * eColorFormat : Decompressed format used by this component - * pNativeWindow : Platform specific reference for a window object if a - * display sink , otherwise this field is 0x0. - */ -typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; - OMX_NATIVE_DEVICETYPE pNativeRender; - OMX_U32 nFrameWidth; - OMX_U32 nFrameHeight; - OMX_S32 nStride; - OMX_U32 nSliceHeight; - OMX_U32 nBitrate; - OMX_U32 xFramerate; - OMX_BOOL bFlagErrorConcealment; - OMX_VIDEO_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_NATIVE_WINDOWTYPE pNativeWindow; -} OMX_VIDEO_PORTDEFINITIONTYPE; - -/** - * Port format parameter. This structure is used to enumerate the various - * data input/output format supported by the port. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Indicates which port to set - * nIndex : Indicates the enumeration index for the format from - * 0x0 to N-1 - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_VIDEO_CodingUnused is specified, - * eColorFormat is used - * eColorFormat : Decompressed format used by this component - * xFrameRate : Indicates the video frame rate in Q16 format - */ -typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_VIDEO_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_U32 xFramerate; -} OMX_VIDEO_PARAM_PORTFORMATTYPE; - - -/** - * This is a structure for configuring video compression quantization - * parameter values. Codecs may support different QP values for different - * frame types. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * nQpI : QP value to use for index frames - * nQpP : QP value to use for P frames - * nQpB : QP values to use for bidirectional frames - */ -typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQpI; - OMX_U32 nQpP; - OMX_U32 nQpB; -} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; - - -/** - * Structure for configuration of video fast update parameters. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * bEnableVFU : Enable/Disable video fast update - * nFirstGOB : Specifies the number of the first macroblock row - * nFirstMB : specifies the first MB relative to the specified first GOB - * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB - * and nFirstMB - */ -typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnableVFU; - OMX_U32 nFirstGOB; - OMX_U32 nFirstMB; - OMX_U32 nNumMBs; -} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; - - -/** - * Enumeration of possible bitrate control types - */ -typedef enum OMX_VIDEO_CONTROLRATETYPE { - OMX_Video_ControlRateDisable, - OMX_Video_ControlRateVariable, - OMX_Video_ControlRateConstant, - OMX_Video_ControlRateVariableSkipFrames, - OMX_Video_ControlRateConstantSkipFrames, - OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_Video_ControlRateMax = 0x7FFFFFFF -} OMX_VIDEO_CONTROLRATETYPE; - - -/** - * Structure for configuring bitrate mode of a codec. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : Port that this struct applies to - * eControlRate : Control rate type enum - * nTargetBitrate : Target bitrate to encode with - */ -typedef struct OMX_VIDEO_PARAM_BITRATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_CONTROLRATETYPE eControlRate; - OMX_U32 nTargetBitrate; -} OMX_VIDEO_PARAM_BITRATETYPE; - - -/** - * Enumeration of possible motion vector (MV) types - */ -typedef enum OMX_VIDEO_MOTIONVECTORTYPE { - OMX_Video_MotionVectorPixel, - OMX_Video_MotionVectorHalfPel, - OMX_Video_MotionVectorQuarterPel, - OMX_Video_MotionVectorEighthPel, - OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_Video_MotionVectorMax = 0x7FFFFFFF -} OMX_VIDEO_MOTIONVECTORTYPE; - - -/** - * Structure for configuring the number of motion vectors used as well - * as their accuracy. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : port that this structure applies to - * eAccuracy : Enumerated MV accuracy - * bUnrestrictedMVs : Allow unrestricted MVs - * bFourMV : Allow use of 4 MVs - * sXSearchRange : Search range in horizontal direction for MVs - * sYSearchRange : Search range in vertical direction for MVs - */ -typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; - OMX_BOOL bUnrestrictedMVs; - OMX_BOOL bFourMV; - OMX_S32 sXSearchRange; - OMX_S32 sYSearchRange; -} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; - - -/** - * Enumeration of possible methods to use for Intra Refresh - */ -typedef enum OMX_VIDEO_INTRAREFRESHTYPE { - OMX_VIDEO_IntraRefreshCyclic, - OMX_VIDEO_IntraRefreshAdaptive, - OMX_VIDEO_IntraRefreshBoth, - OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF -} OMX_VIDEO_INTRAREFRESHTYPE; - - -/** - * Structure for configuring intra refresh mode - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eRefreshMode : Cyclic, Adaptive, or Both - * nAirMBs : Number of intra macroblocks to refresh in a frame when - * AIR is enabled - * nAirRef : Number of times a motion marked macroblock has to be - * intra coded - * nCirMBs : Number of consecutive macroblocks to be coded as "intra" - * when CIR is enabled - */ -typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; - OMX_U32 nAirMBs; - OMX_U32 nAirRef; - OMX_U32 nCirMBs; -} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; - - -/** - * Structure for enabling various error correction methods for video - * compression. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bEnableHEC : Enable/disable header extension codes (HEC) - * bEnableResync : Enable/disable resynchronization markers - * nResynchMarkerSpacing : Resynch markers interval (in bits) to be - * applied in the stream - * bEnableDataPartitioning : Enable/disable data partitioning - * bEnableRVLC : Enable/disable reversible variable length - * coding - */ -typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnableHEC; - OMX_BOOL bEnableResync; - OMX_U32 nResynchMarkerSpacing; - OMX_BOOL bEnableDataPartitioning; - OMX_BOOL bEnableRVLC; -} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; - - -/** - * Configuration of variable block-size motion compensation (VBSMC) - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * b16x16 : Enable inter block search 16x16 - * b16x8 : Enable inter block search 16x8 - * b8x16 : Enable inter block search 8x16 - * b8x8 : Enable inter block search 8x8 - * b8x4 : Enable inter block search 8x4 - * b4x8 : Enable inter block search 4x8 - * b4x4 : Enable inter block search 4x4 - */ -typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL b16x16; - OMX_BOOL b16x8; - OMX_BOOL b8x16; - OMX_BOOL b8x8; - OMX_BOOL b8x4; - OMX_BOOL b4x8; - OMX_BOOL b4x4; -} OMX_VIDEO_PARAM_VBSMCTYPE; - - -/** - * H.263 profile types, each profile indicates support for various - * performance bounds and different annexes. - * - * ENUMS: - * Baseline : Baseline Profile: H.263 (V1), no optional modes - * H320 Coding : H.320 Coding Efficiency Backward Compatibility - * Profile: H.263+ (V2), includes annexes I, J, L.4 - * and T - * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), - * includes annex F - * ISWV2 : Interactive Streaming Wireless Profile: H.263+ - * (V2), includes annexes I, J, K and T - * ISWV3 : Interactive Streaming Wireless Profile: H.263++ - * (V3), includes profile 3 and annexes V and W.6.3.8 - * HighCompression : Conversational High Compression Profile: H.263++ - * (V3), includes profiles 1 & 2 and annexes D and U - * Internet : Conversational Internet Profile: H.263++ (V3), - * includes profile 5 and annex K - * Interlace : Conversational Interlace Profile: H.263++ (V3), - * includes profile 5 and annex W.6.3.11 - * HighLatency : High Latency Profile: H.263++ (V3), includes - * profile 6 and annexes O.1 and P.5 - */ -typedef enum OMX_VIDEO_H263PROFILETYPE { - OMX_VIDEO_H263ProfileBaseline = 0x01, - OMX_VIDEO_H263ProfileH320Coding = 0x02, - OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, - OMX_VIDEO_H263ProfileISWV2 = 0x08, - OMX_VIDEO_H263ProfileISWV3 = 0x10, - OMX_VIDEO_H263ProfileHighCompression = 0x20, - OMX_VIDEO_H263ProfileInternet = 0x40, - OMX_VIDEO_H263ProfileInterlace = 0x80, - OMX_VIDEO_H263ProfileHighLatency = 0x100, - OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_H263PROFILETYPE; - - -/** - * H.263 level types, each level indicates support for various frame sizes, - * bit rates, decoder frame rates. - */ -typedef enum OMX_VIDEO_H263LEVELTYPE { - OMX_VIDEO_H263Level10 = 0x01, - OMX_VIDEO_H263Level20 = 0x02, - OMX_VIDEO_H263Level30 = 0x04, - OMX_VIDEO_H263Level40 = 0x08, - OMX_VIDEO_H263Level45 = 0x10, - OMX_VIDEO_H263Level50 = 0x20, - OMX_VIDEO_H263Level60 = 0x40, - OMX_VIDEO_H263Level70 = 0x80, - OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_H263LevelMax = 0x7FFFFFFF -} OMX_VIDEO_H263LEVELTYPE; - - -/** - * Specifies the picture type. These values should be OR'd to signal all - * pictures types which are allowed. - * - * ENUMS: - * Generic Picture Types: I, P and B - * H.263 Specific Picture Types: SI and SP - * H.264 Specific Picture Types: EI and EP - * MPEG-4 Specific Picture Types: S - */ -typedef enum OMX_VIDEO_PICTURETYPE { - OMX_VIDEO_PictureTypeI = 0x01, - OMX_VIDEO_PictureTypeP = 0x02, - OMX_VIDEO_PictureTypeB = 0x04, - OMX_VIDEO_PictureTypeSI = 0x08, - OMX_VIDEO_PictureTypeSP = 0x10, - OMX_VIDEO_PictureTypeEI = 0x11, - OMX_VIDEO_PictureTypeEP = 0x12, - OMX_VIDEO_PictureTypeS = 0x14, - OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF -} OMX_VIDEO_PICTURETYPE; - - -/** - * H.263 Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * eProfile : H.263 profile(s) to use - * eLevel : H.263 level(s) to use - * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE - * (specified in the 1998 version of H.263) to - * indicate custom picture sizes or clock - * frequencies - * nAllowedPictureTypes : Specifies the picture types allowed in the - * bitstream - * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is - * not constrained. It is recommended to change - * the value of the RTYPE bit for each reference - * picture in error-free communication - * nPictureHeaderRepetition : Specifies the frequency of picture header - * repetition - * nGOBHeaderInterval : Specifies the interval of non-empty GOB - * headers in units of GOBs - */ -typedef struct OMX_VIDEO_PARAM_H263TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_VIDEO_H263PROFILETYPE eProfile; - OMX_VIDEO_H263LEVELTYPE eLevel; - OMX_BOOL bPLUSPTYPEAllowed; - OMX_U32 nAllowedPictureTypes; - OMX_BOOL bForceRoundingTypeToZero; - OMX_U32 nPictureHeaderRepetition; - OMX_U32 nGOBHeaderInterval; -} OMX_VIDEO_PARAM_H263TYPE; - - -/** - * MPEG-2 profile types, each profile indicates support for various - * performance bounds and different annexes. - */ -typedef enum OMX_VIDEO_MPEG2PROFILETYPE { - OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ - OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ - OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ - OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ - OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ - OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ - OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG2PROFILETYPE; - - -/** - * MPEG-2 level types, each level indicates support for various frame - * sizes, bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_MPEG2LEVELTYPE { - OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ - OMX_VIDEO_MPEG2LevelML, /**< Main Level */ - OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ - OMX_VIDEO_MPEG2LevelHL, /**< High Level */ - OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG2LEVELTYPE; - - -/** - * MPEG-2 params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * eProfile : MPEG-2 profile(s) to use - * eLevel : MPEG-2 levels(s) to use - */ -typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_VIDEO_MPEG2PROFILETYPE eProfile; - OMX_VIDEO_MPEG2LEVELTYPE eLevel; -} OMX_VIDEO_PARAM_MPEG2TYPE; - - -/** - * MPEG-4 profile types, each profile indicates support for various - * performance bounds and different annexes. - * - * ENUMS: - * - Simple Profile, Levels 1-3 - * - Simple Scalable Profile, Levels 1-2 - * - Core Profile, Levels 1-2 - * - Main Profile, Levels 2-4 - * - N-bit Profile, Level 2 - * - Scalable Texture Profile, Level 1 - * - Simple Face Animation Profile, Levels 1-2 - * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 - * - Basic Animated Texture Profile, Levels 1-2 - * - Hybrid Profile, Levels 1-2 - * - Advanced Real Time Simple Profiles, Levels 1-4 - * - Core Scalable Profile, Levels 1-3 - * - Advanced Coding Efficiency Profile, Levels 1-4 - * - Advanced Core Profile, Levels 1-2 - * - Advanced Scalable Texture, Levels 2-3 - */ -typedef enum OMX_VIDEO_MPEG4PROFILETYPE { - OMX_VIDEO_MPEG4ProfileSimple = 0x01, - OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, - OMX_VIDEO_MPEG4ProfileCore = 0x04, - OMX_VIDEO_MPEG4ProfileMain = 0x08, - OMX_VIDEO_MPEG4ProfileNbit = 0x10, - OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, - OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, - OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, - OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, - OMX_VIDEO_MPEG4ProfileHybrid = 0x200, - OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, - OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, - OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, - OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, - OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, - OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, - OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG4PROFILETYPE; - - -/** - * MPEG-4 level types, each level indicates support for various frame - * sizes, bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_MPEG4LEVELTYPE { - OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ - OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ - OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ - OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ - OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ - OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ - OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ - OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ - OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG4LEVELTYPE; - - -/** - * MPEG-4 configuration. This structure handles configuration options - * which are specific to MPEG4 algorithms - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ - * Annex K). Put zero if not used - * bSVH : Enable Short Video Header mode - * bGov : Flag to enable GOV - * nPFrames : Number of P frames between each I frame (also called - * GOV period) - * nBFrames : Number of B frames between each I frame - * nIDCVLCThreshold : Value of intra DC VLC threshold - * bACPred : Flag to use ac prediction - * nMaxPacketSize : Maximum size of packet in bytes. - * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. - * Interpreted as described in MPEG4 standard. - * eProfile : MPEG-4 profile(s) to use. - * eLevel : MPEG-4 level(s) to use. - * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream - * nHeaderExtension : Specifies the number of consecutive video packet - * headers within a VOP - * bReversibleVLC : Specifies whether reversible variable length coding - * is in use - */ -typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nSliceHeaderSpacing; - OMX_BOOL bSVH; - OMX_BOOL bGov; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_U32 nIDCVLCThreshold; - OMX_BOOL bACPred; - OMX_U32 nMaxPacketSize; - OMX_U32 nTimeIncRes; - OMX_VIDEO_MPEG4PROFILETYPE eProfile; - OMX_VIDEO_MPEG4LEVELTYPE eLevel; - OMX_U32 nAllowedPictureTypes; - OMX_U32 nHeaderExtension; - OMX_BOOL bReversibleVLC; -} OMX_VIDEO_PARAM_MPEG4TYPE; - - -/** - * WMV Versions - */ -typedef enum OMX_VIDEO_WMVFORMATTYPE { - OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ - OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ - OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ - OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ - OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF -} OMX_VIDEO_WMVFORMATTYPE; - - -/** - * WMV Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of WMV stream / data - */ -typedef struct OMX_VIDEO_PARAM_WMVTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_WMVFORMATTYPE eFormat; -} OMX_VIDEO_PARAM_WMVTYPE; - - -/** - * Real Video Version - */ -typedef enum OMX_VIDEO_RVFORMATTYPE { - OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ - OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ - OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ - OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ - OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_RVFormatMax = 0x7FFFFFFF -} OMX_VIDEO_RVFORMATTYPE; - - -/** - * Real Video Params - * - * STUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of RV stream / data - * nBitsPerPixel : Bits per pixel coded in the frame - * nPaddedWidth : Padded width in pixel of a video frame - * nPaddedHeight : Padded Height in pixels of a video frame - * nFrameRate : Rate of video in frames per second - * nBitstreamFlags : Flags which internal information about the bitstream - * nBitstreamVersion : Bitstream version - * nMaxEncodeFrameSize: Max encoded frame size - * bEnablePostFilter : Turn on/off post filter - * bEnableTemporalInterpolation : Turn on/off temporal interpolation - * bEnableLatencyMode : When enabled, the decoder does not display a decoded - * frame until it has detected that no enhancement layer - * frames or dependent B frames will be coming. This - * detection usually occurs when a subsequent non-B - * frame is encountered - */ -typedef struct OMX_VIDEO_PARAM_RVTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_RVFORMATTYPE eFormat; - OMX_U16 nBitsPerPixel; - OMX_U16 nPaddedWidth; - OMX_U16 nPaddedHeight; - OMX_U32 nFrameRate; - OMX_U32 nBitstreamFlags; - OMX_U32 nBitstreamVersion; - OMX_U32 nMaxEncodeFrameSize; - OMX_BOOL bEnablePostFilter; - OMX_BOOL bEnableTemporalInterpolation; - OMX_BOOL bEnableLatencyMode; -} OMX_VIDEO_PARAM_RVTYPE; - - -/** - * AVC profile types, each profile indicates support for various - * performance bounds and different annexes. - */ -typedef enum OMX_VIDEO_AVCPROFILETYPE { - OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ - OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ - OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ - OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ - OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ - OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ - OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ - OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF -} OMX_VIDEO_AVCPROFILETYPE; - - -/** - * AVC level types, each level indicates support for various frame sizes, - * bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_AVCLEVELTYPE { - OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ - OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ - OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ - OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ - OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ - OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ - OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ - OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ - OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ - OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ - OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ - OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ - OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ - OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ - OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ - OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ - OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF -} OMX_VIDEO_AVCLEVELTYPE; - - -/** - * AVC loop filter modes - * - * OMX_VIDEO_AVCLoopFilterEnable : Enable - * OMX_VIDEO_AVCLoopFilterDisable : Disable - * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries - */ -typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { - OMX_VIDEO_AVCLoopFilterEnable = 0, - OMX_VIDEO_AVCLoopFilterDisable, - OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, - OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF -} OMX_VIDEO_AVCLOOPFILTERTYPE; - - -/** - * AVC params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nSliceHeaderSpacing : Number of macroblocks between slice header, put - * zero if not used - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * bUseHadamard : Enable/disable Hadamard transform - * nRefFrames : Max number of reference frames to use for inter - * motion search (1-16) - * nRefIdxTrailing : Pic param set ref frame index (index into ref - * frame buffer of trailing frames list), B frame - * support - * nRefIdxForward : Pic param set ref frame index (index into ref - * frame buffer of forward frames list), B frame - * support - * bEnableUEP : Enable/disable unequal error protection. This - * is only valid of data partitioning is enabled. - * bEnableFMO : Enable/disable flexible macroblock ordering - * bEnableASO : Enable/disable arbitrary slice ordering - * bEnableRS : Enable/disable sending of redundant slices - * eProfile : AVC profile(s) to use - * eLevel : AVC level(s) to use - * nAllowedPictureTypes : Specifies the picture types allowed in the - * bitstream - * bFrameMBsOnly : specifies that every coded picture of the - * coded video sequence is a coded frame - * containing only frame macroblocks - * bMBAFF : Enable/disable switching between frame and - * field macroblocks within a picture - * bEntropyCodingCABAC : Entropy decoding method to be applied for the - * syntax elements for which two descriptors appear - * in the syntax tables - * bWeightedPPrediction : Enable/disable weighted prediction shall not - * be applied to P and SP slices - * nWeightedBipredicitonMode : Default weighted prediction is applied to B - * slices - * bconstIpred : Enable/disable intra prediction - * bDirect8x8Inference : Specifies the method used in the derivation - * process for luma motion vectors for B_Skip, - * B_Direct_16x16 and B_Direct_8x8 as specified - * in subclause 8.4.1.2 of the AVC spec - * bDirectSpatialTemporal : Flag indicating spatial or temporal direct - * mode used in B slice coding (related to - * bDirect8x8Inference) . Spatial direct mode is - * more common and should be the default. - * nCabacInitIdx : Index used to init CABAC contexts - * eLoopFilterMode : Enable/disable loop filter - */ -typedef struct OMX_VIDEO_PARAM_AVCTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nSliceHeaderSpacing; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_BOOL bUseHadamard; - OMX_U32 nRefFrames; - OMX_U32 nRefIdx10ActiveMinus1; - OMX_U32 nRefIdx11ActiveMinus1; - OMX_BOOL bEnableUEP; - OMX_BOOL bEnableFMO; - OMX_BOOL bEnableASO; - OMX_BOOL bEnableRS; - OMX_VIDEO_AVCPROFILETYPE eProfile; - OMX_VIDEO_AVCLEVELTYPE eLevel; - OMX_U32 nAllowedPictureTypes; - OMX_BOOL bFrameMBsOnly; - OMX_BOOL bMBAFF; - OMX_BOOL bEntropyCodingCABAC; - OMX_BOOL bWeightedPPrediction; - OMX_U32 nWeightedBipredicitonMode; - OMX_BOOL bconstIpred ; - OMX_BOOL bDirect8x8Inference; - OMX_BOOL bDirectSpatialTemporal; - OMX_U32 nCabacInitIdc; - OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; -} OMX_VIDEO_PARAM_AVCTYPE; - -typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, - or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ - OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, - or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ - OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, - This parameter is valid only for - OMX_IndexParamVideoProfileLevelQuerySupported index, - For all other indices this parameter is to be ignored. */ -} OMX_VIDEO_PARAM_PROFILELEVELTYPE; - -/** - * Structure for dynamically configuring bitrate mode of a codec. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : Port that this struct applies to - * nEncodeBitrate : Target average bitrate to be generated in bps - */ -typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nEncodeBitrate; -} OMX_VIDEO_CONFIG_BITRATETYPE; - -/** - * Defines Encoder Frame Rate setting - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * xEncodeFramerate : Encoding framerate represented in Q16 format - */ -typedef struct OMX_CONFIG_FRAMERATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 xEncodeFramerate; /* Q16 format */ -} OMX_CONFIG_FRAMERATETYPE; - -typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL IntraRefreshVOP; -} OMX_CONFIG_INTRAREFRESHVOPTYPE; - -typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ - OMX_U8 ErrMap[1]; /* Error map hint */ -} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; - -typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnabled; -} OMX_CONFIG_MBERRORREPORTINGTYPE; - -typedef struct OMX_PARAM_MACROBLOCKSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nMacroblocks; -} OMX_PARAM_MACROBLOCKSTYPE; - -/** - * AVC Slice Mode modes - * - * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame - * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame - * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame - */ -typedef enum OMX_VIDEO_AVCSLICEMODETYPE { - OMX_VIDEO_SLICEMODE_AVCDefault = 0, - OMX_VIDEO_SLICEMODE_AVCMBSlice, - OMX_VIDEO_SLICEMODE_AVCByteSlice, - OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF -} OMX_VIDEO_AVCSLICEMODETYPE; - -/** - * AVC FMO Slice Mode Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nNumSliceGroups : Specifies the number of slice groups - * nSliceGroupMapType : Specifies the type of slice groups - * eSliceMode : Specifies the type of slice - */ -typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U8 nNumSliceGroups; - OMX_U8 nSliceGroupMapType; - OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; -} OMX_VIDEO_PARAM_AVCSLICEFMO; - -/** - * AVC IDR Period Configs - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nIDRPeriod : Specifies periodicity of IDR frames - * nPFrames : Specifies internal of coding Intra frames - */ -typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIDRPeriod; - OMX_U32 nPFrames; -} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; - -/** - * AVC NAL Size Configs - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nNaluBytes : Specifies the NAL unit size - */ -typedef struct OMX_VIDEO_CONFIG_NALSIZE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nNaluBytes; -} OMX_VIDEO_CONFIG_NALSIZE; - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Def.h b/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Def.h deleted file mode 100644 index 2b4df69..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Def.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Def.h - * @brief SEC_OMX specific define - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_DEF -#define SEC_OMX_DEF - -#include "OMX_Types.h" -#include "OMX_IVCommon.h" - -#define VERSIONMAJOR_NUMBER 1 -#define VERSIONMINOR_NUMBER 0 -#define REVISION_NUMBER 0 -#define STEP_NUMBER 0 - - -#define MAX_OMX_COMPONENT_NUM 20 -#define MAX_OMX_COMPONENT_ROLE_NUM 10 -#define MAX_OMX_COMPONENT_NAME_SIZE OMX_MAX_STRINGNAME_SIZE -#define MAX_OMX_COMPONENT_ROLE_SIZE OMX_MAX_STRINGNAME_SIZE -#define MAX_OMX_COMPONENT_LIBNAME_SIZE OMX_MAX_STRINGNAME_SIZE * 2 -#define MAX_OMX_MIMETYPE_SIZE OMX_MAX_STRINGNAME_SIZE - -#define MAX_TIMESTAMP 17 -#define MAX_FLAGS 17 - -#define SEC_OMX_INSTALL_PATH "/system/lib/omx/" - -typedef enum _SEC_CODEC_TYPE -{ - SW_CODEC, - HW_VIDEO_DEC_CODEC, - HW_VIDEO_ENC_CODEC, - HW_AUDIO_DEC_CODEC, - HW_AUDIO_ENC_CODEC -} SEC_CODEC_TYPE; - -typedef struct _SEC_OMX_PRIORITYMGMTTYPE -{ - OMX_U32 nGroupPriority; /* the value 0 represents the highest priority */ - /* for a group of components */ - OMX_U32 nGroupID; -} SEC_OMX_PRIORITYMGMTTYPE; - -typedef enum _SEC_OMX_INDEXTYPE -{ -#define SEC_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.ThumbnailMode" - OMX_IndexVendorThumbnailMode = 0x7F000001, -#define SEC_INDEX_CONFIG_VIDEO_INTRAPERIOD "OMX.SEC.index.VideoIntraPeriod" - OMX_IndexConfigVideoIntraPeriod = 0x7F000002, - - /* for Android Native Window */ -#define SEC_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers" - OMX_IndexParamEnableAndroidBuffers = 0x7F000011, -#define SEC_INDEX_PARAM_GET_ANB "OMX.google.android.index.getAndroidNativeBufferUsage" - OMX_IndexParamGetAndroidNativeBuffer = 0x7F000012, -#define SEC_INDEX_PARAM_USE_ANB "OMX.google.android.index.useAndroidNativeBuffer" - OMX_IndexParamUseAndroidNativeBuffer = 0x7F000013, - /* for Android Store Metadata Inbuffer */ -#define SEC_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.google.android.index.storeMetaDataInBuffers" - OMX_IndexParamStoreMetaDataBuffer = 0x7F000014, - - /* for Android PV OpenCore*/ - OMX_COMPONENT_CAPABILITY_TYPE_INDEX = 0xFF7A347 -} SEC_OMX_INDEXTYPE; - -typedef enum _SEC_OMX_ERRORTYPE -{ - OMX_ErrorNoEOF = (OMX_S32) 0x90000001, - OMX_ErrorInputDataDecodeYet = (OMX_S32) 0x90000002, - OMX_ErrorInputDataEncodeYet = (OMX_S32) 0x90000003, - OMX_ErrorMFCInit = (OMX_S32) 0x90000004 -} SEC_OMX_ERRORTYPE; - -typedef enum _SEC_OMX_COMMANDTYPE -{ - SEC_OMX_CommandComponentDeInit = 0x7F000001, - SEC_OMX_CommandEmptyBuffer, - SEC_OMX_CommandFillBuffer -} SEC_OMX_COMMANDTYPE; - -typedef enum _SEC_OMX_TRANS_STATETYPE { - SEC_OMX_TransStateInvalid, - SEC_OMX_TransStateLoadedToIdle, - SEC_OMX_TransStateIdleToExecuting, - SEC_OMX_TransStateExecutingToIdle, - SEC_OMX_TransStateIdleToLoaded, - SEC_OMX_TransStateMax = 0X7FFFFFFF -} SEC_OMX_TRANS_STATETYPE; - -typedef enum _SEC_OMX_COLOR_FORMATTYPE { - OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */ - OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002, - OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003, - OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, /* 0x7FC00002 */ -#ifdef S3D_SUPPORT - OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR = 0x7FC00003, /* 0x7FC00003 */ - OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL = 0x7FC00004, /* 0x7FC00004 */ - OMX_SEC_COLOR_FormatNV12Tiled_TB_LR = 0x7FC00005, /* 0x7FC00005 */ - OMX_SEC_COLOR_FormatNV12Tiled_TB_RL = 0x7FC00006, /* 0x7FC00006 */ - OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR = 0x7FC00007, /* 0x7FC00007 */ - OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL = 0x7FC00008, /* 0x7FC00008 */ - OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR = 0x7FC00009, /* 0x7FC00009 */ - OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL = 0x7FC0000A, /* 0x7FC0000A */ - OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR = 0x7FC0000B, /* 0x7FC0000B */ - OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL = 0x7FC0000C, /* 0x7FC0000C */ - OMX_SEC_COLOR_FormatYUV420Planar_TB_LR = 0x7FC0000D, /* 0x7FC0000D */ - OMX_SEC_COLOR_FormatYUV420Planar_TB_RL = 0x7FC0000E, /* 0x7FC0000E */ -#endif - OMX_SEC_COLOR_FormatNV21LPhysicalAddress = 0x7F000010, - OMX_SEC_COLOR_FormatNV21Linear = 0x7F000011, - - /* for Android Native Window */ - OMX_SEC_COLOR_FormatANBYUV420SemiPlanar = 0x100, - /* for Android SurfaceMediaSource*/ - OMX_COLOR_FormatAndroidOpaque = 0x7F000789 -}SEC_OMX_COLOR_FORMATTYPE; - -typedef enum _SEC_OMX_SUPPORTFORMAT_TYPE -{ - supportFormat_0 = 0x00, - supportFormat_1, - supportFormat_2, - supportFormat_3, - supportFormat_4, - supportFormat_5, - supportFormat_6, - supportFormat_7, - supportFormat_8 -} SEC_OMX_SUPPORTFORMAT_TYPE; - -/* for Android PV OpenCore*/ -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; - -typedef struct _SEC_OMX_VIDEO_PROFILELEVEL -{ - OMX_S32 profile; - OMX_S32 level; -} SEC_OMX_VIDEO_PROFILELEVEL; - -#define OMX_VIDEO_CodingVPX 0x09 /**< Google VPX, formerly known as On2 VP8 */ - -#ifndef __OMX_EXPORTS -#define __OMX_EXPORTS -#define SEC_EXPORT_REF __attribute__((visibility("default"))) -#define SEC_IMPORT_REF __attribute__((visibility("default"))) -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Macros.h b/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Macros.h deleted file mode 100644 index 853d0ac..0000000 --- a/exynos4/multimedia/openmax/sec_omx/include/sec/SEC_OMX_Macros.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OMX_Macros.h - * @brief Macros - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OMX_MACROS -#define SEC_OMX_MACROS - -#include "SEC_OMX_Def.h" -#include "SEC_OSAL_Memory.h" - - -/* - * MACROS - */ -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4) -#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) -#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) -#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) - -#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \ - do { \ - SEC_OSAL_Memset((_struct_), 0, sizeof(_structType_)); \ - (_struct_)->nSize = sizeof(_structType_); \ - (_struct_)->nVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; \ - (_struct_)->nVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; \ - (_struct_)->nVersion.s.nRevision = REVISION_NUMBER; \ - (_struct_)->nVersion.s.nStep = STEP_NUMBER; \ - } while (0) - -/* - * Port Specific - */ -#define SEC_TUNNEL_ESTABLISHED 0x0001 -#define SEC_TUNNEL_IS_SUPPLIER 0x0002 - -#define CHECK_PORT_BEING_FLUSHED(port) (port->bIsPortFlushed == OMX_TRUE) -#define CHECK_PORT_BEING_DISABLED(port) (port->bIsPortDisabled == OMX_TRUE) -#define CHECK_PORT_ENABLED(port) (port->portDefinition.bEnabled == OMX_TRUE) -#define CHECK_PORT_POPULATED(port) (port->portDefinition.bPopulated == OMX_TRUE) -#define CHECK_PORT_TUNNELED(port) (port->tunnelFlags & SEC_TUNNEL_ESTABLISHED) -#define CHECK_PORT_BUFFER_SUPPLIER(port) (port->tunnelFlags & SEC_TUNNEL_IS_SUPPLIER) - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/Android.mk b/exynos4/multimedia/openmax/sec_omx/osal/Android.mk deleted file mode 100644 index 5dcbeee..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - SEC_OSAL_Android.cpp \ - SEC_OSAL_Event.c \ - SEC_OSAL_Queue.c \ - SEC_OSAL_ETC.c \ - SEC_OSAL_Mutex.c \ - SEC_OSAL_Thread.c \ - SEC_OSAL_Memory.c \ - SEC_OSAL_Semaphore.c \ - SEC_OSAL_Library.c \ - SEC_OSAL_Log.c - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := libsecosal - -LOCAL_CFLAGS := - -ifeq ($(BOARD_USE_S3D_SUPPORT), true) -LOCAL_CFLAGS += -DS3D_SUPPORT -endif - -LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libcutils libutils \ - libui \ - libhardware \ - libandroid_runtime \ - libsurfaceflinger_client \ - libbinder \ - libmedia - -LOCAL_C_INCLUDES := \ - $(SEC_OMX_INC)/khronos \ - $(SEC_OMX_INC)/sec \ - $(SEC_OMX_TOP)/osal \ - $(SEC_OMX_COMPONENT)/common \ - $(SEC_OMX_COMPONENT)/video/dec \ - $(BOARD_HAL_PATH)/include \ - $(BOARD_HAL_PATH)/libump/include - -include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.cpp b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.cpp deleted file mode 100644 index 2a51de9..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.cpp +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Android.cpp - * @brief - * @author Seungbeom Kim (sbcrux.kim@samsung.com) - * @author Hyeyeon Chung (hyeon.chung@samsung.com) - * @author Yunji Kim (yunji.kim@samsung.com) - * @author Jinsung Yang (jsgood.yang@samsung.com) - * @version 1.1.0 - * @history - * 2011.7.15 : Create - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "gralloc_priv.h" - -#include "SEC_OSAL_Semaphore.h" -#include "SEC_OMX_Baseport.h" -#include "SEC_OMX_Basecomponent.h" -#include "SEC_OMX_Macros.h" -#include "SEC_OMX_Vdec.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_OSAL_Android" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - -using namespace android; - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE useAndroidNativeBuffer( - SEC_OMX_BASEPORT *pSECPort, - OMX_BUFFERHEADERTYPE **ppBufferHdr, - OMX_U32 nPortIndex, - OMX_PTR pAppPrivate, - OMX_U32 nSizeBytes, - OMX_U8 *pBuffer) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; - unsigned int i = 0; - - FunctionIn(); - - if (pSECPort == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pSECPort->portState != OMX_StateIdle) { - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); - if (temp_bufferHeader == NULL) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); - - for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { - if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { - pSECPort->bufferHeader[i] = temp_bufferHeader; - pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); - INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); - temp_bufferHeader->pBuffer = pBuffer; - temp_bufferHeader->nAllocLen = nSizeBytes; - temp_bufferHeader->pAppPrivate = pAppPrivate; - if (nPortIndex == INPUT_PORT_INDEX) - temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; - else - temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; - - pSECPort->assignedBufferNum++; - if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { - pSECPort->portDefinition.bPopulated = OMX_TRUE; - /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ - SEC_OSAL_SemaphorePost(pSECPort->loadedResource); - /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ - } - *ppBufferHdr = temp_bufferHeader; - goto EXIT; - } - } - - SEC_OSAL_Free(temp_bufferHeader); - ret = OMX_ErrorInsufficientResources; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_LockANBHandle( - OMX_IN OMX_U32 handle, - OMX_IN OMX_U32 width, - OMX_IN OMX_U32 height, - OMX_IN OMX_COLOR_FORMATTYPE format, - OMX_OUT OMX_PTR *vaddr) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - GraphicBufferMapper &mapper = GraphicBufferMapper::get(); - buffer_handle_t bufferHandle = (buffer_handle_t) handle; - Rect bounds(width, height); - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); - - int usage = 0; - - switch (format) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: -#ifdef S3D_SUPPORT - case OMX_SEC_COLOR_FormatNV12Tiled_SBS_LR: - case OMX_SEC_COLOR_FormatNV12Tiled_SBS_RL: - case OMX_SEC_COLOR_FormatNV12Tiled_TB_LR: - case OMX_SEC_COLOR_FormatNV12Tiled_TB_RL: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_LR: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_SBS_RL: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_LR: - case OMX_SEC_COLOR_FormatYUV420SemiPlanar_TB_RL: - case OMX_SEC_COLOR_FormatYUV420Planar_SBS_LR: - case OMX_SEC_COLOR_FormatYUV420Planar_SBS_RL: - case OMX_SEC_COLOR_FormatYUV420Planar_TB_LR: - case OMX_SEC_COLOR_FormatYUV420Planar_TB_RL: -#endif - case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: - usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR; - break; - default: - usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; - break; - } - - if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.lock() fail", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_UnlockANBHandle(OMX_IN OMX_U32 handle) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - GraphicBufferMapper &mapper = GraphicBufferMapper::get(); - buffer_handle_t bufferHandle = (buffer_handle_t) handle; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); - - if (mapper.unlock(bufferHandle) != 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.unlock() fail", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_GetPhysANBHandle( - OMX_IN OMX_U32 handle, - OMX_OUT OMX_PTR *paddr) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - GraphicBufferMapper &mapper = GraphicBufferMapper::get(); - buffer_handle_t bufferHandle = (buffer_handle_t) handle; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); - - if (mapper.getphys(bufferHandle, paddr) != 0) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: mapper.getphys() fail", __func__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_LockANB( - OMX_IN OMX_PTR pBuffer, - OMX_IN OMX_U32 width, - OMX_IN OMX_U32 height, - OMX_IN OMX_COLOR_FORMATTYPE format, - OMX_OUT OMX_U32 *pStride, - OMX_OUT OMX_PTR *vaddr) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; - - ret = SEC_OSAL_LockANBHandle((OMX_U32)pANB->handle, width, height, format, vaddr); - *pStride = pANB->stride; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_UnlockANB(OMX_IN OMX_PTR pBuffer) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; - - ret = SEC_OSAL_UnlockANBHandle((OMX_U32)pANB->handle); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_GetPhysANB( - OMX_IN OMX_PTR pBuffer, - OMX_OUT OMX_PTR *paddr) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; - - ret = SEC_OSAL_GetPhysANBHandle((OMX_U32)pANB->handle, paddr); - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_GetANBParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - switch (nIndex) { - case OMX_IndexParamGetAndroidNativeBuffer: - { - GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure; - OMX_U32 portIndex = pANBParams->nPortIndex; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__); - - ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__); - goto EXIT; - } - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - /* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any - * modifications since currently not defined what the 'nUsage' is for. - */ - pANBParams->nUsage |= 0; - } - break; - - default: - { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); - ret = OMX_ErrorUnsupportedIndex; - goto EXIT; - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_SetANBParameter( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_COMPONENTTYPE *pOMXComponent = NULL; - SEC_OMX_BASECOMPONENT *pSECComponent = NULL; - SEC_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; - - FunctionIn(); - - if (hComponent == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; - ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); - if (ret != OMX_ErrorNone) { - goto EXIT; - } - - if (pOMXComponent->pComponentPrivate == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; - if (pSECComponent->currentState == OMX_StateInvalid ) { - ret = OMX_ErrorInvalidState; - goto EXIT; - } - - if (ComponentParameterStructure == NULL) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - pVideoDec = (SEC_OMX_VIDEODEC_COMPONENT *)pSECComponent->hComponentHandle; - - switch (nIndex) { - case OMX_IndexParamEnableAndroidBuffers: - { - EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure; - OMX_U32 portIndex = pANBParams->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__); - - ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__); - goto EXIT; - } - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort->bIsANBEnabled = pANBParams->enable; - } - break; - - case OMX_IndexParamUseAndroidNativeBuffer: - { - UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure; - OMX_U32 portIndex = pANBParams->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - android_native_buffer_t *pANB; - OMX_U32 nSizeBytes; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex); - - ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__); - goto EXIT; - } - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - if (pSECPort->portState != OMX_StateIdle) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Port state should be IDLE", __func__); - ret = OMX_ErrorIncorrectStateOperation; - goto EXIT; - } - - pANB = pANBParams->nativeBuffer.get(); - - /* MALI alignment restriction */ - nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16); - nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2; - - ret = useAndroidNativeBuffer(pSECPort, - pANBParams->bufferHeader, - pANBParams->nPortIndex, - pANBParams->pAppPrivate, - nSizeBytes, - (OMX_U8 *) pANB); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: useAndroidNativeBuffer is failed", __func__); - goto EXIT; - } - } - break; - - case OMX_IndexParamStoreMetaDataBuffer: - { - StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure; - OMX_U32 portIndex = pANBParams->nPortIndex; - SEC_OMX_BASEPORT *pSECPort = NULL; - - SEC_OSAL_Log(SEC_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__); - - ret = SEC_OMX_Check_SizeVersion(pANBParams, sizeof(StoreMetaDataInBuffersParams)); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__); - goto EXIT; - } - - if (portIndex >= pSECComponent->portParam.nPorts) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort = &pSECComponent->pSECPort[portIndex]; - if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { - ret = OMX_ErrorBadPortIndex; - goto EXIT; - } - - pSECPort->bStoreMetaData = pANBParams->bStoreMetaData; - } - break; - - default: - { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); - ret = OMX_ErrorUnsupportedIndex; - goto EXIT; - } - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_GetInfoFromMetaData(OMX_IN SEC_OMX_DATA *pBuffer, - OMX_OUT OMX_PTR *ppBuf) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - MetadataBufferType type; - buffer_handle_t pBufHandle; - - FunctionIn(); - -/* - * meta data contains the following data format. - * payload depends on the MetadataBufferType - * -------------------------------------------------------------- - * | MetadataBufferType | payload | - * -------------------------------------------------------------- - * - * If MetadataBufferType is kMetadataBufferTypeCameraSource, then - * -------------------------------------------------------------- - * | kMetadataBufferTypeCameraSource | physical addr. of Y |physical addr. of CbCr | - * -------------------------------------------------------------- - * - * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then - * -------------------------------------------------------------- - * | kMetadataBufferTypeGrallocSource | buffer_handle_t | - * -------------------------------------------------------------- - */ - - /* MetadataBufferType */ - memcpy(&type, (MetadataBufferType *)(pBuffer->dataBuffer), sizeof(type)); - - if (type == kMetadataBufferTypeCameraSource) { - /* physical addr. of Y */ - ppBuf[0] = (OMX_PTR)(pBuffer->dataBuffer + sizeof(type)); - /* physical addr. of CbCr */ - ppBuf[1] = (OMX_PTR)(pBuffer->dataBuffer + sizeof(type) + sizeof(pBuffer->dataBuffer)); - } else if (type == kMetadataBufferTypeGrallocSource) { - /* buffer_handle_t */ - memcpy(&pBufHandle, pBuffer->dataBuffer + sizeof(type), sizeof(buffer_handle_t)); - ppBuf[0] = (OMX_PTR)pBufHandle; - } - -EXIT: - FunctionOut(); - - return ret; -} - -#ifdef __cplusplus -} -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.h deleted file mode 100644 index 67029f5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Android.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Android.h - * @brief - * @author Seungbeom Kim (sbcrux.kim@samsung.com) - * @author Hyeyeon Chung (hyeon.chung@samsung.com) - * @author Yunji Kim (yunji.kim@samsung.com) - * @author Jinsung Yang (jsgood.yang@samsung.com) - * @version 1.1.0 - * @history - * 2011.7.15 : Create - */ - -#ifndef SEC_OSAL_ANDROID -#define SEC_OSAL_ANDROID - -#include "OMX_Types.h" -#include "OMX_Core.h" -#include "OMX_Index.h" - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OSAL_GetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR ComponentParameterStructure); - -OMX_ERRORTYPE SEC_OSAL_SetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR ComponentParameterStructure); - -OMX_ERRORTYPE SEC_OSAL_LockANB(OMX_IN OMX_PTR pBuffer, - OMX_IN OMX_U32 width, - OMX_IN OMX_U32 height, - OMX_IN OMX_COLOR_FORMATTYPE format, - OMX_OUT OMX_U32 *pStride, - OMX_OUT OMX_PTR *vaddr); - -OMX_ERRORTYPE SEC_OSAL_GetPhysANB(OMX_IN OMX_PTR pBuffer, - OMX_OUT OMX_PTR *paddr); - -OMX_ERRORTYPE SEC_OSAL_UnlockANB(OMX_IN OMX_PTR pBuffer); - -OMX_ERRORTYPE SEC_OSAL_LockANBHandle(OMX_IN OMX_U32 pBuffer, - OMX_IN OMX_U32 width, - OMX_IN OMX_U32 height, - OMX_IN OMX_COLOR_FORMATTYPE format, - OMX_OUT OMX_PTR *vaddr); - -OMX_ERRORTYPE SEC_OSAL_UnlockANBHandle(OMX_IN OMX_U32 pBuffer); - -OMX_ERRORTYPE SEC_OSAL_GetPhysANBHandle(OMX_IN OMX_U32 pBuffer, - OMX_OUT OMX_PTR *paddr); - -OMX_ERRORTYPE SEC_OSAL_GetInfoFromMetaData(OMX_IN SEC_OMX_DATA *pBuffer, - OMX_OUT OMX_PTR *pOutBuffer); - -OMX_ERRORTYPE SEC_OSAL_CheckANB(OMX_IN SEC_OMX_DATA *pBuffer, - OMX_OUT OMX_BOOL *bIsANBEnabled); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.c deleted file mode 100644 index 2082368..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_ETC.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_ETC.h" -#include "SEC_OSAL_Log.h" - -static struct timeval perfStart[PERF_ID_MAX+1], perfStop[PERF_ID_MAX+1]; -static unsigned long perfTime[PERF_ID_MAX+1], totalPerfTime[PERF_ID_MAX+1]; -static unsigned int perfFrameCount[PERF_ID_MAX+1], perfOver30ms[PERF_ID_MAX+1]; - -#ifndef HAVE_GETLINE -ssize_t getline(char **ppLine, size_t *pLen, FILE *pStream) -{ - char *pCurrentPointer = NULL; - size_t const chunk = 512; - - size_t defaultBufferSize = chunk + 1; - size_t retSize = 0; - - if (*ppLine == NULL) { - *ppLine = (char *)malloc(defaultBufferSize); - if (*ppLine == NULL) { - retSize = -1; - goto EXIT; - } - *pLen = defaultBufferSize; - } - else { - if (*pLen < defaultBufferSize) { - *ppLine = (char *)realloc(*ppLine, defaultBufferSize); - if (*ppLine == NULL) { - retSize = -1; - goto EXIT; - } - *pLen = defaultBufferSize; - } - } - - while (1) { - size_t i; - size_t j = 0; - size_t readByte = 0; - - pCurrentPointer = *ppLine + readByte; - - i = fread(pCurrentPointer, 1, chunk, pStream); - if (i < chunk && ferror(pStream)) { - retSize = -1; - goto EXIT; - } - while (j < i) { - ++j; - if (*pCurrentPointer++ == (char)'\n') { - *pCurrentPointer = '\0'; - if (j != i) { - if (fseek(pStream, j - i, SEEK_CUR)) { - retSize = -1; - goto EXIT; - } - if (feof(pStream)) - clearerr(pStream); - } - readByte += j; - retSize = readByte; - goto EXIT; - } - } - - readByte += j; - if (feof(pStream)) { - if (readByte) { - retSize = readByte; - goto EXIT; - } - if (!i) { - retSize = -1; - goto EXIT; - } - } - - i = ((readByte + (chunk * 2)) / chunk) * chunk; - if (i != *pLen) { - *ppLine = (char *)realloc(*ppLine, i); - if (*ppLine == NULL) { - retSize = -1; - goto EXIT; - } - *pLen = i; - } - } - -EXIT: - return retSize; -} -#endif /* HAVE_GETLINE */ - -OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src) -{ - return strcpy(dest, src); -} - -OMX_PTR SEC_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num) -{ - return strncpy(dest, src, num); -} - -OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2) -{ - return strcmp(str1, str2); -} - -OMX_S32 SEC_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num) -{ - return strncmp(str1, str2, num); -} - -OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src) -{ - return strcat(dest, src); -} - -OMX_PTR SEC_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num) -{ - return strncat(dest, src, num); -} - -size_t SEC_OSAL_Strlen(const char *str) -{ - return strlen(str); -} - -static OMX_U32 MeasureTime(struct timeval *start, struct timeval *stop) -{ - unsigned long sec, usec, time; - - sec = stop->tv_sec - start->tv_sec; - if (stop->tv_usec >= start->tv_usec) { - usec = stop->tv_usec - start->tv_usec; - } else { - usec = stop->tv_usec + 1000000 - start->tv_usec; - sec--; - } - - time = sec * 1000000 + (usec); - - return time; -} - -void SEC_OSAL_PerfInit(PERF_ID_TYPE id) -{ - memset(&perfStart[id], 0, sizeof(perfStart[id])); - memset(&perfStop[id], 0, sizeof(perfStop[id])); - perfTime[id] = 0; - totalPerfTime[id] = 0; - perfFrameCount[id] = 0; - perfOver30ms[id] = 0; -} - -void SEC_OSAL_PerfStart(PERF_ID_TYPE id) -{ - gettimeofday(&perfStart[id], NULL); -} - -void SEC_OSAL_PerfStop(PERF_ID_TYPE id) -{ - gettimeofday(&perfStop[id], NULL); - - perfTime[id] = MeasureTime(&perfStart[id], &perfStop[id]); - totalPerfTime[id] += perfTime[id]; - perfFrameCount[id]++; - - if (perfTime[id] > 30000) - perfOver30ms[id]++; -} - -OMX_U32 SEC_OSAL_PerfFrame(PERF_ID_TYPE id) -{ - return perfTime[id]; -} - -OMX_U32 SEC_OSAL_PerfTotal(PERF_ID_TYPE id) -{ - return totalPerfTime[id]; -} - -OMX_U32 SEC_OSAL_PerfFrameCount(PERF_ID_TYPE id) -{ - return perfFrameCount[id]; -} - -int SEC_OSAL_PerfOver30ms(PERF_ID_TYPE id) -{ - return perfOver30ms[id]; -} - -void SEC_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id) -{ - OMX_U32 perfTotal; - int frameCount; - - frameCount = SEC_OSAL_PerfFrameCount(id); - perfTotal = SEC_OSAL_PerfTotal(id); - - SEC_OSAL_Log(SEC_LOG_INFO, "%s Frame Count: %d", prefix, frameCount); - SEC_OSAL_Log(SEC_LOG_INFO, "%s Avg Time: %.2f ms, Over 30ms: %d", - prefix, (float)perfTotal / (float)(frameCount * 1000), - SEC_OSAL_PerfOver30ms(id)); -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.h deleted file mode 100644 index 2275abb..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_ETC.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_ETC.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_ETC -#define SEC_OSAL_ETC - -#include "OMX_Types.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src); -OMX_S32 SEC_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num); -OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2); -OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src); -size_t SEC_OSAL_Strlen(const char *str); -ssize_t getline(char **ppLine, size_t *len, FILE *stream); - -/* perf */ -typedef enum _PERF_ID_TYPE { - PERF_ID_CSC = 0, - PERF_ID_DEC, - PERF_ID_ENC, - PERF_ID_USER, - PERF_ID_MAX, -} PERF_ID_TYPE; - -void SEC_OSAL_PerfInit(PERF_ID_TYPE id); -void SEC_OSAL_PerfStart(PERF_ID_TYPE id); -void SEC_OSAL_PerfStop(PERF_ID_TYPE id); -OMX_U32 SEC_OSAL_PerfFrame(PERF_ID_TYPE id); -OMX_U32 SEC_OSAL_PerfTotal(PERF_ID_TYPE id); -OMX_U32 SEC_OSAL_PerfFrameCount(PERF_ID_TYPE id); -int SEC_OSAL_PerfOver30ms(PERF_ID_TYPE id); -void SEC_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.c deleted file mode 100644 index 383b62c..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -/* - * @file SEC_OSAL_Event.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - - -#include -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_Event.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_OSAL_EVENT" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle) -{ - SEC_OSAL_THREADEVENT *event; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - event = (SEC_OSAL_THREADEVENT *)SEC_OSAL_Malloc(sizeof(SEC_OSAL_THREADEVENT)); - if (!event) { - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - SEC_OSAL_Memset(event, 0, sizeof(SEC_OSAL_THREADEVENT)); - event->signal = OMX_FALSE; - - ret = SEC_OSAL_MutexCreate(&event->mutex); - if (ret != OMX_ErrorNone) { - SEC_OSAL_Free(event); - goto EXIT; - } - - if (pthread_cond_init(&event->condition, NULL)) { - SEC_OSAL_MutexTerminate(event->mutex); - SEC_OSAL_Free(event); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - *eventHandle = (OMX_HANDLETYPE)event; - ret = OMX_ErrorNone; - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle) -{ - SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (!event) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - ret = SEC_OSAL_MutexLock(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - if (pthread_cond_destroy(&event->condition)) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - ret = SEC_OSAL_MutexUnlock(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - ret = SEC_OSAL_MutexTerminate(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - SEC_OSAL_Free(event); - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle) -{ - SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (!event) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - ret = SEC_OSAL_MutexLock(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - event->signal = OMX_FALSE; - - SEC_OSAL_MutexUnlock(event->mutex); - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle) -{ - SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (!event) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - ret = SEC_OSAL_MutexLock(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - event->signal = OMX_TRUE; - pthread_cond_signal(&event->condition); - - SEC_OSAL_MutexUnlock(event->mutex); - -EXIT: - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms) -{ - SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct timespec timeout; - struct timeval now; - int funcret = 0; - OMX_U32 tv_us; - - FunctionIn(); - - if (!event) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - gettimeofday(&now, NULL); - - tv_us = now.tv_usec + ms * 1000; - timeout.tv_sec = now.tv_sec + tv_us / 1000000; - timeout.tv_nsec = (tv_us % 1000000) * 1000; - - ret = SEC_OSAL_MutexLock(event->mutex); - if (ret != OMX_ErrorNone) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - - if (ms == 0) { - if (!event->signal) - ret = OMX_ErrorTimeout; - } else if (ms == DEF_MAX_WAIT_TIME) { - while (!event->signal) - pthread_cond_wait(&event->condition, (pthread_mutex_t *)(event->mutex)); - ret = OMX_ErrorNone; - } else { - while (!event->signal) { - funcret = pthread_cond_timedwait(&event->condition, (pthread_mutex_t *)(event->mutex), &timeout); - if ((!event->signal) && (funcret == ETIMEDOUT)) { - ret = OMX_ErrorTimeout; - break; - } - } - } - - SEC_OSAL_MutexUnlock(event->mutex); - -EXIT: - FunctionOut(); - - return ret; -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.h deleted file mode 100644 index 8ae2eb5..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Event.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Event.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_EVENT -#define SEC_OSAL_EVENT - -#include -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#define DEF_MAX_WAIT_TIME 0xFFFFFFFF - -typedef struct _SEC_OSAL_THREADEVENT -{ - OMX_BOOL signal; - OMX_HANDLETYPE mutex; - pthread_cond_t condition; -} SEC_OSAL_THREADEVENT; - - -#ifdef __cplusplus -extern "C" { -#endif - - -OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle); -OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle); -OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle); -OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle); -OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.c deleted file mode 100644 index f400794..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Library.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - - -#include -#include -#include -#include - -#include "SEC_OSAL_Library.h" - - -void *SEC_OSAL_dlopen(const char *filename, int flag) -{ - return dlopen(filename, flag); -} - -void *SEC_OSAL_dlsym(void *handle, const char *symbol) -{ - return dlsym(handle, symbol); -} - -int SEC_OSAL_dlclose(void *handle) -{ - return dlclose(handle); -} - -const char *SEC_OSAL_dlerror(void) -{ - return dlerror(); -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.h deleted file mode 100644 index 27ac42e..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Library.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Library.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_LIBRARY -#define SEC_OSAL_LIBRARY - -#include "OMX_Types.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -void *SEC_OSAL_dlopen(const char *filename, int flag); -void *SEC_OSAL_dlsym(void *handle, const char *symbol); -int SEC_OSAL_dlclose(void *handle); -const char *SEC_OSAL_dlerror(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.c deleted file mode 100644 index 0aa956a..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Log.c - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include - -#include "SEC_OSAL_Log.h" - - -void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) -{ - va_list argptr; - - va_start(argptr, msg); - - switch (logLevel) { - case SEC_LOG_TRACE: - __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); - break; - case SEC_LOG_INFO: - __android_log_vprint(ANDROID_LOG_INFO, tag, msg, argptr); - break; - case SEC_LOG_WARNING: - __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); - break; - case SEC_LOG_ERROR: - __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr); - break; - default: - __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr); - } - - va_end(argptr); -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.h deleted file mode 100644 index d4f2617..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Log.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Log.h - * @brief - * @author Yunji Kim (yunji.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - * 2010.8.27 : Add trace function - */ - -#ifndef SEC_OSAL_LOG -#define SEC_OSAL_LOG - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef SEC_LOG_OFF -#define SEC_LOG -#endif - -#ifndef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_LOG" -#endif - -#ifdef SEC_TRACE_ON -#define SEC_TRACE -#endif - -typedef enum _LOG_LEVEL -{ - SEC_LOG_TRACE, - SEC_LOG_INFO, - SEC_LOG_WARNING, - SEC_LOG_ERROR -} SEC_LOG_LEVEL; - -#ifdef SEC_LOG -#define SEC_OSAL_Log(a, ...) ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)) -#else -#define SEC_OSAL_Log(a, ...) \ - do { \ - if (a == SEC_LOG_ERROR) \ - ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)); \ - } while (0) -#endif - -#ifdef SEC_TRACE -#define FunctionIn() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) -#define FunctionOut() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) -#else -#define FunctionIn() ((void *)0) -#define FunctionOut() ((void *)0) -#endif - -extern void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.c deleted file mode 100644 index bf5224d..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Memory.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include - -#include "SEC_OSAL_Memory.h" - -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -static int mem_cnt = 0; - -OMX_PTR SEC_OSAL_Malloc(OMX_U32 size) -{ - mem_cnt++; - SEC_OSAL_Log(SEC_LOG_TRACE, "alloc count: %d", mem_cnt); - - return (OMX_PTR)malloc(size); -} - -void SEC_OSAL_Free(OMX_PTR addr) -{ - mem_cnt--; - SEC_OSAL_Log(SEC_LOG_TRACE, "free count: %d", mem_cnt); - - if (addr) - free(addr); - - return; -} - -OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n) -{ - return memset(dest, c, n); -} - -OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n) -{ - return memcpy(dest, src, n); -} - -OMX_PTR SEC_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n) -{ - return memmove(dest, src, n); -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.h deleted file mode 100644 index fed5cac..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Memory.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Memory.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_MEMORY -#define SEC_OSAL_MEMORY - -#include "OMX_Types.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_PTR SEC_OSAL_Malloc(OMX_U32 size); -void SEC_OSAL_Free(OMX_PTR addr); -OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n); -OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n); -OMX_PTR SEC_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.c deleted file mode 100644 index b8f7b79..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Mutex.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Mutex.h" - - -OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle) -{ - pthread_mutex_t *mutex; - - mutex = (pthread_mutex_t *)SEC_OSAL_Malloc(sizeof(pthread_mutex_t)); - if (!mutex) - return OMX_ErrorInsufficientResources; - - if (pthread_mutex_init(mutex, NULL) != 0) { - SEC_OSAL_Free(mutex); - return OMX_ErrorUndefined; - } - - *mutexHandle = (OMX_HANDLETYPE)mutex; - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; - - if (mutex == NULL) - return OMX_ErrorBadParameter; - - if (pthread_mutex_destroy(mutex) != 0) - return OMX_ErrorUndefined; - - SEC_OSAL_Free(mutex); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; - int result; - - if (mutex == NULL) - return OMX_ErrorBadParameter; - - if (pthread_mutex_lock(mutex) != 0) - return OMX_ErrorUndefined; - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; - int result; - - if (mutex == NULL) - return OMX_ErrorBadParameter; - - if (pthread_mutex_unlock(mutex) != 0) - return OMX_ErrorUndefined; - - return OMX_ErrorNone; -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.h deleted file mode 100644 index 2dd63bc..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Mutex.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Mutex.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create -*/ - -#ifndef SEC_OSAL_MUTEX -#define SEC_OSAL_MUTEX - -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle); -OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle); -OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle); -OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.c deleted file mode 100644 index 4ecd8dc..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Queue.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - - -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Mutex.h" -#include "SEC_OSAL_Queue.h" - - -OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle) -{ - int i = 0; - SEC_QElem *newqelem = NULL; - SEC_QElem *currentqelem = NULL; - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (!queue) - return OMX_ErrorBadParameter; - - ret = SEC_OSAL_MutexCreate(&queue->qMutex); - if (ret != OMX_ErrorNone) - return ret; - - queue->first = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); - if (queue->first == NULL) - return OMX_ErrorInsufficientResources; - - SEC_OSAL_Memset(queue->first, 0, sizeof(SEC_QElem)); - currentqelem = queue->last = queue->first; - queue->numElem = 0; - - for (i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { - newqelem = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); - if (newqelem == NULL) { - while (queue->first != NULL) { - currentqelem = queue->first->qNext; - SEC_OSAL_Free((OMX_PTR)queue->first); - queue->first = currentqelem; - } - return OMX_ErrorInsufficientResources; - } else { - SEC_OSAL_Memset(newqelem, 0, sizeof(SEC_QElem)); - currentqelem->qNext = newqelem; - currentqelem = newqelem; - } - } - - currentqelem->qNext = queue->first; - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle) -{ - int i = 0; - SEC_QElem *currentqelem = NULL; - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (!queue) - return OMX_ErrorBadParameter; - - for ( i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { - currentqelem = queue->first->qNext; - SEC_OSAL_Free(queue->first); - queue->first = currentqelem; - } - - if(queue->first) { - SEC_OSAL_Free(queue->first); - queue->first = NULL; - } - - ret = SEC_OSAL_MutexTerminate(queue->qMutex); - - return ret; -} - -int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data) -{ - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - if (queue == NULL) - return -1; - - SEC_OSAL_MutexLock(queue->qMutex); - - if ((queue->last->data != NULL) || (queue->numElem >= MAX_QUEUE_ELEMENTS)) { - SEC_OSAL_MutexUnlock(queue->qMutex); - return -1; - } - queue->last->data = data; - queue->last = queue->last->qNext; - queue->numElem++; - - SEC_OSAL_MutexUnlock(queue->qMutex); - return 0; -} - -void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle) -{ - void *data = NULL; - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - if (queue == NULL) - return NULL; - - SEC_OSAL_MutexLock(queue->qMutex); - - if ((queue->first->data == NULL) || (queue->numElem <= 0)) { - SEC_OSAL_MutexUnlock(queue->qMutex); - return NULL; - } - data = queue->first->data; - queue->first->data = NULL; - queue->first = queue->first->qNext; - queue->numElem--; - - SEC_OSAL_MutexUnlock(queue->qMutex); - return data; -} - -int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle) -{ - int ElemNum = 0; - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - if (queue == NULL) - return -1; - - SEC_OSAL_MutexLock(queue->qMutex); - ElemNum = queue->numElem; - SEC_OSAL_MutexUnlock(queue->qMutex); - return ElemNum; -} - -int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum) -{ - SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; - if (queue == NULL) - return -1; - - SEC_OSAL_MutexLock(queue->qMutex); - queue->numElem = ElemNum; - SEC_OSAL_MutexUnlock(queue->qMutex); - return ElemNum; -} - diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.h deleted file mode 100644 index d1dee11..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Queue.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Queue.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_QUEUE -#define SEC_OSAL_QUEUE - -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#define MAX_QUEUE_ELEMENTS 10 - -typedef struct _SEC_QElem -{ - void *data; - struct _SEC_QElem *qNext; -} SEC_QElem; - -typedef struct _SEC_QUEUE -{ - SEC_QElem *first; - SEC_QElem *last; - int numElem; - OMX_HANDLETYPE qMutex; -} SEC_QUEUE; - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle); -OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle); -int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data); -void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle); -int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle); -int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.c deleted file mode 100644 index be9b9cb..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Semaphore.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Semaphore.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_LOG_SEMA" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle) -{ - sem_t *sema; - - sema = (sem_t *)SEC_OSAL_Malloc(sizeof(sem_t)); - if (!sema) - return OMX_ErrorInsufficientResources; - - if (sem_init(sema, 0, 0) != 0) { - SEC_OSAL_Free(sema); - return OMX_ErrorUndefined; - } - - *semaphoreHandle = (OMX_HANDLETYPE)sema; - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle) -{ - sem_t *sema = (sem_t *)semaphoreHandle; - - if (sema == NULL) - return OMX_ErrorBadParameter; - - if (sem_destroy(sema) != 0) - return OMX_ErrorUndefined; - - SEC_OSAL_Free(sema); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle) -{ - sem_t *sema = (sem_t *)semaphoreHandle; - - FunctionIn(); - - if (sema == NULL) - return OMX_ErrorBadParameter; - - if (sem_wait(sema) != 0) - return OMX_ErrorUndefined; - - FunctionOut(); - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle) -{ - sem_t *sema = (sem_t *)semaphoreHandle; - - FunctionIn(); - - if (sema == NULL) - return OMX_ErrorBadParameter; - - if (sem_post(sema) != 0) - return OMX_ErrorUndefined; - - FunctionOut(); - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val) -{ - sem_t *sema = (sem_t *)semaphoreHandle; - - if (sema == NULL) - return OMX_ErrorBadParameter; - - if (sem_init(sema, 0, val) != 0) - return OMX_ErrorUndefined; - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val) -{ - sem_t *sema = (sem_t *)semaphoreHandle; - int semaVal = 0; - - if (sema == NULL) - return OMX_ErrorBadParameter; - - if (sem_getvalue(sema, &semaVal) != 0) - return OMX_ErrorUndefined; - - *val = (OMX_S32)semaVal; - - return OMX_ErrorNone; -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.h deleted file mode 100644 index 431cba4..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Semaphore.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Semaphore.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_SEMAPHORE -#define SEC_OSAL_SEMAPHORE - -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle); -OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle); -OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle); -OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle); -OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val); -OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.c b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.c deleted file mode 100644 index 730b4a9..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Thread.c - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SEC_OSAL_Memory.h" -#include "SEC_OSAL_Thread.h" - -#undef SEC_LOG_TAG -#define SEC_LOG_TAG "SEC_LOG_THREAD" -#define SEC_LOG_OFF -#include "SEC_OSAL_Log.h" - - -typedef struct _SEC_THREAD_HANDLE_TYPE -{ - pthread_t pthread; - pthread_attr_t attr; - struct sched_param schedparam; - int stack_size; -} SEC_THREAD_HANDLE_TYPE; - - -OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument) -{ - FunctionIn(); - - int result = 0; - int detach_ret = 0; - SEC_THREAD_HANDLE_TYPE *thread; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - thread = SEC_OSAL_Malloc(sizeof(SEC_THREAD_HANDLE_TYPE)); - SEC_OSAL_Memset(thread, 0, sizeof(SEC_THREAD_HANDLE_TYPE)); - - pthread_attr_init(&thread->attr); - if (thread->stack_size != 0) - pthread_attr_setstacksize(&thread->attr, thread->stack_size); - - /* set priority */ - if (thread->schedparam.sched_priority != 0) - pthread_attr_setschedparam(&thread->attr, &thread->schedparam); - - detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE); - if (detach_ret != 0) { - SEC_OSAL_Free(thread); - *threadHandle = NULL; - ret = OMX_ErrorUndefined; - goto EXIT; - } - - result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument); - /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */ - - switch (result) { - case 0: - *threadHandle = (OMX_HANDLETYPE)thread; - ret = OMX_ErrorNone; - break; - case EAGAIN: - SEC_OSAL_Free(thread); - *threadHandle = NULL; - ret = OMX_ErrorInsufficientResources; - break; - default: - SEC_OSAL_Free(thread); - *threadHandle = NULL; - ret = OMX_ErrorUndefined; - break; - } - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle) -{ - FunctionIn(); - - OMX_ERRORTYPE ret = OMX_ErrorNone; - SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; - - if (!thread) { - ret = OMX_ErrorBadParameter; - goto EXIT; - } - if (pthread_join(thread->pthread, NULL) != 0) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - SEC_OSAL_Free(thread); - ret = OMX_ErrorNone; - -EXIT: - FunctionOut(); - - return ret; -} - -OMX_ERRORTYPE SEC_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle) -{ - SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; - - if (!thread) - return OMX_ErrorBadParameter; - - /* thread_cancel(thread->pthread); */ - pthread_exit(&thread->pthread); - pthread_join(thread->pthread, NULL); - - SEC_OSAL_Free(thread); - return OMX_ErrorNone; -} - -void SEC_OSAL_ThreadExit(void *value_ptr) -{ - pthread_exit(value_ptr); - return; -} - -void SEC_OSAL_SleepMillisec(OMX_U32 ms) -{ - usleep(ms * 1000); - return; -} diff --git a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.h b/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.h deleted file mode 100644 index ce1262d..0000000 --- a/exynos4/multimedia/openmax/sec_omx/osal/SEC_OSAL_Thread.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2010 Samsung Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file SEC_OSAL_Thread.h - * @brief - * @author SeungBeom Kim (sbcrux.kim@samsung.com) - * @version 1.1.0 - * @history - * 2010.7.15 : Create - */ - -#ifndef SEC_OSAL_THREAD -#define SEC_OSAL_THREAD - -#include "OMX_Types.h" -#include "OMX_Core.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument); -OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle); -OMX_ERRORTYPE SEC_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle); -void SEC_OSAL_ThreadExit(void *value_ptr); -void SEC_OSAL_SleepMillisec(OMX_U32 ms); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exynos4210.mk b/exynos4210.mk new file mode 100644 index 0000000..527891e --- /dev/null +++ b/exynos4210.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +ifeq ($(TARGET_SOC),exynos4210) + +include $(TARGET_HAL_PATH)/Android.mk +include hardware/samsung/exynos/multimedia/Android.mk +include hardware/samsung/exynos4/exynos4210/Android.mk + +endif +endif diff --git a/exynos4x12.mk b/exynos4x12.mk new file mode 100644 index 0000000..29cc4d5 --- /dev/null +++ b/exynos4x12.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +ifeq ($(TARGET_SOC),exynos4x12) + +include $(TARGET_HAL_PATH)/Android.mk +include hardware/samsung/exynos/multimedia/Android.mk + +endif +endif diff --git a/exynos5/hal/Android.mk b/exynos5/hal/Android.mk new file mode 100644 index 0000000..6fe94d2 --- /dev/null +++ b/exynos5/hal/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ifeq ($(TARGET_BOARD_PLATFORM),exynos5) +common_exynos5_dirs := libgralloc_ump libhdmi libhwcomposer libfimg4x libcamera +exynos5250_dirs := $(common_exynos5_dirs) + +ifeq ($(BOARD_USES_HWJPEG),true) +exynos5250_dirs += libhwjpeg +endif + +ifeq ($(TARGET_SOC),exynos5250) + include $(call all-named-subdir-makefiles,$(exynos5250_dirs)) +endif +endif diff --git a/exynos5/hal/include/Exif.h b/exynos5/hal/include/Exif.h new file mode 100644 index 0000000..71e2241 --- /dev/null +++ b/exynos5/hal/include/Exif.h @@ -0,0 +1,231 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ANDROID_HARDWARE_EXIF_H +#define ANDROID_HARDWARE_EXIF_H + +#include + +#define EXIF_LOG2(x) (log((double)(x)) / log(2.0)) +#define APEX_FNUM_TO_APERTURE(x) ((int)(EXIF_LOG2((double)(x)) * 2 + 0.5)) +#define APEX_EXPOSURE_TO_SHUTTER(x) ((x) >= 1 ? \ + (int)(-(EXIF_LOG2((double)(x)) + 0.5)) : \ + (int)(-(EXIF_LOG2((double)(x)) - 0.5))) +#define APEX_ISO_TO_FILMSENSITIVITY(x) ((int)(EXIF_LOG2((x) / 3.125) + 0.5)) + +#define NUM_SIZE 2 +#define IFD_SIZE 12 +#define OFFSET_SIZE 4 + +#define NUM_0TH_IFD_TIFF 10 +#define NUM_0TH_IFD_EXIF 22 +#define NUM_0TH_IFD_GPS 10 +#define NUM_1TH_IFD_TIFF 9 + +/* Type */ +#define EXIF_TYPE_BYTE 1 +#define EXIF_TYPE_ASCII 2 +#define EXIF_TYPE_SHORT 3 +#define EXIF_TYPE_LONG 4 +#define EXIF_TYPE_RATIONAL 5 +#define EXIF_TYPE_UNDEFINED 7 +#define EXIF_TYPE_SLONG 9 +#define EXIF_TYPE_SRATIONAL 10 + +#define EXIF_FILE_SIZE 28800 + +/* 0th IFD TIFF Tags */ +#define EXIF_TAG_IMAGE_WIDTH 0x0100 +#define EXIF_TAG_IMAGE_HEIGHT 0x0101 +#define EXIF_TAG_MAKE 0x010f +#define EXIF_TAG_MODEL 0x0110 +#define EXIF_TAG_ORIENTATION 0x0112 +#define EXIF_TAG_SOFTWARE 0x0131 +#define EXIF_TAG_DATE_TIME 0x0132 +#define EXIF_TAG_YCBCR_POSITIONING 0x0213 +#define EXIF_TAG_EXIF_IFD_POINTER 0x8769 +#define EXIF_TAG_GPS_IFD_POINTER 0x8825 + +/* 0th IFD Exif Private Tags */ +#define EXIF_TAG_EXPOSURE_TIME 0x829A +#define EXIF_TAG_FNUMBER 0x829D +#define EXIF_TAG_EXPOSURE_PROGRAM 0x8822 +#define EXIF_TAG_ISO_SPEED_RATING 0x8827 +#define EXIF_TAG_EXIF_VERSION 0x9000 +#define EXIF_TAG_DATE_TIME_ORG 0x9003 +#define EXIF_TAG_DATE_TIME_DIGITIZE 0x9004 +#define EXIF_TAG_SHUTTER_SPEED 0x9201 +#define EXIF_TAG_APERTURE 0x9202 +#define EXIF_TAG_BRIGHTNESS 0x9203 +#define EXIF_TAG_EXPOSURE_BIAS 0x9204 +#define EXIF_TAG_MAX_APERTURE 0x9205 +#define EXIF_TAG_METERING_MODE 0x9207 +#define EXIF_TAG_FLASH 0x9209 +#define EXIF_TAG_FOCAL_LENGTH 0x920A +#define EXIF_TAG_USER_COMMENT 0x9286 +#define EXIF_TAG_COLOR_SPACE 0xA001 +#define EXIF_TAG_PIXEL_X_DIMENSION 0xA002 +#define EXIF_TAG_PIXEL_Y_DIMENSION 0xA003 +#define EXIF_TAG_EXPOSURE_MODE 0xA402 +#define EXIF_TAG_WHITE_BALANCE 0xA403 +#define EXIF_TAG_SCENCE_CAPTURE_TYPE 0xA406 + +/* 0th IFD GPS Info Tags */ +#define EXIF_TAG_GPS_VERSION_ID 0x0000 +#define EXIF_TAG_GPS_LATITUDE_REF 0x0001 +#define EXIF_TAG_GPS_LATITUDE 0x0002 +#define EXIF_TAG_GPS_LONGITUDE_REF 0x0003 +#define EXIF_TAG_GPS_LONGITUDE 0x0004 +#define EXIF_TAG_GPS_ALTITUDE_REF 0x0005 +#define EXIF_TAG_GPS_ALTITUDE 0x0006 +#define EXIF_TAG_GPS_TIMESTAMP 0x0007 +#define EXIF_TAG_GPS_PROCESSING_METHOD 0x001B +#define EXIF_TAG_GPS_DATESTAMP 0x001D + +/* 1th IFD TIFF Tags */ +#define EXIF_TAG_COMPRESSION_SCHEME 0x0103 +#define EXIF_TAG_X_RESOLUTION 0x011A +#define EXIF_TAG_Y_RESOLUTION 0x011B +#define EXIF_TAG_RESOLUTION_UNIT 0x0128 +#define EXIF_TAG_JPEG_INTERCHANGE_FORMAT 0x0201 +#define EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN 0x0202 + +typedef enum { + EXIF_ORIENTATION_UP = 1, + EXIF_ORIENTATION_90 = 6, + EXIF_ORIENTATION_180 = 3, + EXIF_ORIENTATION_270 = 8, +} ExifOrientationType; + +typedef enum { + EXIF_SCENE_STANDARD, + EXIF_SCENE_LANDSCAPE, + EXIF_SCENE_PORTRAIT, + EXIF_SCENE_NIGHT, +} CamExifSceneCaptureType; + +typedef enum { + EXIF_METERING_UNKNOWN, + EXIF_METERING_AVERAGE, + EXIF_METERING_CENTER, + EXIF_METERING_SPOT, + EXIF_METERING_MULTISPOT, + EXIF_METERING_PATTERN, + EXIF_METERING_PARTIAL, + EXIF_METERING_OTHER = 255, +} CamExifMeteringModeType; + +typedef enum { + EXIF_EXPOSURE_AUTO, + EXIF_EXPOSURE_MANUAL, + EXIF_EXPOSURE_AUTO_BRACKET, +} CamExifExposureModeType; + +typedef enum { + EXIF_WB_AUTO, + EXIF_WB_MANUAL, +} CamExifWhiteBalanceType; + +/* Values */ +#define EXIF_DEF_MAKER "SAMSUNG" +#define EXIF_DEF_MODEL "SAMSUNG" +#define EXIF_DEF_SOFTWARE "SAMSUNG" +#define EXIF_DEF_EXIF_VERSION "0220" +#define EXIF_DEF_USERCOMMENTS "User comments" + +#define EXIF_DEF_YCBCR_POSITIONING 1 /* centered */ +#define EXIF_DEF_FNUMBER_NUM 26 /* 2.6 */ +#define EXIF_DEF_FNUMBER_DEN 10 +#define EXIF_DEF_EXPOSURE_PROGRAM 3 /* aperture priority */ +#define EXIF_DEF_FOCAL_LEN_NUM 278 /* 2.78mm */ +#define EXIF_DEF_FOCAL_LEN_DEN 100 +#define EXIF_DEF_FLASH 0 /* O: off, 1: on*/ +#define EXIF_DEF_COLOR_SPACE 1 +#define EXIF_DEF_EXPOSURE_MODE EXIF_EXPOSURE_AUTO +#define EXIF_DEF_APEX_DEN 10 + +#define EXIF_DEF_COMPRESSION 6 +#define EXIF_DEF_RESOLUTION_NUM 72 +#define EXIF_DEF_RESOLUTION_DEN 1 +#define EXIF_DEF_RESOLUTION_UNIT 2 /* inches */ + +typedef struct { + uint32_t num; + uint32_t den; +} rational_t; + +typedef struct { + int32_t num; + int32_t den; +} srational_t; + +typedef struct { + bool enableGps; + bool enableThumb; + + unsigned char maker[32]; + unsigned char model[32]; + unsigned char software[32]; + unsigned char exif_version[4]; + unsigned char date_time[20]; + unsigned char user_comment[150]; + + uint32_t width; + uint32_t height; + uint32_t widthThumb; + uint32_t heightThumb; + + uint16_t orientation; + uint16_t ycbcr_positioning; + uint16_t exposure_program; + uint16_t iso_speed_rating; + uint16_t metering_mode; + uint16_t flash; + uint16_t color_space; + uint16_t exposure_mode; + uint16_t white_balance; + uint16_t scene_capture_type; + + rational_t exposure_time; + rational_t fnumber; + rational_t aperture; + rational_t max_aperture; + rational_t focal_length; + + srational_t shutter_speed; + srational_t brightness; + srational_t exposure_bias; + + unsigned char gps_latitude_ref[2]; + unsigned char gps_longitude_ref[2]; + + uint8_t gps_version_id[4]; + uint8_t gps_altitude_ref; + + rational_t gps_latitude[3]; + rational_t gps_longitude[3]; + rational_t gps_altitude; + rational_t gps_timestamp[3]; + unsigned char gps_datestamp[11]; + unsigned char gps_processing_method[100]; + + rational_t x_resolution; + rational_t y_resolution; + uint16_t resolution_unit; + uint16_t compression_scheme; +} exif_attribute_t; + +#endif /* ANDROID_HARDWARE_EXIF_H */ diff --git a/exynos5/hal/include/SecBuffer.h b/exynos5/hal/include/SecBuffer.h new file mode 100644 index 0000000..b8a41df --- /dev/null +++ b/exynos5/hal/include/SecBuffer.h @@ -0,0 +1,158 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/*! + * \file SecBuffer.h + * \brief header file for SecBuffer + * \author Sangwoo, Park(sw5771.park@samsung.com) + * \date 2011/06/02 + * + * Revision History: + * - 2010/06/03 : Sangwoo, Park(sw5771.park@samsung.com) \n + * Initial version + * + */ + +/** + * @page SecBuffer + * + * @section Introduction + * SecBuffer is common struct for buffer + * + * @section Copyright + * Copyright (c) 2008-2011 Samsung Electronics Co., Ltd.All rights reserved. \n + * Proprietary and Confidential + * + * @image html samsung.png + */ + +#ifndef __SEC_BUFFER_H__ +#define __SEC_BUFFER_H__ + +#include + +//! Buffer information +struct SecBuffer +{ +public: + //! Buffer type + enum BUFFER_TYPE + { + BUFFER_TYPE_BASE = 0, + BUFFER_TYPE_VIRT = 1, //!< virtual address + BUFFER_TYPE_PHYS = 1 << 1, //!< physical address + BUFFER_TYPE_RESERVED = 1 << 2, //!< reserved type + BUFFER_TYPE_MAX, + }; + + //! Buffer virtual address + union { + char *p; //! single address. + char *extP[3]; //! Y Cb Cr. + } virt; + + //! Buffer physical address + union { + unsigned int p; //! single address. + unsigned int extP[3]; //! Y Cb Cr. + } phys; + + //! Buffer reserved id + union { + unsigned int p; //! \n + unsigned int extP[3]; //! \n + } reserved; + + //! Buffer size + union { + unsigned int s; + unsigned int extS[3]; + } size; + + //! Constructor + SecBuffer() + { + for (int i = 0; i < 3; i++) { + virt. extP[i] = NULL; + phys. extP[i] = 0; + reserved.extP[i] = 0; + size. extS[i] = 0; + } + } + + //! Constructor + SecBuffer(const SecBuffer *other) + { + for (int i = 0; i < 3; i++) { + virt. extP[i] = other->virt.extP[i]; + phys. extP[i] = other->phys.extP[i]; + reserved.extP[i] = other->reserved.extP[i]; + size. extS[i] = other->size.extS[i]; + } + } + + //! Operator(=) override + SecBuffer& operator =(const SecBuffer &other) + { + for (int i = 0; i < 3; i++) { + virt. extP[i] = other.virt.extP[i]; + phys. extP[i] = other.phys.extP[i]; + reserved.extP[i] = other.reserved.extP[i]; + size. extS[i] = other.size.extS[i]; + } + return *this; + } + + //! Operator(==) override + bool operator ==(const SecBuffer &other) const + { + return ( virt. extP[0] == other.virt.extP[0] + && virt. extP[1] == other.virt.extP[1] + && virt. extP[2] == other.virt.extP[2] + && phys. extP[0] == other.phys.extP[0] + && phys. extP[1] == other.phys.extP[1] + && phys. extP[2] == other.phys.extP[2] + && reserved.extP[0] == other.reserved.extP[0] + && reserved.extP[1] == other.reserved.extP[1] + && reserved.extP[2] == other.reserved.extP[2] + && size. extS[0] == other.size.extS[0] + && size. extS[1] == other.size.extS[1] + && size. extS[2] == other.size.extS[2]); + } + + //! Operator(!=) override + bool operator !=(const SecBuffer &other) const + { + // use operator(==) + return !(*this == other); + } + + //! Get Buffer type + static int BUFFER_TYPE(SecBuffer *buf) + { + int type = BUFFER_TYPE_BASE; + if (buf->virt.p) + type |= BUFFER_TYPE_VIRT; + if (buf->phys.p) + type |= BUFFER_TYPE_PHYS; + if (buf->reserved.p) + type |= BUFFER_TYPE_RESERVED; + + return type; + } +}; + +#endif //__SEC_BUFFER_H__ diff --git a/exynos5/hal/include/SecFimc.h b/exynos5/hal/include/SecFimc.h new file mode 100644 index 0000000..c7f9945 --- /dev/null +++ b/exynos5/hal/include/SecFimc.h @@ -0,0 +1,186 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + * \file SecFimc.h + * \brief header file for Fimc HAL MODULE + * \author Hyunkyung, Kim(hk310.kim@samsung.com) + * \date 2010/10/13 + * + * Revision History: + * - 2010/10/13 : Hyunkyung, Kim(hk310.kim@samsung.com) \n + * Initial version + * + * - 2011/11/15 : Sunmi, Lee(carrotsm.lee@samsung.com) \n + * Adjust V4L2 architecture \n + */ + +#ifndef __SEC_FIMC_H__ +#define __SEC_FIMC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "utils/Timers.h" + +#include "s5p_fimc_v4l2.h" +#include "sec_utils_v4l2.h" +#include "sec_format.h" + +#include "SecBuffer.h" +#include "SecRect.h" + +#define PFX_NODE_FIMC "/dev/video" +#define MAX_DST_BUFFERS (3) +#define MAX_SRC_BUFFERS (1) +#define MAX_PLANES (3) + +#ifdef __cplusplus +} + +class SecFimc +{ +public: + enum DEV { + DEV_0 = 0, + DEV_1, + DEV_2, + DEV_3, + DEV_MAX, + }; + + enum MODE { + MODE_NONE = 0, + MODE_SINGLE_BUF, + MODE_MULTI_BUF, + MODE_DMA_AUTO, + MODE_MAX, + }; + +private: + bool mFlagCreate; + int mDev; + int mFimcMode; + int mNumOfBuf; + + int mRealDev; + int mFd; + int mHwVersion; + int mBufIndex; + int mRotVal; + bool mFlagGlobalAlpha; + int mGlobalAlpha; + bool mFlagLocalAlpha; + bool mFlagColorKey; + int mColorKey; + bool mFlagSetSrcParam; + bool mFlagSetDstParam; + bool mFlagStreamOn; + + s5p_fimc_t mS5pFimc; + struct v4l2_capability mFimcCap; + + SecBuffer mSrcBuffer; + SecBuffer mDstBuffer[MAX_DST_BUFFERS]; + +public: + SecFimc(); + virtual ~SecFimc(); + + bool create(enum DEV dev, enum MODE mode, int numOfBuf); + bool destroy(void); + bool flagCreate(void); + + int getFd(void); + + SecBuffer * getMemAddr(int index = 0); + + int getHWVersion(void); + + bool setSrcParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = true); + + bool getSrcParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *colorFormat); + + bool setSrcAddr(unsigned int physYAddr, + unsigned int physCbAddr = 0, + unsigned int physCrAddr = 0, + int colorFormat = 0); + + bool setDstParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = true); + + bool getDstParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *colorFormat); + + bool setDstAddr(unsigned int physYAddr, unsigned int physCbAddr = 0, unsigned int physCrAddr = 0, int buf_index = 0); + + bool setRotVal(unsigned int rotVal); + bool setGlobalAlpha(bool enable = true, int alpha = 0xff); + bool setLocalAlpha(bool enable); + bool setColorKey(bool enable = true, int colorKey = 0xff); + + bool draw(int src_index, int dst_index); + +private: + bool m_streamOn(void); + bool m_checkSrcSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = false); + + bool m_checkDstSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + int rotVal, + bool forceChange = false); + int m_widthOfFimc(int v4l2ColorFormat, int width); + int m_heightOfFimc(int v4l2ColorFormat, int height); + int m_getYuvBpp(unsigned int fmt); + int m_getYuvPlanes(unsigned int fmt); +}; +#endif + +#endif //__SEC_FIMC_H__ diff --git a/exynos5/hal/include/SecHdmi.h b/exynos5/hal/include/SecHdmi.h new file mode 100644 index 0000000..1811c73 --- /dev/null +++ b/exynos5/hal/include/SecHdmi.h @@ -0,0 +1,250 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +** +** @author Sangwoo, Park(sw5771.park@samsung.com) +** @date 2010-09-10 +** +*/ + +#ifndef __SEC_HDMI_H__ +#define __SEC_HDMI_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s5p_tvout_v4l2.h" +#include "v4l2-mediabus.h" + +#if defined(BOARD_USES_HDMI_FIMGAPI) +#include "sec_g2d.h" +#include "FimgApi.h" +#endif + +#include "s3c_lcd.h" +#include "SecBuffer.h" + +#include "../libhdmi/libsForhdmi/libedid/libedid.h" +#include "../libhdmi/libsForhdmi/libcec/libcec.h" + +#include "../libhdmi/SecHdmi/SecHdmiCommon.h" +#include "../libhdmi/SecHdmi/SecHdmiV4L2Utils.h" +#include "../libhdmi/SecHdmi/SecGscaler.h" + + +#include +#include + +namespace android { + +class SecHdmi: virtual public RefBase +{ +public : + enum HDMI_LAYER { + HDMI_LAYER_BASE = 0, + HDMI_LAYER_VIDEO, + HDMI_LAYER_GRAPHIC_0, + HDMI_LAYER_GRAPHIC_1, + HDMI_LAYER_MAX, + }; + +private : + class CECThread: public Thread + { + public: + bool mFlagRunning; + + private: + sp mSecHdmi; + Mutex mThreadLoopLock; + Mutex mThreadControlLock; + virtual bool threadLoop(); + enum CECDeviceType mDevtype; + int mLaddr; + int mPaddr; + + public: + CECThread(sp secHdmi) + :Thread(false), + mFlagRunning(false), + mSecHdmi(secHdmi), + mDevtype(CEC_DEVICE_PLAYER), + mLaddr(0), + mPaddr(0){ + }; + virtual ~CECThread(); + + bool start(); + bool stop(); + + }; + + Mutex mLock; + + sp mCECThread; + + bool mFlagCreate; + bool mFlagConnected; + bool mFlagLayerEnable[HDMI_LAYER_MAX]; + bool mFlagHdmiStart[HDMI_LAYER_MAX]; + + int mSrcWidth[HDMI_LAYER_MAX]; + int mSrcHeight[HDMI_LAYER_MAX]; + int mSrcColorFormat[HDMI_LAYER_MAX]; + int mHdmiResolutionWidth[HDMI_LAYER_MAX]; + int mHdmiResolutionHeight[HDMI_LAYER_MAX]; + int mPreviousNumofHwLayer[HDMI_LAYER_MAX]; + __u32 mPreviousHdmiPresetId; + int mHdmiDstWidth; + int mHdmiDstHeight; + + unsigned int mHdmiSrcYAddr; + unsigned int mHdmiSrcCbCrAddr; + + unsigned int mFBaddr; + unsigned int mFBsize; + int mFBionfd; + unsigned int mFBoffset; + + int mHdmiOutputMode; + unsigned int mHdmiResolutionValue; + v4l2_std_id mHdmiStdId; + __u32 mHdmiPresetId; + unsigned int mCompositeStd; + bool mHdcpMode; + int mAudioMode; + unsigned int mUIRotVal; + unsigned int mG2DUIRotVal; + + int mCurrentsrcW; + int mCurrentsrcH; + int mCurrentsrcColorFormat; + unsigned int mCurrentsrcYAddr; + unsigned int mCurrentsrcCbAddr; + int mCurrentdstX; + int mCurrentdstY; + int mCurrenthdmiLayer; + int mCurrentNumOfHWCLayer; + + int mCurrentHdmiOutputMode; + unsigned int mCurrentHdmiResolutionValue; + bool mCurrentHdcpMode; + int mCurrentAudioMode; + bool mHdmiInfoChange; + + bool mFlagGscalerStart; + int mGscalerDstColorFormat; + + int mVideodevFd[HDMI_LAYER_MAX]; + int mMediadevFd; + int mSubdevMixerFd; + + __u32 mMixerSubdevEntity; + + SecBuffer mSrcBuffer[HDMI_LAYER_MAX][MAX_BUFFERS_MIXER]; + int mSrcIndex[HDMI_LAYER_MAX]; + SecGscaler mSecGscaler; + + struct v4l2_rect mSrcRect; + struct media_link_desc mlink_desc; + + int mIonClient; + + unsigned int mHdmiResolutionValueList[14]; + int mHdmiSizeOfResolutionValueList; + + int mDefaultFBFd; + int mDisplayWidth; + int mDisplayHeight; + + bool mGscalerForceUpdate; + +public : + + SecHdmi(); + virtual ~SecHdmi(); + bool create(int width, int height); + bool destroy(void); + inline bool flagCreate(void) { return mFlagCreate; } + + bool connect(void); + bool disconnect(void); + + bool flagConnected(void); + + bool flush(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, unsigned int srcCrAddr, + int dstX, int dstY, + int hdmiLayer, + int num_of_hwc_layer); + + bool clear(int hdmiLayer); + + void clearGraphicLayer(int hdmiLayer); + bool enableGraphicLayer(int hdmiLayer); + bool disableGraphicLayer(int hdmiLayer); + + bool startHdmi(int hdmiLayer); + bool stopHdmi(int hdmiLayer); + + bool setHdmiOutputMode(int hdmiOutputMode, bool forceRun = false); + bool setHdmiResolution(unsigned int hdmiResolutionValue, bool forceRun = true); + bool setHdcpMode(bool hdcpMode, bool forceRun = false); + bool setUIRotation(unsigned int rotVal, unsigned int hwcLayer); + bool setDisplaySize(int width, int height); + void setDisplayInfo(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, + int dstX, int dstY, + int hdmiLayer, + int num_of_hwc_layer); +private: + bool m_setupLink(void); + bool m_openLayer(int layer); + bool m_closeLayer(int layer); + + bool m_reset(int w, int h, int dstX, int dstY, int colorFormat, int hdmiLayer, int num_of_hwc_layer); + bool m_streamOn(int hdmiLayer); + + bool m_run(int hdmiLayer); + bool m_startHdmi(int hdmiLayer); + bool m_stopHdmi(int hdmiLayer); + + bool m_setHdmiOutputMode(int hdmiOutputMode); + bool m_setHdmiResolution(unsigned int hdmiResolutionValue); + bool m_setCompositeResolution(unsigned int compositeStdId); + bool m_setHdcpMode(bool hdcpMode); + bool m_setAudioMode(int audioMode); + + int m_resolutionValueIndex(unsigned int ResolutionValue); + + bool m_flagHWConnected(void); + bool m_flush(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, unsigned int srcCrAddr, + int dstX, int dstY, + int hdmiLayer, + int nun_of_hwc_layer); +}; + +}; // namespace android + +#endif //__SEC_HDMI_H__ diff --git a/exynos5/hal/include/SecJpegCodecHal.h b/exynos5/hal/include/SecJpegCodecHal.h new file mode 100644 index 0000000..55db15d --- /dev/null +++ b/exynos5/hal/include/SecJpegCodecHal.h @@ -0,0 +1,217 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SEC_JPG_CODEC_HAL_H__ +#define __SEC_JPG_CODEC_HAL_H__ + +#include "videodev2.h" + +#define JPEG_DEC_NODE "/dev/video11" +#define JPEG_ENC_NODE "/dev/video12" + +#define JPEG_MAX_PLANE_CNT (3) +#define JPEG_BYTE_ALIGN (32) + +#define MAX_JPG_WIDTH 8192 +#define MAX_JPG_HEIGHT 8192 + +#define JPEG_CACHE_OFF (0) +#define JPEG_CACHE_ON (1) + +class SecJpegCodecHal { +public: + ; + SecJpegCodecHal(); + virtual ~SecJpegCodecHal(); + + enum ERROR_JPEG_HAL { + ERROR_JPEG_DEVICE_ALREADY_CREATE = -0x100, + ERROR_CANNOT_OPEN_JPEG_DEVICE, + ERROR_JPEG_DEVICE_ALREADY_CLOSED, + ERROR_JPEG_DEVICE_ALREADY_DESTROY, + ERROR_JPEG_DEVICE_NOT_CREATE_YET, + ERROR_INVALID_COLOR_FORMAT, + ERROR_INVALID_JPEG_FORMAT, + ERROR_INVALID_IMAGE_SIZE, + ERROR_JPEG_CONFIG_POINTER_NULL, + ERROR_INVALID_JPEG_CONFIG, + ERROR_IN_BUFFER_CREATE_FAIL, + ERROR_OUT_BUFFER_CREATE_FAIL, + ERROR_EXCUTE_FAIL, + ERROR_JPEG_SIZE_TOO_SMALL, + ERROR_CANNOT_CHANGE_CACHE_SETTING, + ERROR_SIZE_NOT_SET_YET, + ERROR_BUFFR_IS_NULL, + ERROR_BUFFER_TOO_SMALL, + ERROR_GET_SIZE_FAIL, + ERROR_REQBUF_FAIL, + ERROR_INVALID_V4l2_BUF_TYPE = -0x80, + ERROR_MMAP_FAILED, + ERROR_FAIL, + ERROR_NONE = 0 + }; + + enum MODE { + MODE_ENCODE = 0, + MODE_DECODE + }; + + struct BUFFER{ + int numOfPlanes; + char *addr[JPEG_MAX_PLANE_CNT]; + int size[JPEG_MAX_PLANE_CNT]; + }; + + struct BUF_INFO{ + int numOfPlanes; + enum v4l2_memory memory; + enum v4l2_buf_type buf_type; + int reserved[4]; + }; + + struct PIX_FMT{ + int in_fmt; + int out_fmt; + int reserved[4]; + }; + + struct CONFIG{ + int mode; + int enc_qual; + + int width; + int height; + int scaled_width; + int scaled_height; + + int numOfPlanes; + + int sizeJpeg; + + union { + PIX_FMT enc_fmt; + PIX_FMT dec_fmt; + } pix; + + int reserved[8]; + }; + +protected: + // variables + bool t_bFlagCreate; + bool t_bFlagCreateInBuf; + bool t_bFlagCreateOutBuf; + bool t_bFlagExcute; + + int t_iPlaneNum; + + int t_iJpegFd; + struct CONFIG t_stJpegConfig; + struct BUFFER t_stJpegInbuf; + struct BUFFER t_stJpegOutbuf; + + //functions + int t_v4l2Querycap(int iFd); + int t_v4l2SetJpegcomp(int iFd, int iQuality); + int t_v4l2SetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig); + int t_v4l2GetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig); + int t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo); + int t_v4l2Querybuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf); + int t_v4l2Qbuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf); + int t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory); + int t_v4l2StreamOn(int iFd, enum v4l2_buf_type eType); + int t_v4l2StreamOff(int iFd, enum v4l2_buf_type eType); + int t_v4l2SetCtrl(int iFd, int iCid, int iValue); + int t_v4l2GetCtrl(int iFd, int iCid); +}; + +class SecJpegEncoderHal : SecJpegCodecHal { +public: + ; + SecJpegEncoderHal(); + virtual ~SecJpegEncoderHal(); + + enum QUALITY { + QUALITY_LEVEL_1 = 0, /* high */ + QUALITY_LEVEL_2, + QUALITY_LEVEL_3, + QUALITY_LEVEL_4, /* low */ + }; + + int create(void); + int destroy(void); + + int setSize(int iW, int iH); + + int setJpegConfig(void* pConfig); + void *getJpegConfig(void); + + + char **getInBuf(int *piInputSize); + char *getOutBuf(int *piOutputSize); + + int setCache(int iValue); + + int setInBuf(char **pcBuf, int *iSize); + int setOutBuf(char *pcBuf, int iSize); + + int getSize(int *piWidth, int *piHeight); + int setColorFormat(int iV4l2ColorFormat); + int setJpegFormat(int iV4l2JpegFormat); + int updateConfig(void); + + int setQuality(int iQuality); + int getJpegSize(void); + + int encode(void); +}; + +class SecJpegDecoderHal : SecJpegCodecHal { +public: + ; + SecJpegDecoderHal(); + virtual ~SecJpegDecoderHal(); + + int create(void); + int destroy(void); + + int setSize(int iW, int iH); + + int setJpegConfig(void* pConfig); + void *getJpegConfig(void); + + + char *getInBuf(int *piInputSize); + char **getOutBuf(int *piOutputSize); + + int setCache(int iValue); + + int setInBuf(char *pcBuf, int iSize); + int setOutBuf(char **pcBuf, int *iSize); + + int getSize(int *piWidth, int *piHeight); + int setColorFormat(int iV4l2ColorFormat); + int setJpegFormat(int iV4l2JpegFormat); + int updateConfig(void); + + int setScaledSize(int iW, int iH); + int setJpegSize(int iJpegSize); + + int decode(void); +}; + +#endif /* __SEC_JPG_CODEC_HAL_H__ */ diff --git a/exynos5/hal/include/SecJpegEncoder.h b/exynos5/hal/include/SecJpegEncoder.h new file mode 100644 index 0000000..c7390f9 --- /dev/null +++ b/exynos5/hal/include/SecJpegEncoder.h @@ -0,0 +1,157 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SEC_JPG_ENC_H__ +#define __SEC_JPG_ENC_H__ + +#include "Exif.h" + +#include "SecJpegCodecHal.h" + +#include +#include "ion.h" + +#define JPEG_THUMBNAIL_QUALITY 60 +#define EXIF_LIMIT_SIZE 64*1024 +//#define JPEG_WA_FOR_PAGEFAULT +#define JPEG_WA_BUFFER_SIZE 64 + +class SecJpegEncoder { +public : + ; + enum ERROR { + ERROR_ALREADY_CREATE = -0x200, + ERROR_CANNOT_CREATE_SEC_JPEG_ENC_HAL, + ERROR_NOT_YET_CREATED, + ERROR_ALREADY_DESTROY, + ERROR_INPUT_DATA_SIZE_TOO_LARGE, + ERROR_OUT_BUFFER_SIZE_TOO_SMALL, + ERROR_EXIFOUT_ALLOC_FAIL, + ERROR_MAKE_EXIF_FAIL, + ERROR_INVALID_SCALING_WIDTH_HEIGHT, + ERROR_CANNOT_CREATE_SEC_THUMB, + ERROR_THUMB_JPEG_SIZE_TOO_SMALL, + ERROR_IMPLEMENT_NOT_YET, + ERROR_JPEG_DEVICE_ALREADY_CREATE = -0x100, + ERROR_CANNOT_OPEN_JPEG_DEVICE, + ERROR_JPEG_DEVICE_ALREADY_CLOSED, + ERROR_JPEG_DEVICE_ALREADY_DESTROY, + ERROR_JPEG_DEVICE_NOT_CREATE_YET, + ERROR_INVALID_COLOR_FORMAT, + ERROR_INVALID_JPEG_FORMAT, + ERROR_JPEG_CONFIG_POINTER_NULL, + ERROR_INVALID_JPEG_CONFIG, + ERROR_IN_BUFFER_CREATE_FAIL, + ERROR_OUT_BUFFER_CREATE_FAIL, + ERROR_EXCUTE_FAIL, + ERROR_JPEG_SIZE_TOO_SMALL, + ERROR_CANNOT_CHANGE_CACHE_SETTING, + ERROR_SIZE_NOT_SET_YET, + ERROR_BUFFR_IS_NULL, + ERROR_BUFFER_TOO_SMALL, + ERROR_GET_SIZE_FAIL, + ERROR_REQBUF_FAIL, + ERROR_INVALID_V4l2_BUF_TYPE = -0x80, + ERROR_MMAP_FAILED, + ERROR_FAIL, + ERROR_NONE = 0 + }; + + SecJpegEncoder(); + virtual ~SecJpegEncoder(); + + bool flagCreate(); + int create(void); + int destroy(void); + + int setSize(int w, int h); + int setQuality(int quality); + int setColorFormat(int colorFormat); + int setJpegFormat(int jpegFormat); + + int updateConfig(void); + + char *getInBuf(int *input_size); + char *getOutBuf(int *output_size); + int setInBuf(char *buf, int size); + int setOutBuf(char *buf, int size); + + int encode(int *size, exif_attribute_t *exifInfo); + + int setThumbnailSize(int w, int h); + + int makeExif(unsigned char *exifOut, + exif_attribute_t *exifIn, + unsigned int *size, + bool useMainbufForThumb = false); + +private: + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + uint32_t value); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start); + int m_scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHight, + char *dstBuf, uint32_t dstWidth, uint32_t dstHight); + // thumbnail + int encodeThumbnail(unsigned int *size, bool useMain = true); + + int allocJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size); + void freeJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size); + + bool m_flagCreate; + + SecJpegEncoderHal *m_jpegMain; + SecJpegEncoderHal *m_jpegThumb; + + char *m_pThumbInputBuffer; + char *m_pThumbOutputBuffer; +#ifdef JPEG_WA_FOR_PAGEFAULT + char *m_pExtInBuf; + char *m_pJpegInputBuffer; + int m_iInBufSize; +#endif // JPEG_WA_FOR_PAGEFAULT + ion_client m_ionJpegClient; + ion_buffer m_ionThumbInBuffer, m_ionThumbOutBuffer; +#ifdef JPEG_WA_FOR_PAGEFAULT + ion_buffer m_ionJpegInBuffer; +#endif // JPEG_WA_FOR_PAGEFAULT + + int m_thumbnailW; + int m_thumbnailH; +}; + +#endif /* __SEC_JPG_ENC_H__ */ diff --git a/exynos5/hal/include/SecRect.h b/exynos5/hal/include/SecRect.h new file mode 100644 index 0000000..1160a0b --- /dev/null +++ b/exynos5/hal/include/SecRect.h @@ -0,0 +1,172 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/*! + * \file SecRect.h + * \brief header file for SecRect + * \author Sangwoo, Park(sw5771.park@samsung.com) + * \date 2011/06/02 + * + * Revision History: + * - 2010/06/03 : Sangwoo, Park(sw5771.park@samsung.com) \n + * Initial version + * + */ + +/** + * @page SecRect + * + * @section Introduction + * SetRect is common struct for rectangle + * + * @section Copyright + * Copyright (c) 2008-2011 Samsung Electronics Co., Ltd.All rights reserved. \n + * Proprietary and Confidential + * + * @image html samsung.png + */ + +#ifndef __SEC_RECT_H__ +#define __SEC_RECT_H__ + +//! Rectangle information +struct SecRect +{ + int x; //!< x pos + int y; //!< y pos + int w; //!< width + int h; //!< height + int fullW; //!< full width of image + int fullH; //!< full height of image + int colorFormat; //!< V4L2_PIX_FMT_XXX + + //! Constructor + SecRect(int _x_ = 0, + int _y_ = 0, + int _w_ = 0, + int _h_ = 0, + int _fullW_ = 0, + int _fullH_ = 0, + int _colorFormat_ = 0) + { + x = _x_; + y = _y_; + w = _w_; + h = _h_; + fullW = _fullW_; + fullH = _fullH_; + colorFormat = _colorFormat_; + } + + //! Constructor + SecRect(const SecRect *other) + { + x = other->x; + y = other->y; + w = other->w; + h = other->h; + fullW = other->fullW; + fullH = other->fullH; + colorFormat = other->colorFormat; + } + + //! Operator(=) override + SecRect& operator =(const SecRect &other) + { + x = other.x; + y = other.y; + w = other.w; + h = other.h; + fullW = other.fullW; + fullH = other.fullH; + colorFormat = other.colorFormat; + return *this; + } + + //! Operator(==) override + bool operator ==(const SecRect &other) const + { + return ( x == other.x + && y == other.y + && w == other.w + && h == other.h + && fullW == other.fullW + && fullH == other.fullH + && colorFormat == other.colorFormat); + } + + //! Operator(!=) override + bool operator !=(const SecRect &other) const + { + // use operator(==) + return !(*this == other); + } +}; + +//! Clip information +struct SecRect2 +{ + int x1; //!< Left (The x-coordinate value of upper-left corner) + int y1; //!< Top (The y-coordinate value of upper-left corner) + int x2; //!< Right (The x-coordinate value of lower-right corner) + int y2; //!< Bottom (The y-coordinate value of lower-right corner) + + //! Constructor + SecRect2(int _x1_ = 0, int _y1_ = 0, int _x2_ = 0, int _y2_ = 0) + { + x1 = _x1_; + y1 = _y1_; + x2 = _x2_; + y2 = _y2_; + } + + //! Constructor + SecRect2(const SecRect2 *other) + { + x1 = other->x1; + y1 = other->y1; + x2 = other->x2; + y2 = other->y2; + } + + //! Operator(=) override + SecRect2& operator =(const SecRect2 &other) + { + x1 = other.x1; + y1 = other.y1; + x2 = other.x2; + y2 = other.y2; + return *this; + } + + //! Operator(==) override + bool operator ==(const SecRect2 &other) const + { + return ( x1 == other.x1 + && y1 == other.y1 + && x2 == other.x2 + && y2 == other.y2); + } + + //! Operator(!=) override + bool operator !=(const SecRect2 &other) const + { + // use operator(==) + return !(*this == other); + } +}; + +#endif //__SEC_RECT_H__ diff --git a/exynos5/hal/include/audio.h b/exynos5/hal/include/audio.h new file mode 100644 index 0000000..1275db3 --- /dev/null +++ b/exynos5/hal/include/audio.h @@ -0,0 +1,363 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _AUDIO_H_ +#define _AUDIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __HDMI_AUDIO_HDMIAUDIOPORT__ +#define __HDMI_AUDIO_HDMIAUDIOPORT__ +/** + * @enum HDMIAudioPort + * Available audio inputs on HDMI HW module. + */ +enum HDMIAudioPort { + /** I2S input port */ + I2S_PORT, + /** SPDIF input port */ + SPDIF_PORT, + /** DSD input port */ + DSD_PORT, +}; +#endif /* __HDMI_AUDIO_HDMIAUDIOPORT__ */ + +#ifndef __HDMI_AUDIO_AUDIOFORMAT__ +#define __HDMI_AUDIO_AUDIOFORMAT__ +/** + * @enum AudioFormat + * The encoding format of audio stream + */ +enum AudioFormat { + /** LPCM encoding format */ + LPCM_FORMAT = 1, + /** AC3 encoding format */ + AC3_FORMAT, + /** MPEG1 encoding format */ + MPEG1_FORMAT, + /** MP3 encoding format */ + MP3_FORMAT, + /** MPEG2 encoding format */ + MPEG2_FORMAT, + /** AAC encoding format */ + AAC_FORMAT, + /** DTS encoding format */ + DTS_FORMAT, + /** ATRAC encoding format */ + ATRAC_FORMAT, + /** DSD encoding format */ + DSD_FORMAT, + /** Dolby Digital+ encoding format */ + Dolby_Digital_Plus_FORMAT, + /** DTS HD encoding format */ + DTS_HD_FORMAT, + /** MAT encoding format */ + MAT_FORMAT, + /** DST encoding format */ + DST_FORMAT, + /** WAM_Pro encoding format */ + WAM_Pro_FORMAT +}; +#endif /* __HDMI_AUDIO_AUDIOFORMAT__ */ + +#ifndef __HDMI_AUDIO_LPCMWORDLENGTH__ +#define __HDMI_AUDIO_LPCMWORDLENGTH__ +/** + * @enum LPCM_WordLen + * Word length of LPCM audio stream. + */ +enum LPCM_WordLen { + /** 16bit word length */ + WORD_16 = 0, + /** 17bit word length */ + WORD_17, + /** 18bit word length */ + WORD_18, + /** 19bit word length */ + WORD_19, + /** 20bit word length */ + WORD_20, + /** 21bit word length */ + WORD_21, + /** 22bit word length */ + WORD_22, + /** 23bit word length */ + WORD_23, + /** 24bit word length */ + WORD_24 +}; +#endif /* __HDMI_AUDIO_LPCMWORDLENGTH__ */ + +#ifndef __HDMI_AUDIO_SAMPLINGFREQUENCY__ +#define __HDMI_AUDIO_SAMPLINGFREQUENCY__ +/** + * @enum SamplingFreq + * Sampling frequency of audio stream. + */ +enum SamplingFreq { + /** 32KHz sampling frequency */ + SF_32KHZ = 0, + /** 44.1KHz sampling frequency */ + SF_44KHZ, + /** 48KHz sampling frequency */ + SF_48KHZ, + /** 88.2KHz sampling frequency */ + SF_88KHZ, + /** 96KHz sampling frequency */ + SF_96KHZ, + /** 176.4KHz sampling frequency */ + SF_176KHZ, + /** 192KHz sampling frequency */ + SF_192KHZ +}; +#endif /* __HDMI_AUDIO_SAMPLINGFREQUENCY__ */ + +#ifndef __HDMI_AUDIO_CHANNELNUMBER__ +#define __HDMI_AUDIO_CHANNELNUMBER__ +/** + * @enum ChannelNum + * Channel number of audio stream. + */ +enum ChannelNum { + /** 2 channel audio stream */ + CH_2 = 2, + /** 3 channel audio stream */ + CH_3, + /** 4 channel audio stream */ + CH_4, + /** 5 channel audio stream */ + CH_5, + /** 6 channel audio stream */ + CH_6, + /** 7 channel audio stream */ + CH_7, + /** 8 channel audio stream */ + CH_8, +}; +#endif /* __HDMI_AUDIO_CHANNELNUMBER__ */ + +#ifndef __HDMI_AUDIO_AUDIOSAMPLEPACKETTYPE__ +#define __HDMI_AUDIO_AUDIOSAMPLEPACKETTYPE__ +/** + * @enum HDMIASPType + * Type of HDMI audio sample packet + */ +enum HDMIASPType { + /** Audio Sample Packet Type */ + HDMI_ASP, + /** One Bit Audio Packet Type */ + HDMI_DSD, + /** High Bit Rate Packet Type */ + HDMI_HBR, + /** DST Packet Type */ + HDMI_DST +}; +#endif /* __HDMI_AUDID_AUDIOSAMPLEPACKETTYPE__ */ + +#ifndef __HDMI_AUDIO_I2S_CUV_AUDIO_CODING_TYPE__ +#define __HDMI_AUDIO_I2S_CUV_AUDIO_CODING_TYPE__ +/** + * @enum CUVAudioCoding + * Audio coding type information for CUV fields. + */ +enum CUVAudioCoding { + /** Linear PCM coding type */ + CUV_LPCM, + /** Non-linear PCM coding type */ + CUV_NLPCM +}; +#endif /* __HDMI_AUDIO_I2S_CUV_AUDIO_CODING_TYPE__ */ + +#ifndef __HDMI_AUDIO_SPDIF_AUDIO_CODING_TYPE__ +#define __HDMI_AUDIO_SPDIF_AUDIO_CODING_TYPE__ +/** + * @enum SPDIFAudioCoding + * Audio coding type information for SPDIF input port. + */ +enum SPDIFAudioCoding { + /** Linear PCM coding type */ + SPDIF_LPCM, + /** Non-linear PCM coding type */ + SPDIF_NLPCM +}; +#endif /* __HDMI_AUDIO_SPDIF_AUDIO_CODING_TYPE__ */ + +#ifndef __HDMI_AUDIO_I2S_CUV_CHANNEL_NUMBER__ +#define __HDMI_AUDIO_I2S_CUV_CHANNEL_NUMBER__ +/** + * @enum CUVChannelNumber + * Channel number information for CUV fields. + */ +enum CUVChannelNumber { + /** Unknown channel audio stream */ + CUV_CH_UNDEFINED = 0, + /** 1 channel audio stream */ + CUV_CH_01, + /** 2 channel audio stream */ + CUV_CH_02, + /** 3 channel audio stream */ + CUV_CH_03, + /** 4 channel audio stream */ + CUV_CH_04, + /** 5 channel audio stream */ + CUV_CH_05, + /** 6 channel audio stream */ + CUV_CH_06, + /** 7 channel audio stream */ + CUV_CH_07, + /** 8 channel audio stream */ + CUV_CH_08, + /** 9 channel audio stream */ + CUV_CH_09, + /** 10 channel audio stream */ + CUV_CH_10, + /** 11 channel audio stream */ + CUV_CH_11, + /** 12 channel audio stream */ + CUV_CH_12, + /** 13 channel audio stream */ + CUV_CH_13, + /** 14 channel audio stream */ + CUV_CH_14, + /** 15 channel audio stream */ + CUV_CH_15, +}; +#endif /* __HDMI_AUDIO_I2S_CUV_CHANNEL_NUMBER__ */ + +#ifndef __HDMI_AUDIO_I2S_CUV_WORD_LENGTH__ +#define __HDMI_AUDIO_I2S_CUV_WORD_LENGTH__ +/** + * @enum CUVWordLength + * Word length information of LPCM audio stream for CUV fields. + */ +enum CUVWordLength { + /** Max word length is 20 bits, number of valid bits is not defined */ + CUV_WL_20_NOT_DEFINED, + /** Max word length is 20 bits, 16 bits are valid */ + CUV_WL_20_16, + /** Max word length is 20 bits, 18 bits are valid */ + CUV_WL_20_18, + /** Max word length is 20 bits, 19 bits are valid */ + CUV_WL_20_19, + /** Max word length is 20 bits, 20 bits are valid */ + CUV_WL_20_20, + /** Max word length is 20 bits, 17 bits are valid */ + CUV_WL_20_17, + /** Max word length is 24 bits, number of valid bits is not defined */ + CUV_WL_24_NOT_DEFINED, + /** Max word length is 24 bits, 20 bits are valid */ + CUV_WL_24_20, + /** Max word length is 24 bits, 22 bits are valid */ + CUV_WL_24_22, + /** Max word length is 24 bits, 23 bits are valid */ + CUV_WL_24_23, + /** Max word length is 24 bits, 24 bits are valid */ + CUV_WL_24_24, + /** Max word length is 24 bits, 21 bits are valid */ + CUV_WL_24_21, +}; +#endif /* __HDMI_AUDIO_I2S_CUV_WORD_LENGTH__ */ + +#ifndef __HDMI_AUDIO_I2S_BITS_PER_CHANNEL__ +#define __HDMI_AUDIO_I2S_BITS_PER_CHANNEL__ + +/** + * @enum I2SBitsPerChannel + * Serial data bit per channel in I2S audio stream. + */ +enum I2SBitsPerChannel { + /** 16 bits per channel */ + I2S_BPC_16, + /** 20 bits per channel */ + I2S_BPC_20, + /** 24 bits per channel */ + I2S_BPC_24 +}; + +#endif /* __HDMI_AUDIO_I2S_BITS_PER_CHANNEL__ */ + +#ifndef __HDMI_AUDIO_I2S_DATA_FORMAT__ +#define __HDMI_AUDIO_I2S_DATA_FORMAT__ + +/** + * @enum I2SDataFormat + * Foramt of data in I2S audio stream. + */ +enum I2SDataFormat { + /** Basic format */ + I2S_BASIC, + /** Left justified format */ + I2S_LEFT_JUSTIFIED, + /** Right justified format */ + I2S_RIGHT_JUSTIFIED +}; + +#endif /* __HDMI_AUDIO_I2S_DATA_FORMAT__ */ + +#ifndef __HDMI_AUDIO_I2S_CLOCK_PER_FRAME__ +#define __HDMI_AUDIO_I2S_CLOCK_PER_FRAME__ + +/** + * @enum I2SClockPerFrame + * Bit clock per Frame in I2S audio stream. + */ +enum I2SClockPerFrame { + /** 32 clock per Frame */ + I2S_32FS, + /** 48 clock per Frame */ + I2S_48FS, + /** 64 clock per Frame */ + I2S_64FS +}; + +#endif /* __HDMI_AUDIO_I2S_CLOCK_PER_FRAME__ */ + +#ifndef __HDMI_AUDIO_I2S_PARAMETER__ +#define __HDMI_AUDIO_I2S_PARAMETER__ + +//! Structure for I2S audio stream +struct I2SParameter { + enum I2SBitsPerChannel bpc; + enum I2SDataFormat format; + enum I2SClockPerFrame clk; +}; +#endif /* __HDMI_AUDIO_I2S_PARAMETER__ */ + +//! Structure for HDMI audio input +struct HDMIAudioParameter { + /** Input audio port to HDMI HW */ + enum HDMIAudioPort inputPort; + /** Output Packet type **/ + enum HDMIASPType outPacket; + /** Encoding format */ + enum AudioFormat formatCode; + /** Channel number */ + enum ChannelNum channelNum; + /** Sampling frequency */ + enum SamplingFreq sampleFreq; + /** Word length. This is avaliable only if LPCM encoding format */ + enum LPCM_WordLen wordLength; + /** structure for I2S audio stream */ + struct I2SParameter i2sParam; +}; + +#ifdef __cplusplus +} +#endif + +#endif // _AUDIO_H_ diff --git a/exynos5/hal/include/exynos_mem.h b/exynos5/hal/include/exynos_mem.h new file mode 100644 index 0000000..a65f030 --- /dev/null +++ b/exynos5/hal/include/exynos_mem.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __INCLUDE_EXYNOS_MEM_H +#define __INCLUDE_EXYNOS_MEM_H __FILE__ + +/* IOCTL commands */ +#define EXYNOS_MEM_SET_CACHEABLE _IOW('M', 200, bool) +#define EXYNOS_MEM_PADDR_CACHE_FLUSH _IOW('M', 201, struct exynos_mem_flush_range) + +struct exynos_mem_flush_range { + dma_addr_t start; + size_t length; +}; + +#endif /* __INCLUDE_EXYNOS_MEM_H */ diff --git a/exynos5/hal/include/gralloc_priv.h b/exynos5/hal/include/gralloc_priv.h new file mode 100644 index 0000000..05d7754 --- /dev/null +++ b/exynos5/hal/include/gralloc_priv.h @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_PRIV_H_ +#define GRALLOC_PRIV_H_ + +#include +#include +#include +#include + +#include +#include + +#include "ump.h" + +/* + * HWC_HWOVERLAY is flag for location of glFinish(). + * Enable this define if you want that glFinish() is in HWComposer. + * If you disable this define, glFinish() is called in threadloop(). + */ +#define HWC_HWOVERLAY 1 + +#define GRALLOC_ARM_UMP_MODULE 1 + +struct private_handle_t; + +struct private_module_t +{ + gralloc_module_t base; + + private_handle_t* framebuffer; + uint32_t flags; + uint32_t numBuffers; + uint32_t bufferMask; + pthread_mutex_t lock; + buffer_handle_t currentBuffer; + int ion_client; + + struct fb_var_screeninfo info; + struct fb_fix_screeninfo finfo; + float xdpi; + float ydpi; + float fps; + + enum { + PRIV_USAGE_LOCKED_FOR_POST = 0x80000000 + }; +}; + +#ifdef __cplusplus +struct private_handle_t : public native_handle +{ +#else +struct private_handle_t +{ + struct native_handle nativeHandle; +#endif + + enum { + PRIV_FLAGS_FRAMEBUFFER = 0x00000001, + PRIV_FLAGS_USES_UMP = 0x00000002, + PRIV_FLAGS_USES_ION = 0x00000020, + }; + + enum { + LOCK_STATE_WRITE = 1<<31, + LOCK_STATE_MAPPED = 1<<30, + LOCK_STATE_READ_MASK = 0x3FFFFFFF + }; + + // Following member is for ION memory only + int fd; + int magic; + int flags; + int size; + int base; + int lockState; + int writeOwner; + int pid; + + // Following members are for UMP memory only + ump_secure_id ump_id; + ump_handle ump_mem_handle; + + // Following members is for framebuffer only + int offset; + int paddr; + + int format; + int usage; + int width; + int height; + int bpp; + int stride; + + /* Following members are for YUV information */ + unsigned int yaddr; + unsigned int uoffset; + unsigned int voffset; + int ion_client; + +#ifdef __cplusplus + static const int sNumInts = 21; + static const int sNumFds = 1; + static const int sMagic = 0x3141592; + + private_handle_t(int flags, int size, int base, int lock_state, ump_secure_id secure_id, ump_handle handle): + magic(sMagic), + flags(flags), + size(size), + base(base), + lockState(lock_state), + writeOwner(0), + pid(getpid()), + ump_id(secure_id), + ump_mem_handle(handle), + fd(0), + format(0), + usage(0), + width(0), + height(0), + bpp(0), + stride(0), + yaddr(0), + uoffset(0), + voffset(0), + offset(0) + { + version = sizeof(native_handle); + numFds = sNumFds; + numInts = sNumInts; + } + + private_handle_t(int flags, int size, int base, int lock_state, int fb_file, int fb_offset): + magic(sMagic), + flags(flags), + size(size), + base(base), + lockState(lock_state), + writeOwner(0), + pid(getpid()), + ump_id(UMP_INVALID_SECURE_ID), + ump_mem_handle(UMP_INVALID_MEMORY_HANDLE), + fd(fb_file), + format(0), + usage(0), + width(0), + height(0), + bpp(0), + stride(0), + yaddr(0), + uoffset(0), + voffset(0), + offset(fb_offset) + { + version = sizeof(native_handle); + numFds = sNumFds; + numInts = sNumInts; + } + + ~private_handle_t() + { + magic = 0; + } + + bool usesPhysicallyContiguousMemory() + { + return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false; + } + + static int validate(const native_handle* h) + { + const private_handle_t* hnd = (const private_handle_t*)h; + + if (!h || h->version != sizeof(native_handle) || + h->numInts != sNumInts || + h->numFds != sNumFds || + hnd->magic != sMagic) + return -EINVAL; + + return 0; + } + + static private_handle_t* dynamicCast(const native_handle* in) + { + if (validate(in) == 0) + return (private_handle_t*) in; + + return NULL; + } +#endif +}; + +#endif /* GRALLOC_PRIV_H_ */ diff --git a/exynos5/hal/include/i2c-dev.h b/exynos5/hal/include/i2c-dev.h new file mode 100644 index 0000000..a7a35a7 --- /dev/null +++ b/exynos5/hal/include/i2c-dev.h @@ -0,0 +1,74 @@ +/* + i2c-dev.h - i2c-bus driver, char device interface + + Copyright (C) 1995-97 Simon G. Vogl + Copyright (C) 1998-99 Frodo Looijaard + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _LINUX_I2C_DEV_H +#define _LINUX_I2C_DEV_H + +#include +#include + +/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an + * unsigned long, except for: + * - I2C_FUNCS, takes pointer to an unsigned long + * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data + * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data + */ +#define I2C_RETRIES 0x0701 /* number of times a device address should + be polled when not acknowledging */ +#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */ + +/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses + * are NOT supported! (due to code brokenness) + */ +#define I2C_SLAVE 0x0703 /* Use this slave address */ +#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it + is already in use by a driver! */ +#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ + +#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ + +#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */ + +#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ +#define I2C_SMBUS 0x0720 /* SMBus transfer */ + + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + __u8 read_write; + __u8 command; + __u32 size; + union i2c_smbus_data __user *data; +}; + +/* This is the structure as used in the I2C_RDWR ioctl call */ +struct i2c_rdwr_ioctl_data { + struct i2c_msg __user *msgs; /* pointers to i2c_msgs */ + __u32 nmsgs; /* number of i2c_msgs */ +}; + +#define I2C_RDRW_IOCTL_MAX_MSGS 42 + +#ifdef __KERNEL__ +#define I2C_MAJOR 89 /* Device major number */ +#endif + +#endif /* _LINUX_I2C_DEV_H */ diff --git a/exynos5/hal/include/ion.h b/exynos5/hal/include/ion.h new file mode 100644 index 0000000..dbb8896 --- /dev/null +++ b/exynos5/hal/include/ion.h @@ -0,0 +1,144 @@ +#ifndef _LIB_ION_H_ +#define _LIB_ION_H_ + +#include /* size_t */ + +#define ION_HEAP_SYSTEM_MASK (1 << 0) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1) +#define ION_HEAP_EXYNOS_MASK (1 << 4) +#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 5) + +/* ION_MSYNC_FLAGS + * values of @flags parameter to ion_msync() + * + * IMSYNC_DEV_TO_READ: Device only reads the buffer + * IMSYNC_DEV_TO_WRITE: Device may writes to the buffer + * IMSYNC_DEV_TO_RW: Device reads and writes to the buffer + * + * IMSYNC_SYNC_FOR_DEV: ion_msync() for device to access the buffer + * IMSYNC_SYNC_FOR_CPU: ion_msync() for CPU to access the buffer after device + * has accessed it. + * + * The values must be ORed with one of IMSYNC_DEV_* and one of IMSYNC_SYNC_*. + * Otherwise, ion_msync() will not effect. + */ +enum ION_MSYNC_FLAGS { + IMSYNC_DEV_TO_READ = 0, + IMSYNC_DEV_TO_WRITE = 1, + IMSYNC_DEV_TO_RW = 2, + IMSYNC_SYNC_FOR_DEV = 0x10000, + IMSYNC_SYNC_FOR_CPU = 0x20000, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ion_client + * An ION client is an object or an entity that needs to use the service of + * ION and has unique address space. ion_client is an identifier of an ION + * client and it represents the ION client. + * All operations on ION needs a valid ion_client value and it can be obtained + * by ion_client_create(). + */ +typedef int ion_client; + +/* ion_buffer + * An identifier of a buffer allocated from ION. You must obtain to access + * a buffer allocated from ION. If you have an effective ion_buffer, you have + * three options to work with it. + * - To access the buffer, you can request an address (user virtual address) + * of the buffer with ion_map(). + * - To pass the buffer to the kernel, you can pass the ion_buffer to the + * kernel driver directly, if the kernel driver can work with ION. + * - To pass the buffer to other processes, you can pass the ion_buffer to + * other processes through RPC machanism such as socket communication or + * Android Binder because ion_buffer is actually an open file descripotor + * of the current process. + */ +typedef int ion_buffer; + +/* ion_client_create() + * @RETURN: new ion_client. + * netative value if creating new ion_client is failed. + * + * A call to ion_client_create() must be paired with ion_client_destroy(), + * symmetrically. ion_client_destroy() needs a valid ion_client that + * is returned by ion_client_create(). + */ +ion_client ion_client_create(void); + +/* ion_client_destroy() + * @client: An ion_client value to remove. + */ +void ion_client_destroy(ion_client client); + +/* ion_alloc() - Allocates new buffer from ION. + * @client: A valid ion_client value returned by ion_client_create(). + * @len: Size of a buffer required in bytes. + * @align: Alignment requirements of @len and the start address of the allocated + * buffer. If the @len is not aligned by @align, ION allocates a buffer + * that is aligned by @align and the size of the buffer will be larger + * than @len. + * @flags: Additional requirements about buffer. ION_HEAP_SYSTEM_CONTIG_MASK + * for allocating physically contiguous buffer and ION_HEAP_SYSTEM_MASK + * for virtually contiguous buffer. You can combine those flags or + * simply give -1(0xFFFFFFFF) if you do not care about the contiguouty + * of the buffer. + * @RETURN: An ion_buffer that represents the buffer allocated. It is only + * unique in the context of the given client, @client. + * -error if the allocation failed. + * See the description of ion_buffer above for detailed information. + */ +ion_buffer ion_alloc(ion_client client, size_t len, size_t align, + unsigned int flags); + +/* ion_free() - Frees an existing buffer that is allocated by ION + * @buffer: An ion_buffer of the buffer to be released. + */ +void ion_free(ion_buffer buffer); + +/* ion_map() - Obtains a virtual address of the buffer identied by @buffer + * @buffer: The buffer to map. The virtual address returned is allocated by the + * kernel. + * @len: The size of the buffer to map. This must not exceed the size of the + * buffer represented by @fd_buf. Thus you need to know the size of it + * before calling this function. If @len is less than the size of the + * buffer, this function just map just the size requested (@len) not the + * entire buffer. + * @offset: How many pages will be ignored while mapping.@offset number of + * pages from the start of the buffer will not be mapped. + * @RETURN: The start virtual addres mapped. + * MAP_FAILED if mapping fails. + * + * Note that @len + (@offset * PAGE_SIZE) must not exceed the size of the + * buffer. + */ +void *ion_map(ion_buffer buffer, size_t len, off_t offset); + +/* ion_unmap() - Frees the buffer mapped by ion_map() + * @addr: The address returned by ion_map(). + * @len: The size of the buffer mapped by ion_map(). + * @RETURN: 0 on success, and -1 on failure. + * errno is also set on failure. + */ +int ion_unmap(void *addr, size_t len); + +/* ion_msync() - Makes sure that data in the buffer are visible to H/W peri. + * @client: A valid ion_client value returned by ion_client_create(). + * @buffer: The buffer to perform ion_msync(). + * @flags: Direction of access of H/W peri and CPU. See the description of + * ION_MSYNC_FLAGS. + * @size: Size to ion_msync() in bytes. + * @offset: Where ion_msync() start in @buffer, size in bytes. + * @RETURN: 0 if successful. -error, otherwise. + * + * Note that @offset + @size must not exceed the size of @buffer. + */ +int ion_msync(ion_client client, ion_buffer buffer, long flags, + size_t size, off_t offset); + +#ifdef __cplusplus +} +#endif +#endif /* _LIB_ION_H_ */ diff --git a/exynos5/hal/include/jpeg_api.h b/exynos5/hal/include/jpeg_api.h new file mode 100644 index 0000000..f2685e1 --- /dev/null +++ b/exynos5/hal/include/jpeg_api.h @@ -0,0 +1,121 @@ +#ifndef __JPEG_API_H__ +#define __JPEG_API_H__ + +#define JPEG_DRIVER_NAME "/dev/s5p-jpeg" + +#define MAX_JPEG_WIDTH 3264 +#define MAX_JPEG_HEIGHT 2448 + +#define MAX_JPEG_RES (MAX_JPEG_WIDTH * MAX_JPEG_HEIGHT) + +#define JPEG_STREAM_BUF_SIZE MAX_JPEG_RES +#define JPEG_FRAME_BUF_SIZE (MAX_JPEG_RES * 3) + +#define JPEG_TOTAL_BUF_SIZE (JPEG_STREAM_BUF_SIZE + JPEG_FRAME_BUF_SIZE) + +#define JPEG_IOCTL_MAGIC 'J' + +#define IOCTL_JPEG_DEC_EXE _IO(JPEG_IOCTL_MAGIC, 1) +#define IOCTL_JPEG_ENC_EXE _IO(JPEG_IOCTL_MAGIC, 2) +#define IOCTL_GET_DEC_IN_BUF _IO(JPEG_IOCTL_MAGIC, 3) +#define IOCTL_GET_DEC_OUT_BUF _IO(JPEG_IOCTL_MAGIC, 4) +#define IOCTL_GET_ENC_IN_BUF _IO(JPEG_IOCTL_MAGIC, 5) +#define IOCTL_GET_ENC_OUT_BUF _IO(JPEG_IOCTL_MAGIC, 6) +#define IOCTL_SET_DEC_PARAM _IO(JPEG_IOCTL_MAGIC, 7) +#define IOCTL_SET_ENC_PARAM _IO(JPEG_IOCTL_MAGIC, 8) + +enum jpeg_ret_type{ + JPEG_FAIL, + JPEG_OK, + JPEG_ENCODE_FAIL, + JPEG_ENCODE_OK, + JPEG_DECODE_FAIL, + JPEG_DECODE_OK, + JPEG_OUT_OF_MEMORY, + JPEG_UNKNOWN_ERROR +}; + +enum jpeg_img_quality_level { + QUALITY_LEVEL_1 = 0, /* high */ + QUALITY_LEVEL_2, + QUALITY_LEVEL_3, + QUALITY_LEVEL_4, /* low */ +}; + +/* raw data image format */ +enum jpeg_frame_format { + YUV_422, /* decode output, encode input */ + YUV_420, /* decode output, encode output */ + RGB_565, /* encode input */ +}; + +/* jpeg data format */ +enum jpeg_stream_format { + JPEG_422, /* decode input, encode output */ + JPEG_420, /* decode input, encode output */ + JPEG_444, /* decode input*/ + JPEG_GRAY, /* decode input*/ + JPEG_RESERVED, +}; + +enum jpeg_test_mode { + encode_mode, + decode_mode, +}; + +struct jpeg_dec_param { + unsigned int width; + unsigned int height; + unsigned int size; + enum jpeg_stream_format in_fmt; + enum jpeg_frame_format out_fmt; +}; + +struct jpeg_enc_param { + unsigned int width; + unsigned int height; + unsigned int size; + enum jpeg_frame_format in_fmt; + enum jpeg_stream_format out_fmt; + enum jpeg_img_quality_level quality; +}; + +struct jpeg_args{ + char *in_buf; + unsigned int in_cookie; + unsigned int in_buf_size; + char *out_buf; + unsigned int out_cookie; + unsigned int out_buf_size; + char *mmapped_addr; + struct jpeg_dec_param *dec_param; + struct jpeg_enc_param *enc_param; +}; + +struct jpeg_lib { + int jpeg_fd; + struct jpeg_args args; +}; + +#ifdef __cplusplus +extern "C" { +#endif +int api_jpeg_decode_init(); +int api_jpeg_encode_init(); +int api_jpeg_decode_deinit(int dev_fd); +int api_jpeg_encode_deinit(int dev_fd); +void *api_jpeg_get_decode_in_buf(int dev_fd, unsigned int size); +void *api_jpeg_get_encode_in_buf(int dev_fd, unsigned int size); +void *api_jpeg_get_decode_out_buf(int dev_fd); +void *api_jpeg_get_encode_out_buf(int dev_fd); +void api_jpeg_set_decode_param(struct jpeg_dec_param *param); +void api_jpeg_set_encode_param(struct jpeg_enc_param *param); +enum jpeg_ret_type api_jpeg_decode_exe(int dev_fd, + struct jpeg_dec_param *dec_param); +enum jpeg_ret_type api_jpeg_encode_exe(int dev_fd, + struct jpeg_enc_param *enc_param); +#ifdef __cplusplus +} +#endif + +#endif//__JPEG_API_H__ diff --git a/exynos5/hal/include/jpeg_hal.h b/exynos5/hal/include/jpeg_hal.h new file mode 100644 index 0000000..4d9c160 --- /dev/null +++ b/exynos5/hal/include/jpeg_hal.h @@ -0,0 +1,135 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "videodev2.h" + +#define JPEG_DEC_NODE "/dev/video11" +#define JPEG_ENC_NODE "/dev/video12" + +#define JPEG_MAX_PLANE_CNT 3 +#define JPEG_DEC_OUT_BYTE_ALIGN 8 + +//#define JPEG_PERF_MEAS + +#ifdef JPEG_PERF_MEAS +#define JPEG_PERF_DEFINE(n) \ + struct timeval time_start_##n, time_stop_##n; unsigned long log_time_##n = 0; + +#define JPEG_PERF_START(n) \ + gettimeofday(&time_start_##n, NULL); + +#define JPEG_PERF_END(n) \ + gettimeofday(&time_stop_##n, NULL); log_time_##n = measure_time(&time_start_##n, &time_stop_##n); + +#define JPEG_PERF(n) \ + log_time_##n +#else +#define JPEG_PERF_DEFINE(n) +#define JPEG_PERF_START(n) +#define JPEG_PERF_END(n) +#define JPEG_PERF(n) +#endif + +enum jpeg_ret_type { + JPEG_FAIL, + JPEG_OK, + JPEG_ENCODE_FAIL, + JPEG_ENCODE_OK, + JPEG_DECODE_FAIL, + JPEG_DECODE_OK, + JPEG_OUT_OF_MEMORY, + JPEG_UNKNOWN_ERROR +}; + +enum jpeg_quality_level { + QUALITY_LEVEL_1 = 0, /* high */ + QUALITY_LEVEL_2, + QUALITY_LEVEL_3, + QUALITY_LEVEL_4, /* low */ +}; + +enum jpeg_mode { + JPEG_ENCODE, + JPEG_DECODE +}; + +struct jpeg_buf { + int num_planes; + void *start[JPEG_MAX_PLANE_CNT]; + int length[JPEG_MAX_PLANE_CNT]; +}; + +struct jpeg_buf_info { + int num_planes; + enum v4l2_memory memory; + enum v4l2_buf_type buf_type; + int reserved[4]; +}; + +struct jpeg_pixfmt { + int in_fmt; + int out_fmt; + int reserved[4]; +}; + +struct jpeg_config { + enum jpeg_mode mode; + enum jpeg_quality_level enc_qual; + + int width; + int height; + + int num_planes; + + int scaled_width; + int scaled_height; + + int sizeJpeg; + + union { + struct jpeg_pixfmt enc_fmt; + struct jpeg_pixfmt dec_fmt; + } pix; + + int reserved[8]; +}; + +#ifdef __cplusplus +extern "C" { +#endif +int jpeghal_dec_init(); +int jpeghal_enc_init(); + +int jpeghal_dec_setconfig(int fd, struct jpeg_config *config); +int jpeghal_enc_setconfig(int fd, struct jpeg_config *config); +int jpeghal_dec_getconfig(int fd, struct jpeg_config *config); +int jpeghal_enc_getconfig(int fd, struct jpeg_config *config); + +int jpeghal_set_inbuf(int fd, struct jpeg_buf *buf); +int jpeghal_set_outbuf(int fd, struct jpeg_buf *buf); + +int jpeghal_dec_exe(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf); +int jpeghal_enc_exe(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf); + +int jpeghal_deinit(int fd, struct jpeg_buf *in_buf, struct jpeg_buf *out_buf); + +int jpeghal_s_ctrl(int fd, int cid, int value); +int jpeghal_g_ctrl(int fd, int id); + +unsigned long measure_time(struct timeval *start, struct timeval *stop); +#ifdef __cplusplus +} +#endif diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd.h new file mode 100644 index 0000000..61520b5 --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd.h @@ -0,0 +1,469 @@ +/* + * + * (C) COPYRIGHT 2007-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +/** + * @addtogroup malisw + * @{ + */ + +/* ============================================================================ + Description +============================================================================ */ +/** + * @defgroup arm_cstd_coding_standard ARM C standard types and constants + * The common files are a set of standard headers which are used by all parts + * of this development, describing types, and generic constants. + * + * Files in group: + * - arm_cstd.h + * - arm_cstd_compilers.h + * - arm_cstd_types.h + * - arm_cstd_types_rvct.h + * - arm_cstd_types_gcc.h + * - arm_cstd_types_msvc.h + * - arm_cstd_pack_push.h + * - arm_cstd_pack_pop.h + */ + +/** + * @addtogroup arm_cstd_coding_standard + * @{ + */ + +#ifndef _ARM_CSTD_ +#define _ARM_CSTD_ + +/* ============================================================================ + Import standard C99 types +============================================================================ */ +#include "arm_cstd_compilers.h" +#include "arm_cstd_types.h" + +/* ============================================================================ + Min and Max Values +============================================================================ */ +#if !defined(INT8_MAX) + #define INT8_MAX ((int8_t) 0x7F) +#endif +#if !defined(INT8_MIN) + #define INT8_MIN (-INT8_MAX - 1) +#endif + +#if !defined(INT16_MAX) + #define INT16_MAX ((int16_t)0x7FFF) +#endif +#if !defined(INT16_MIN) + #define INT16_MIN (-INT16_MAX - 1) +#endif + +#if !defined(INT32_MAX) + #define INT32_MAX ((int32_t)0x7FFFFFFF) +#endif +#if !defined(INT32_MIN) + #define INT32_MIN (-INT32_MAX - 1) +#endif + +#if !defined(INT64_MAX) + #define INT64_MAX ((int64_t)0x7FFFFFFFFFFFFFFFLL) +#endif +#if !defined(INT64_MIN) + #define INT64_MIN (-INT64_MAX - 1) +#endif + +#if !defined(UINT8_MAX) + #define UINT8_MAX ((uint8_t) 0xFF) +#endif + +#if !defined(UINT16_MAX) + #define UINT16_MAX ((uint16_t)0xFFFF) +#endif + +#if !defined(UINT32_MAX) + #define UINT32_MAX ((uint32_t)0xFFFFFFFF) +#endif + +#if !defined(UINT64_MAX) + #define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFFULL) +#endif + +/* fallbacks if limits.h wasn't available */ +#if !defined(UCHAR_MAX) + #define UCHAR_MAX ((unsigned char)~0U) +#endif + +#if !defined(SCHAR_MAX) + #define SCHAR_MAX ((signed char)(UCHAR_MAX >> 1)) +#endif +#if !defined(SCHAR_MIN) + #define SCHAR_MIN ((signed char)(-SCHAR_MAX - 1)) +#endif + +#if !defined(USHRT_MAX) + #define USHRT_MAX ((unsigned short)~0U) +#endif + +#if !defined(SHRT_MAX) + #define SHRT_MAX ((signed short)(USHRT_MAX >> 1)) +#endif +#if !defined(SHRT_MIN) + #define SHRT_MIN ((signed short)(-SHRT_MAX - 1)) +#endif + +#if !defined(UINT_MAX) + #define UINT_MAX ((unsigned int)~0U) +#endif + +#if !defined(INT_MAX) + #define INT_MAX ((signed int)(UINT_MAX >> 1)) +#endif +#if !defined(INT_MIN) + #define INT_MIN ((signed int)(-INT_MAX - 1)) +#endif + +#if !defined(ULONG_MAX) + #define ULONG_MAX ((unsigned long)~0UL) +#endif + +#if !defined(LONG_MAX) + #define LONG_MAX ((signed long)(ULONG_MAX >> 1)) +#endif +#if !defined(LONG_MIN) + #define LONG_MIN ((signed long)(-LONG_MAX - 1)) +#endif + +#if !defined(ULLONG_MAX) + #define ULLONG_MAX ((unsigned long long)~0ULL) +#endif + +#if !defined(LLONG_MAX) + #define LLONG_MAX ((signed long long)(ULLONG_MAX >> 1)) +#endif +#if !defined(LLONG_MIN) + #define LLONG_MIN ((signed long long)(-LLONG_MAX - 1)) +#endif + +#if !defined(SIZE_MAX) + #if 1 == CSTD_CPU_32BIT + #define SIZE_MAX UINT32_MAX + #elif 1 == CSTD_CPU_64BIT + #define SIZE_MAX UINT64_MAX + #endif +#endif + +/* ============================================================================ + Keywords +============================================================================ */ +/* Portable keywords. */ + +#if !defined(CONST) +/** + * @hideinitializer + * Variable is a C @c const, which can be made non-const for testing purposes. + */ + #define CONST const +#endif + +#if !defined(STATIC) +/** + * @hideinitializer + * Variable is a C @c static, which can be made non-static for testing + * purposes. + */ + #define STATIC static +#endif + +/** + * Specifies a function as being exported outside of a logical module. + */ +#define PUBLIC + +/** + * @def PROTECTED + * Specifies a a function which is internal to an logical module, but which + * should not be used outside of that module. This cannot be enforced by the + * compiler, as a module is typically more than one translation unit. + */ +#define PROTECTED + +/** + * Specify an assertion value which is evaluated at compile time. Recommended + * usage is specification of a @c static @c INLINE function containing all of + * the assertions thus: + * + * @code + * static INLINE [module]_compile_time_assertions( void ) + * { + * COMPILE_TIME_ASSERT( sizeof(uintptr_t) == sizeof(intptr_t) ); + * } + * @endcode + * + * @note Use @c static not @c STATIC. We never want to turn off this @c static + * specification for testing purposes. + */ +#define CSTD_COMPILE_TIME_ASSERT( expr ) \ + do { switch(0){case 0: case (expr):;} } while( FALSE ) + +/** + * @hideinitializer + * @deprecated Prefered form is @c CSTD_UNUSED + * Function-like macro for suppressing unused variable warnings. Where possible + * such variables should be removed; this macro is present for cases where we + * much support API backwards compatibility. + */ +#define UNUSED( x ) ((void)(x)) + +/** + * @hideinitializer + * Function-like macro for suppressing unused variable warnings. Where possible + * such variables should be removed; this macro is present for cases where we + * much support API backwards compatibility. + */ +#define CSTD_UNUSED( x ) ((void)(x)) + +/** + * @hideinitializer + * Function-like macro for use where "no behavior" is desired. This is useful + * when compile time macros turn a function-like macro in to a no-op, but + * where having no statement is otherwise invalid. + */ +#define CSTD_NOP( ... ) ((void)#__VA_ARGS__) + +/** + * @hideinitializer + * Function-like macro for converting a pointer in to a u64 for storing into + * an external data structure. This is commonly used when pairing a 32-bit + * CPU with a 64-bit peripheral, such as a Midgard GPU. C's type promotion + * is complex and a straight cast does not work reliably as pointers are + * often considered as signed. + */ +#define CSTD_PTR_TO_U64( x ) ((uint64_t)((uintptr_t)(x))) + +/** + * @hideinitializer + * Function-like macro for stringizing a single level macro. + * @code + * #define MY_MACRO 32 + * CSTD_STR1( MY_MACRO ) + * > "MY_MACRO" + * @endcode + */ +#define CSTD_STR1( x ) #x + +/** + * @hideinitializer + * Function-like macro for stringizing a macro's value. This should not be used + * if the macro is defined in a way which may have no value; use the + * alternative @c CSTD_STR2N macro should be used instead. + * @code + * #define MY_MACRO 32 + * CSTD_STR2( MY_MACRO ) + * > "32" + * @endcode + */ +#define CSTD_STR2( x ) CSTD_STR1( x ) + +/** + * @hideinitializer + * Utility function for stripping the first character off a string. + */ +static INLINE char* arm_cstd_strstrip( char * string ) +{ + return ++string; +} + +/** + * @hideinitializer + * Function-like macro for stringizing a single level macro where the macro + * itself may not have a value. Parameter @c a should be set to any single + * character which is then stripped by the macro via an inline function. This + * should only be used via the @c CSTD_STR2N macro; for printing a single + * macro only the @c CSTD_STR1 macro is a better alternative. + * + * This macro requires run-time code to handle the case where the macro has + * no value (you can't concat empty strings in the preprocessor). + */ +#define CSTD_STR1N( a, x ) arm_cstd_strstrip( CSTD_STR1( a##x ) ) + +/** + * @hideinitializer + * Function-like macro for stringizing a two level macro where the macro itself + * may not have a value. + * @code + * #define MY_MACRO 32 + * CSTD_STR2N( MY_MACRO ) + * > "32" + * + * #define MY_MACRO 32 + * CSTD_STR2N( MY_MACRO ) + * > "32" + * @endcode + */ +#define CSTD_STR2N( x ) CSTD_STR1N( _, x ) + +/* ============================================================================ + Validate portability constructs +============================================================================ */ +static INLINE void arm_cstd_compile_time_assertions( void ) +{ + CSTD_COMPILE_TIME_ASSERT( sizeof(uint8_t) == 1 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(int8_t) == 1 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(uint16_t) == 2 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(int16_t) == 2 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(uint32_t) == 4 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(int32_t) == 4 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(uint64_t) == 8 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(int64_t) == 8 ); + CSTD_COMPILE_TIME_ASSERT( sizeof(intptr_t) == sizeof(uintptr_t) ); + + CSTD_COMPILE_TIME_ASSERT( 1 == TRUE ); + CSTD_COMPILE_TIME_ASSERT( 0 == FALSE ); + +#if 1 == CSTD_CPU_32BIT + CSTD_COMPILE_TIME_ASSERT( sizeof(uintptr_t) == 4 ); +#elif 1 == CSTD_CPU_64BIT + CSTD_COMPILE_TIME_ASSERT( sizeof(uintptr_t) == 8 ); +#endif + +} + +/* ============================================================================ + Useful function-like macro +============================================================================ */ +/** + * @brief Return the lesser of two values. + * As a macro it may evaluate its arguments more than once. + * @see CSTD_MAX + */ +#define CSTD_MIN( x, y ) ((x) < (y) ? (x) : (y)) + +/** + * @brief Return the greater of two values. + * As a macro it may evaluate its arguments more than once. + * If called on the same two arguments as CSTD_MIN it is guaranteed to return + * the one that CSTD_MIN didn't return. This is significant for types where not + * all values are comparable e.g. NaNs in floating-point types. But if you want + * to retrieve the min and max of two values, consider using a conditional swap + * instead. + */ +#define CSTD_MAX( x, y ) ((x) < (y) ? (y) : (x)) + +/** + * @brief Clamp value @c x to within @c min and @c max inclusive. + */ +#define CSTD_CLAMP( x, min, max ) ((x)<(min) ? (min):((x)>(max) ? (max):(x))) + +/** + * Flag a cast as a reinterpretation, usually of a pointer type. + */ +#define CSTD_REINTERPRET_CAST(type) (type) + +/** + * Flag a cast as casting away const, usually of a pointer type. + */ +#define CSTD_CONST_CAST(type) (type) + +/** + * Flag a cast as a (potentially complex) value conversion, usually of a + * numerical type. + */ +#define CSTD_STATIC_CAST(type) (type) + +/* ============================================================================ + Useful bit constants +============================================================================ */ +/** + * @cond arm_cstd_utilities + */ + +/* Common bit constant values, useful in embedded programming. */ +#define F_BIT_0 ((uint32_t)0x00000001) +#define F_BIT_1 ((uint32_t)0x00000002) +#define F_BIT_2 ((uint32_t)0x00000004) +#define F_BIT_3 ((uint32_t)0x00000008) +#define F_BIT_4 ((uint32_t)0x00000010) +#define F_BIT_5 ((uint32_t)0x00000020) +#define F_BIT_6 ((uint32_t)0x00000040) +#define F_BIT_7 ((uint32_t)0x00000080) +#define F_BIT_8 ((uint32_t)0x00000100) +#define F_BIT_9 ((uint32_t)0x00000200) +#define F_BIT_10 ((uint32_t)0x00000400) +#define F_BIT_11 ((uint32_t)0x00000800) +#define F_BIT_12 ((uint32_t)0x00001000) +#define F_BIT_13 ((uint32_t)0x00002000) +#define F_BIT_14 ((uint32_t)0x00004000) +#define F_BIT_15 ((uint32_t)0x00008000) +#define F_BIT_16 ((uint32_t)0x00010000) +#define F_BIT_17 ((uint32_t)0x00020000) +#define F_BIT_18 ((uint32_t)0x00040000) +#define F_BIT_19 ((uint32_t)0x00080000) +#define F_BIT_20 ((uint32_t)0x00100000) +#define F_BIT_21 ((uint32_t)0x00200000) +#define F_BIT_22 ((uint32_t)0x00400000) +#define F_BIT_23 ((uint32_t)0x00800000) +#define F_BIT_24 ((uint32_t)0x01000000) +#define F_BIT_25 ((uint32_t)0x02000000) +#define F_BIT_26 ((uint32_t)0x04000000) +#define F_BIT_27 ((uint32_t)0x08000000) +#define F_BIT_28 ((uint32_t)0x10000000) +#define F_BIT_29 ((uint32_t)0x20000000) +#define F_BIT_30 ((uint32_t)0x40000000) +#define F_BIT_31 ((uint32_t)0x80000000) + +/* Common 2^n size values, useful in embedded programming. */ +#define C_SIZE_1B ((uint32_t)0x00000001) +#define C_SIZE_2B ((uint32_t)0x00000002) +#define C_SIZE_4B ((uint32_t)0x00000004) +#define C_SIZE_8B ((uint32_t)0x00000008) +#define C_SIZE_16B ((uint32_t)0x00000010) +#define C_SIZE_32B ((uint32_t)0x00000020) +#define C_SIZE_64B ((uint32_t)0x00000040) +#define C_SIZE_128B ((uint32_t)0x00000080) +#define C_SIZE_256B ((uint32_t)0x00000100) +#define C_SIZE_512B ((uint32_t)0x00000200) +#define C_SIZE_1KB ((uint32_t)0x00000400) +#define C_SIZE_2KB ((uint32_t)0x00000800) +#define C_SIZE_4KB ((uint32_t)0x00001000) +#define C_SIZE_8KB ((uint32_t)0x00002000) +#define C_SIZE_16KB ((uint32_t)0x00004000) +#define C_SIZE_32KB ((uint32_t)0x00008000) +#define C_SIZE_64KB ((uint32_t)0x00010000) +#define C_SIZE_128KB ((uint32_t)0x00020000) +#define C_SIZE_256KB ((uint32_t)0x00040000) +#define C_SIZE_512KB ((uint32_t)0x00080000) +#define C_SIZE_1MB ((uint32_t)0x00100000) +#define C_SIZE_2MB ((uint32_t)0x00200000) +#define C_SIZE_4MB ((uint32_t)0x00400000) +#define C_SIZE_8MB ((uint32_t)0x00800000) +#define C_SIZE_16MB ((uint32_t)0x01000000) +#define C_SIZE_32MB ((uint32_t)0x02000000) +#define C_SIZE_64MB ((uint32_t)0x04000000) +#define C_SIZE_128MB ((uint32_t)0x08000000) +#define C_SIZE_256MB ((uint32_t)0x10000000) +#define C_SIZE_512MB ((uint32_t)0x20000000) +#define C_SIZE_1GB ((uint32_t)0x40000000) +#define C_SIZE_2GB ((uint32_t)0x80000000) + +/** + * @endcond + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* End (_ARM_CSTD_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_compilers.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_compilers.h new file mode 100644 index 0000000..0dcb5e2 --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_compilers.h @@ -0,0 +1,565 @@ +/* + * + * (C) COPYRIGHT 2005-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_COMPILERS_H_ +#define _ARM_CSTD_COMPILERS_H_ + +/* ============================================================================ + Document default definitions - assuming nothing set at this point. +============================================================================ */ +/** + * @addtogroup arm_cstd_coding_standard + * @{ + */ + +/** + * @hideinitializer + * Defined with value of 1 if toolchain is Microsoft Visual Studio, 0 + * otherwise. + */ +#define CSTD_TOOLCHAIN_MSVC 0 + +/** + * @hideinitializer + * Defined with value of 1 if toolchain is the GNU Compiler Collection, 0 + * otherwise. + */ +#define CSTD_TOOLCHAIN_GCC 0 + +/** + * @hideinitializer + * Defined with value of 1 if toolchain is ARM RealView Compiler Tools, 0 + * otherwise. Note - if running RVCT in GCC mode this define will be set to 0; + * @c CSTD_TOOLCHAIN_GCC and @c CSTD_TOOLCHAIN_RVCT_GCC_MODE will both be + * defined as 1. + */ +#define CSTD_TOOLCHAIN_RVCT 0 + +/** + * @hideinitializer + * Defined with value of 1 if toolchain is ARM RealView Compiler Tools running + * in GCC mode, 0 otherwise. + */ +#define CSTD_TOOLCHAIN_RVCT_GCC_MODE 0 + +/** + * @hideinitializer + * Defined with value of 1 if processor is an x86 32-bit machine, 0 otherwise. + */ +#define CSTD_CPU_X86_32 0 + +/** + * @hideinitializer + * Defined with value of 1 if processor is an x86-64 (AMD64) machine, 0 + * otherwise. + */ +#define CSTD_CPU_X86_64 0 + +/** + * @hideinitializer + * Defined with value of 1 if processor is an ARM machine, 0 otherwise. + */ +#define CSTD_CPU_ARM 0 + +/** + * @hideinitializer + * Defined with value of 1 if processor is a MIPS machine, 0 otherwise. + */ +#define CSTD_CPU_MIPS 0 + +/** + * @hideinitializer + * Defined with value of 1 if CPU is 32-bit, 0 otherwise. + */ +#define CSTD_CPU_32BIT 0 + +/** + * @hideinitializer + * Defined with value of 1 if CPU is 64-bit, 0 otherwise. + */ +#define CSTD_CPU_64BIT 0 + +/** + * @hideinitializer + * Defined with value of 1 if processor configured as big-endian, 0 if it + * is little-endian. + */ +#define CSTD_CPU_BIG_ENDIAN 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a version of Windows, 0 if + * it is not. + */ +#define CSTD_OS_WINDOWS 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 32-bit version of Windows, + * 0 if it is not. + */ +#define CSTD_OS_WIN32 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 64-bit version of Windows, + * 0 if it is not. + */ +#define CSTD_OS_WIN64 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is Linux, 0 if it is not. + */ +#define CSTD_OS_LINUX 0 + +/** + * @hideinitializer + * Defined with value of 1 if we are compiling Linux kernel code, 0 otherwise. + */ +#define CSTD_OS_LINUX_KERNEL 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 32-bit version of Linux, + * 0 if it is not. + */ +#define CSTD_OS_LINUX32 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 64-bit version of Linux, + * 0 if it is not. + */ +#define CSTD_OS_LINUX64 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is Android, 0 if it is not. + */ +#define CSTD_OS_ANDROID 0 + +/** + * @hideinitializer + * Defined with value of 1 if we are compiling Android kernel code, 0 otherwise. + */ +#define CSTD_OS_ANDROID_KERNEL 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 32-bit version of Android, + * 0 if it is not. + */ +#define CSTD_OS_ANDROID32 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 64-bit version of Android, + * 0 if it is not. + */ +#define CSTD_OS_ANDROID64 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a version of Apple OS, + * 0 if it is not. + */ +#define CSTD_OS_APPLEOS 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 32-bit version of Apple OS, + * 0 if it is not. + */ +#define CSTD_OS_APPLEOS32 0 + +/** + * @hideinitializer + * Defined with value of 1 if operating system is a 64-bit version of Apple OS, + * 0 if it is not. + */ +#define CSTD_OS_APPLEOS64 0 + +/** + * @def CSTD_OS_SYMBIAN + * @hideinitializer + * Defined with value of 1 if operating system is Symbian, 0 if it is not. + */ +#define CSTD_OS_SYMBIAN 0 + +/** + * @def CSTD_OS_NONE + * @hideinitializer + * Defined with value of 1 if there is no operating system (bare metal), 0 + * otherwise + */ +#define CSTD_OS_NONE 0 + +/* ============================================================================ + Determine the compiler in use +============================================================================ */ +#if defined(_MSC_VER) + #undef CSTD_TOOLCHAIN_MSVC + #define CSTD_TOOLCHAIN_MSVC 1 + +#elif defined(__GNUC__) + #undef CSTD_TOOLCHAIN_GCC + #define CSTD_TOOLCHAIN_GCC 1 + + /* Detect RVCT pretending to be GCC. */ + #if defined(__ARMCC_VERSION) + #undef CSTD_TOOLCHAIN_RVCT_GCC_MODE + #define CSTD_TOOLCHAIN_RVCT_GCC_MODE 1 + #endif + +#elif defined(__ARMCC_VERSION) + #undef CSTD_TOOLCHAIN_RVCT + #define CSTD_TOOLCHAIN_RVCT 1 + +#else + #warning "Unsupported or unknown toolchain" + +#endif + +/* ============================================================================ + Determine the processor +============================================================================ */ +#if 1 == CSTD_TOOLCHAIN_MSVC + #if defined(_M_IX86) + #undef CSTD_CPU_X86_32 + #define CSTD_CPU_X86_32 1 + + #elif defined(_M_X64) || defined(_M_AMD64) + #undef CSTD_CPU_X86_64 + #define CSTD_CPU_X86_64 1 + + #elif defined(_M_ARM) + #undef CSTD_CPU_ARM + #define CSTD_CPU_ARM 1 + + #elif defined(_M_MIPS) + #undef CSTD_CPU_MIPS + #define CSTD_CPU_MIPS 1 + + #else + #warning "Unsupported or unknown host CPU for MSVC tools" + + #endif + +#elif 1 == CSTD_TOOLCHAIN_GCC + #if defined(__amd64__) + #undef CSTD_CPU_X86_64 + #define CSTD_CPU_X86_64 1 + + #elif defined(__i386__) + #undef CSTD_CPU_X86_32 + #define CSTD_CPU_X86_32 1 + + #elif defined(__arm__) + #undef CSTD_CPU_ARM + #define CSTD_CPU_ARM 1 + + #elif defined(__mips__) + #undef CSTD_CPU_MIPS + #define CSTD_CPU_MIPS 1 + + #else + #warning "Unsupported or unknown host CPU for GCC tools" + + #endif + +#elif 1 == CSTD_TOOLCHAIN_RVCT + #undef CSTD_CPU_ARM + #define CSTD_CPU_ARM 1 + +#else + #warning "Unsupported or unknown toolchain" + +#endif + +/* ============================================================================ + Determine the Processor Endianness +============================================================================ */ + +#if ((1 == CSTD_CPU_X86_32) || (1 == CSTD_CPU_X86_64)) + /* Note: x86 and x86-64 are always little endian, so leave at default. */ + +#elif 1 == CSTD_TOOLCHAIN_RVCT + #if defined(__BIG_ENDIAN) + #undef CSTD_ENDIAN_BIG + #define CSTD_ENDIAN_BIG 1 + #endif + +#elif ((1 == CSTD_TOOLCHAIN_GCC) && (1 == CSTD_CPU_ARM)) + #if defined(__ARMEB__) + #undef CSTD_ENDIAN_BIG + #define CSTD_ENDIAN_BIG 1 + #endif + +#elif ((1 == CSTD_TOOLCHAIN_GCC) && (1 == CSTD_CPU_MIPS)) + #if defined(__MIPSEB__) + #undef CSTD_ENDIAN_BIG + #define CSTD_ENDIAN_BIG 1 + #endif + +#elif 1 == CSTD_TOOLCHAIN_MSVC + /* Note: Microsoft only support little endian, so leave at default. */ + +#else + #warning "Unsupported or unknown CPU" + +#endif + +/* ============================================================================ + Determine the operating system and addressing width +============================================================================ */ +#if 1 == CSTD_TOOLCHAIN_MSVC + #if defined(_WIN32) && !defined(_WIN64) + #undef CSTD_OS_WINDOWS + #define CSTD_OS_WINDOWS 1 + #undef CSTD_OS_WIN32 + #define CSTD_OS_WIN32 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + + #elif defined(_WIN32) && defined(_WIN64) + #undef CSTD_OS_WINDOWS + #define CSTD_OS_WINDOWS 1 + #undef CSTD_OS_WIN64 + #define CSTD_OS_WIN64 1 + #undef CSTD_CPU_64BIT + #define CSTD_CPU_64BIT 1 + + #else + #warning "Unsupported or unknown host OS for MSVC tools" + + #endif + +#elif 1 == CSTD_TOOLCHAIN_GCC + #if defined(_WIN32) && defined(_WIN64) + #undef CSTD_OS_WINDOWS + #define CSTD_OS_WINDOWS 1 + #undef CSTD_OS_WIN64 + #define CSTD_OS_WIN64 1 + #undef CSTD_CPU_64BIT + #define CSTD_CPU_64BIT 1 + + #elif defined(_WIN32) && !defined(_WIN64) + #undef CSTD_OS_WINDOWS + #define CSTD_OS_WINDOWS 1 + #undef CSTD_OS_WIN32 + #define CSTD_OS_WIN32 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + + #elif defined(ANDROID) + #undef CSTD_OS_ANDROID + #define CSTD_OS_ANDROID 1 + + #if defined(__KERNEL__) + #undef CSTD_OS_ANDROID_KERNEL + #define CSTD_OS_ANDROID_KERNEL 1 + #endif + + #if defined(__LP64__) || defined(_LP64) + #undef CSTD_OS_ANDROID64 + #define CSTD_OS_ANDROID64 1 + #undef CSTD_CPU_64BIT + #define CSTD_CPU_64BIT 1 + #else + #undef CSTD_OS_ANDROID32 + #define CSTD_OS_ANDROID32 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + #endif + + #elif defined(__linux) + #undef CSTD_OS_LINUX + #define CSTD_OS_LINUX 1 + + #if defined(__KERNEL__) + #undef CSTD_OS_LINUX_KERNEL + #define CSTD_OS_LINUX_KERNEL 1 + #endif + + #if defined(__LP64__) || defined(_LP64) + #undef CSTD_OS_LINUX64 + #define CSTD_OS_LINUX64 1 + #undef CSTD_CPU_64BIT + #define CSTD_CPU_64BIT 1 + #else + #undef CSTD_OS_LINUX32 + #define CSTD_OS_LINUX32 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + #endif + + #elif defined(__APPLE__) + #undef CSTD_OS_APPLEOS + #define CSTD_OS_APPLEOS 1 + + #if defined(__LP64__) || defined(_LP64) + #undef CSTD_OS_APPLEOS64 + #define CSTD_OS_APPLEOS64 1 + #undef CSTD_CPU_64BIT + #define CSTD_CPU_64BIT 1 + #else + #undef CSTD_OS_APPLEOS32 + #define CSTD_OS_APPLEOS32 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + #endif + + #elif defined(__SYMBIAN32__) + #undef CSTD_OS_SYMBIAN + #define CSTD_OS_SYMBIAN 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + + #else + #undef CSTD_OS_NONE + #define CSTD_OS_NONE 1 + #undef CSTD_CPU_32BIT + #define CSTD_CPU_32BIT 1 + +#endif + +#elif 1 == CSTD_TOOLCHAIN_RVCT + + #if defined(ANDROID) + #undef CSTD_OS_ANDROID + #undef CSTD_OS_ANDROID32 + #define CSTD_OS_ANDROID 1 + #define CSTD_OS_ANDROID32 1 + + #elif defined(__linux) + #undef CSTD_OS_LINUX + #undef CSTD_OS_LINUX32 + #define CSTD_OS_LINUX 1 + #define CSTD_OS_LINUX32 1 + + #elif defined(__SYMBIAN32__) + #undef CSTD_OS_SYMBIAN + #define CSTD_OS_SYMBIAN 1 + + #else + #undef CSTD_OS_NONE + #define CSTD_OS_NONE 1 + +#endif + +#else + #warning "Unsupported or unknown host OS" + +#endif + +/* ============================================================================ + Determine the correct linker symbol Import and Export Macros +============================================================================ */ +/** + * @defgroup arm_cstd_linkage_specifiers Linkage Specifiers + * @{ + * + * This set of macros contain system-dependent linkage specifiers which + * determine the visibility of symbols across DLL boundaries. A header for a + * particular DLL should define a set of local macros derived from these, + * and should not use these macros to decorate functions directly as there may + * be multiple DLLs being used. + * + * These DLL library local macros should be (with appropriate library prefix) + * [MY_LIBRARY]_API, [MY_LIBRARY]_IMPL, and + * [MY_LIBRARY]_LOCAL. + * + * - [MY_LIBRARY]_API should be use to decorate the function + * declarations in the header. It should be defined as either + * @c CSTD_LINK_IMPORT or @c CSTD_LINK_EXPORT, depending whether the + * current situation is a compile of the DLL itself (use export) or a + * compile of an external user of the DLL (use import). + * - [MY_LIBRARY]_IMPL should be defined as @c CSTD_LINK_IMPL + * and should be used to decorate the definition of functions in the C + * file. + * - [MY_LIBRARY]_LOCAL should be used to decorate function + * declarations which are exported across translation units within the + * DLL, but which are not exported outside of the DLL boundary. + * + * Functions which are @c static in either a C file or in a header file do not + * need any form of linkage decoration, and should therefore have no linkage + * macro applied to them. + */ + +/** + * @def CSTD_LINK_IMPORT + * Specifies a function as being imported to a translation unit across a DLL + * boundary. + */ + +/** + * @def CSTD_LINK_EXPORT + * Specifies a function as being exported across a DLL boundary by a + * translation unit. + */ + +/** + * @def CSTD_LINK_IMPL + * Specifies a function which will be exported across a DLL boundary as + * being implemented by a translation unit. + */ + +/** + * @def CSTD_LINK_LOCAL + * Specifies a function which is internal to a DLL, and which should not be + * exported outside of it. + */ + +/** + * @} + */ + +#if 1 == CSTD_OS_LINUX + #define CSTD_LINK_IMPORT __attribute__((visibility("default"))) + #define CSTD_LINK_EXPORT __attribute__((visibility("default"))) + #define CSTD_LINK_IMPL __attribute__((visibility("default"))) + #define CSTD_LINK_LOCAL __attribute__((visibility("hidden"))) + +#elif 1 == CSTD_OS_WINDOWS + #define CSTD_LINK_IMPORT __declspec(dllimport) + #define CSTD_LINK_EXPORT __declspec(dllexport) + #define CSTD_LINK_IMPL __declspec(dllexport) + #define CSTD_LINK_LOCAL + +#elif 1 == CSTD_OS_SYMBIAN + #define CSTD_LINK_IMPORT IMPORT_C + #define CSTD_LINK_EXPORT IMPORT_C + #define CSTD_LINK_IMPL EXPORT_C + #define CSTD_LINK_LOCAL + +#elif 1 == CSTD_OS_APPLEOS + #define CSTD_LINK_IMPORT __attribute__((visibility("default"))) + #define CSTD_LINK_EXPORT __attribute__((visibility("default"))) + #define CSTD_LINK_IMPL __attribute__((visibility("default"))) + #define CSTD_LINK_LOCAL __attribute__((visibility("hidden"))) + +#else /* CSTD_OS_NONE */ + #define CSTD_LINK_IMPORT + #define CSTD_LINK_EXPORT + #define CSTD_LINK_IMPL + #define CSTD_LINK_LOCAL + +#endif + +/** + * @} + */ + +#endif /* End (_ARM_CSTD_COMPILERS_H_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_pop.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_pop.h new file mode 100644 index 0000000..01f8fab --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_pop.h @@ -0,0 +1,22 @@ +/* + * + * (C) COPYRIGHT 2009-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_PACK_POP_H_ +#define _ARM_CSTD_PACK_POP_H_ + +#if 1 == CSTD_TOOLCHAIN_MSVC + #include +#endif + +#endif /* End (_ARM_CSTD_PACK_POP_H_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_push.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_push.h new file mode 100644 index 0000000..ac1ff93 --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_pack_push.h @@ -0,0 +1,22 @@ +/* + * + * (C) COPYRIGHT 2009-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_PACK_PUSH_H_ +#define _ARM_CSTD_PACK_PUSH_H_ + +#if 1 == CSTD_TOOLCHAIN_MSVC + #include +#endif + +#endif /* End (_ARM_CSTD_PACK_PUSH_H_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types.h new file mode 100644 index 0000000..2e50b57 --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types.h @@ -0,0 +1,28 @@ +/* + * + * (C) COPYRIGHT 2009-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_TYPES_H_ +#define _ARM_CSTD_TYPES_H_ + +#if 1 == CSTD_TOOLCHAIN_MSVC + #include "arm_cstd_types_msvc.h" +#elif 1 == CSTD_TOOLCHAIN_GCC + #include "arm_cstd_types_gcc.h" +#elif 1 == CSTD_TOOLCHAIN_RVCT + #include "arm_cstd_types_rvct.h" +#else + #error "Toolchain not recognized" +#endif + +#endif /* End (_ARM_CSTD_TYPES_H_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_gcc.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_gcc.h new file mode 100644 index 0000000..54d06fe --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_gcc.h @@ -0,0 +1,87 @@ +/* + * + * (C) COPYRIGHT 2009-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_TYPES_GCC_H_ +#define _ARM_CSTD_TYPES_GCC_H_ + +/* ============================================================================ + Type definitions +============================================================================ */ +/* All modern versions of GCC support stdint outside of C99 Mode. */ +/* However, Linux kernel limits what headers are available! */ +#if 1 == CSTD_OS_LINUX_KERNEL + #include + #include + #include + #include + + /* Fix up any types which CSTD provdes but which Linux is missing. */ + /* Note Linux assumes pointers are "long", so this is safe. */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + typedef unsigned long uintptr_t; + #endif + typedef long intptr_t; + +#else + #include + #include + #include +#endif + +typedef uint32_t bool_t; + +#if !defined(TRUE) + #define TRUE ((bool_t)1) +#endif + +#if !defined(FALSE) + #define FALSE ((bool_t)0) +#endif + +/* ============================================================================ + Keywords +============================================================================ */ +/* Doxygen documentation for these is in the RVCT header. */ +#define ASM __asm__ + +#define INLINE __inline__ + +#define FORCE_INLINE __attribute__((__always_inline__)) __inline__ + +#define NEVER_INLINE __attribute__((__noinline__)) + +#define PURE __attribute__((__pure__)) + +#define PACKED __attribute__((__packed__)) + +/* GCC does not support pointers to UNALIGNED data, so we do not define it to + * force a compile error if this macro is used. */ + +#define RESTRICT __restrict__ + +/* RVCT in GCC mode does not support the CHECK_RESULT attribute. */ +#if 0 == CSTD_TOOLCHAIN_RVCT_GCC_MODE + #define CHECK_RESULT __attribute__((__warn_unused_result__)) +#else + #define CHECK_RESULT +#endif + +/* RVCT in GCC mode does not support the __func__ name outside of C99. */ +#if (0 == CSTD_TOOLCHAIN_RVCT_GCC_MODE) + #define CSTD_FUNC __func__ +#else + #define CSTD_FUNC __FUNCTION__ +#endif + +#endif /* End (_ARM_CSTD_TYPES_GCC_H_) */ diff --git a/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_rvct.h b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_rvct.h new file mode 100644 index 0000000..8bae4c2 --- /dev/null +++ b/exynos5/hal/include/malisw/arm_cstd/arm_cstd_types_rvct.h @@ -0,0 +1,187 @@ +/* + * + * (C) COPYRIGHT 2009-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _ARM_CSTD_TYPES_RVCT_H_ +#define _ARM_CSTD_TYPES_RVCT_H_ + +/* ============================================================================ + Type definitions +============================================================================ */ +#include +#include + +#if 199901L <= __STDC_VERSION__ + #include +#else + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + typedef unsigned int uint32_t; + typedef signed int int32_t; + typedef unsigned __int64 uint64_t; + typedef signed __int64 int64_t; + typedef ptrdiff_t intptr_t; + typedef size_t uintptr_t; +#endif + +typedef uint32_t bool_t; + +#if !defined(TRUE) + #define TRUE ((bool_t)1) +#endif + +#if !defined(FALSE) + #define FALSE ((bool_t)0) +#endif + +/* ============================================================================ + Keywords +============================================================================ */ +/** + * @addtogroup arm_cstd_coding_standard + * @{ + */ + +/** + * @def ASM + * @hideinitializer + * Mark an assembler block. Such blocks are often compiler specific, so often + * need to be surrounded in appropriate @c ifdef and @c endif blocks + * using the relevant @c CSTD_TOOLCHAIN macro. + */ +#define ASM __asm + +/** + * @def INLINE + * @hideinitializer + * Mark a definition as something which should be inlined. This is not always + * possible on a given compiler, and may be disabled at lower optimization + * levels. + */ +#define INLINE __inline + +/** + * @def FORCE_INLINE + * @hideinitializer + * Mark a definition as something which should be inlined. This provides a much + * stronger hint to the compiler than @c INLINE, and if supported should always + * result in an inlined function being emitted. If not supported this falls + * back to using the @c INLINE definition. + */ +#define FORCE_INLINE __forceinline + +/** + * @def NEVER_INLINE + * @hideinitializer + * Mark a definition as something which should not be inlined. This provides a + * stronger hint to the compiler than the function should not be inlined, + * bypassing any heuristic rules the compiler normally applies. If not + * supported by a toolchain this falls back to being an empty macro. + */ +#define NEVER_INLINE __declspec(noinline) + +/** + * @def PURE + * @hideinitializer + * Denotes that a function's return is only dependent on its inputs, enabling + * more efficient optimizations. Falls back to an empty macro if not supported. + */ +#define PURE __pure + +/** + * @def PACKED + * @hideinitializer + * Denotes that a structure should be stored in a packed form. This macro must + * be used in conjunction with the @c arm_cstd_pack_* headers for portability: + * + * @code + * #include + * + * struct PACKED myStruct { + * ... + * }; + * + * #include + * PACKED + * @endcode + */ +#define PACKED __packed + +/** + * @def UNALIGNED + * @hideinitializer + * Denotes that a pointer points to a buffer with lower alignment than the + * natural alignment required by the C standard. This should only be used + * in extreme cases, as the emitted code is normally more efficient if memory + * is aligned. + * + * @warning This is \b NON-PORTABLE. The GNU tools are anti-unaligned pointers + * and have no support for such a construction. + */ +#define UNALIGNED __packed + +/** + * @def RESTRICT + * @hideinitializer + * Denotes that a pointer does not overlap with any other points currently in + * scope, increasing the range of optimizations which can be performed by the + * compiler. + * + * @warning Specification of @c RESTRICT is a contract between the programmer + * and the compiler. If you place @c RESTICT on buffers which do actually + * overlap the behavior is undefined, and likely to vary at different + * optimization levels.! + */ +#define RESTRICT __restrict + +/** + * @def CHECK_RESULT + * @hideinitializer + * Function attribute which causes a warning to be emitted if the compiler's + * return value is not used by the caller. Compiles to an empty macro if + * there is no supported mechanism for this check in the underlying compiler. + * + * @note At the time of writing this is only supported by GCC. RVCT does not + * support this attribute, even in GCC mode, so engineers are encouraged to + * compile their code using GCC even if primarily working with another + * compiler. + * + * @code + * CHECK_RESULT int my_func( void ); + * @endcode + */ +#define CHECK_RESULT + +/** + * @def CSTD_FUNC + * Specify the @c CSTD_FUNC macro, a portable construct containing the name of + * the current function. On most compilers it is illegal to use this macro + * outside of a function scope. If not supported by the compiler we define + * @c CSTD_FUNC as an empty string. + * + * @warning Due to the implementation of this on most modern compilers this + * expands to a magically defined "static const" variable, not a constant + * string. This makes injecting @c CSTD_FUNC directly in to compile-time + * strings impossible, so if you want to make the function name part of a + * larger string you must use a printf-like function with a @c @%s template + * which is populated with @c CSTD_FUNC + */ +#define CSTD_FUNC __FUNCTION__ + +/** + * @} + */ + +#endif /* End (_ARM_CSTD_TYPES_RVCT_H_) */ diff --git a/exynos5/hal/include/malisw/mali_malisw.h b/exynos5/hal/include/malisw/mali_malisw.h new file mode 100644 index 0000000..c19f14f --- /dev/null +++ b/exynos5/hal/include/malisw/mali_malisw.h @@ -0,0 +1,237 @@ +/* + * + * (C) COPYRIGHT 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _MALISW_H_ +#define _MALISW_H_ + +#define MALI_MODULE_MALISW_MAJOR 2 +#define MALI_MODULE_MALISW_MINOR 4 + +/** + * @file mali_malisw.h + * Driver-wide include for common macros and types. + */ + +/** + * @defgroup malisw Mali software definitions and types + * @{ + */ + +#include + +#include "mali_stdtypes.h" +#include "mali_version_macros.h" + +/** @brief Gets the container object when given a pointer to a member of an object. */ +#define CONTAINER_OF(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type,member))) + +/** @brief Gets the number of elements of type s in a fixed length array of s */ +#define NELEMS(s) (sizeof(s)/sizeof((s)[0])) + +/** + * @brief The lesser of two values. + * May evaluate its arguments more than once. + * @see CSTD_MIN + */ +#define MIN(x,y) CSTD_MIN(x,y) + +/** + * @brief The greater of two values. + * May evaluate its arguments more than once. + * @see CSTD_MAX + */ +#define MAX(x,y) CSTD_MAX(x,y) + +/** + * @brief Clamp value x to within min and max inclusive + * May evaluate its arguments more than once. + * @see CSTD_CLAMP + */ +#define CLAMP( x, min, max ) CSTD_CLAMP( x, min, max ) + +/** + * @brief Convert a pointer into a u64 for storing in a data structure. + * This is commonly used when pairing a 32-bit CPU with a 64-bit peripheral, + * such as a Midgard GPU. C's type promotion is complex and a straight cast + * does not work reliably as pointers are often considered as signed. + */ +#define PTR_TO_U64( x ) CSTD_PTR_TO_U64( x ) + +/** + * @name Mali library linkage specifiers + * These directly map to the cstd versions described in detail here: @ref arm_cstd_linkage_specifiers + * @{ + */ +#define MALI_IMPORT CSTD_LINK_IMPORT +#define MALI_EXPORT CSTD_LINK_EXPORT +#define MALI_IMPL CSTD_LINK_IMPL +#define MALI_LOCAL CSTD_LINK_LOCAL + +/** @brief Decorate exported function prototypes. + * + * The file containing the implementation of the function should define this to be MALI_EXPORT before including + * malisw/mali_malisw.h. + */ +#ifndef MALI_API +#define MALI_API MALI_IMPORT +#endif +/** @} */ + +/** @name Testable static functions + * @{ + * + * These macros can be used to allow functions to be static in release builds but exported from a shared library in unit + * test builds, allowing them to be tested or used to assist testing. + * + * Example mali_foo_bar.c containing the function to test: + * + * @code + * #define MALI_API MALI_EXPORT + * + * #include + * #include "mali_foo_testable_statics.h" + * + * MALI_TESTABLE_STATIC_IMPL void my_func() + * { + * //Implementation + * } + * @endcode + * + * Example mali_foo_testable_statics.h: + * + * @code + * #if 1 == MALI_UNIT_TEST + * #include + * + * MALI_TESTABLE_STATIC_API void my_func(); + * + * #endif + * @endcode + * + * Example mali_foo_tests.c: + * + * @code + * #include + * + * void my_test_func() + * { + * my_func(); + * } + * @endcode + */ + +/** @brief Decorate testable static function implementations. + * + * A header file containing a MALI_TESTABLE_STATIC_API-decorated prototype for each static function will be required + * when MALI_UNIT_TEST == 1 in order to link the function from the test. + */ +#if 1 == MALI_UNIT_TEST +#define MALI_TESTABLE_STATIC_IMPL MALI_IMPL +#else +#define MALI_TESTABLE_STATIC_IMPL static +#endif + +/** @brief Decorate testable static function prototypes. + * + * @note Prototypes should @em only be declared when MALI_UNIT_TEST == 1 + */ +#define MALI_TESTABLE_STATIC_API MALI_API +/** @} */ + +/** @name Testable local functions + * @{ + * + * These macros can be used to allow functions to be local to a shared library in release builds but be exported in unit + * test builds, allowing them to be tested or used to assist testing. + * + * Example mali_foo_bar.c containing the function to test: + * + * @code + * #define MALI_API MALI_EXPORT + * + * #include + * #include "mali_foo_bar.h" + * + * MALI_TESTABLE_LOCAL_IMPL void my_func() + * { + * //Implementation + * } + * @endcode + * + * Example mali_foo_bar.h: + * + * @code + * #include + * + * MALI_TESTABLE_LOCAL_API void my_func(); + * + * @endcode + * + * Example mali_foo_tests.c: + * + * @code + * #include + * + * void my_test_func() + * { + * my_func(); + * } + * @endcode + */ + +/** @brief Decorate testable local function implementations. + * + * This can be used to have a function normally local to the shared library except in unit test builds where it will be + * exported. + */ +#if 1 == MALI_UNIT_TEST +#define MALI_TESTABLE_LOCAL_IMPL MALI_IMPL +#else +#define MALI_TESTABLE_LOCAL_IMPL MALI_LOCAL +#endif + +/** @brief Decorate testable local function prototypes. + * + * This can be used to have a function normally local to the shared library except in unit test builds where it will be + * exported. + */ +#if 1 == MALI_UNIT_TEST +#define MALI_TESTABLE_LOCAL_API MALI_API +#else +#define MALI_TESTABLE_LOCAL_API MALI_LOCAL +#endif +/** @} */ + +/** + * Flag a cast as a reinterpretation, usually of a pointer type. + * @see CSTD_REINTERPRET_CAST + */ +#define REINTERPRET_CAST(type) CSTD_REINTERPRET_CAST(type) + +/** + * Flag a cast as casting away const, usually of a pointer type. + * @see CSTD_CONST_CAST + */ +#define CONST_CAST(type) (type) CSTD_CONST_CAST(type) + +/** + * Flag a cast as a (potentially complex) value conversion, usually of a numerical type. + * @see CSTD_STATIC_CAST + */ +#define STATIC_CAST(type) (type) CSTD_STATIC_CAST(type) + + +/** @} */ + +#endif /* _MALISW_H_ */ diff --git a/exynos5/hal/include/malisw/mali_stdtypes.h b/exynos5/hal/include/malisw/mali_stdtypes.h new file mode 100644 index 0000000..545c085 --- /dev/null +++ b/exynos5/hal/include/malisw/mali_stdtypes.h @@ -0,0 +1,210 @@ +/* + * + * (C) COPYRIGHT 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _MALISW_STDTYPES_H_ +#define _MALISW_STDTYPES_H_ + +/** + * @file mali_stdtypes.h + * This file defines the standard types used by the Mali codebase. + */ + +/** + * @addtogroup malisw + * @{ + */ + +/** + * @defgroup malisw_stdtypes Mali software standard types + * + * Basic driver-wide types. + */ + +/** + * @addtogroup malisw_stdtypes + * @{ + */ + +#include "arm_cstd/arm_cstd.h" + +/** + * @name Scalar types. + * These are the scalar types used within the mali driver. + * @{ + */ +/* Note: if compiling the Linux kernel then avoid redefining these. */ +#if 0 == CSTD_OS_LINUX_KERNEL + typedef uint64_t u64; + typedef uint32_t u32; + typedef uint16_t u16; + typedef uint8_t u8; + + typedef int64_t s64; + typedef int32_t s32; + typedef int16_t s16; + typedef int8_t s8; +#endif + +typedef double f64; +typedef float f32; +typedef u16 f16; + +typedef u32 mali_fixed16_16; +/* @} */ + +/** + * @name Boolean types. + * The intended use is for bool8 to be used when storing boolean values in + * structures, casting to mali_bool to be used in code sections. + * @{ + */ +typedef bool_t mali_bool; +typedef u8 mali_bool8; + +#define MALI_FALSE FALSE +#define MALI_TRUE TRUE +/* @} */ + +/** + * @name Integer bounding values + * Maximum and minimum values for integer types + * @{ + */ +#define U64_MAX UINT64_MAX +#define U32_MAX UINT32_MAX +#define U16_MAX UINT16_MAX +#define U8_MAX UINT8_MAX + +#define S64_MAX INT64_MAX +#define S64_MIN INT64_MIN +#define S32_MAX INT32_MAX +#define S32_MIN INT32_MIN +#define S16_MAX INT16_MAX +#define S16_MIN INT16_MIN +#define S8_MAX INT8_MAX +#define S8_MIN INT8_MIN +/* @} */ + +/** + * @name GPU address types + * Types for integers which hold a GPU pointer or GPU pointer offsets. + * @{ + */ +typedef u64 mali_addr64; +typedef u32 mali_addr32; +typedef u64 mali_size64; +typedef s64 mali_offset64; +/* 32 bit offsets and sizes are always for native types and so use ptrdiff_t and size_t respectively */ +/* @} */ + +/** + * @name Mali error types + * @brief The common error type for the mali drivers + * The mali_error type, all driver error handling should be of this type unless + * it must deal with a specific APIs error type. + * @{ + */ +typedef enum +{ + /** + * @brief Common Mali errors for the entire driver + * MALI_ERROR_NONE is guaranteed to be 0. + * @{ + */ + MALI_ERROR_NONE = 0, + MALI_ERROR_OUT_OF_GPU_MEMORY, + MALI_ERROR_OUT_OF_MEMORY, + MALI_ERROR_FUNCTION_FAILED, + /* @} */ + /** + * @brief Mali errors for Client APIs to pass to EGL when creating EGLImages + * These errors must only be returned to EGL from one of the Client APIs as part of the + * (clientapi)_egl_image_interface.h + * @{ + */ + MALI_ERROR_EGLP_BAD_ACCESS, + MALI_ERROR_EGLP_BAD_PARAMETER, + /* @} */ + /** + * @brief Mali errors for the MCL module. + * These errors must only be used within the private components of the OpenCL implementation that report + * directly to API functions for cases where errors cannot be detected in the entrypoints file. They must + * not be passed between driver components. + * These are errors in the mali error space specifically for the MCL module, hence the MCLP prefix. + * @{ + */ + MALI_ERROR_MCLP_DEVICE_NOT_FOUND, + MALI_ERROR_MCLP_DEVICE_NOT_AVAILABLE, + MALI_ERROR_MCLP_COMPILER_NOT_AVAILABLE, + MALI_ERROR_MCLP_MEM_OBJECT_ALLOCATION_FAILURE, + MALI_ERROR_MCLP_PROFILING_INFO_NOT_AVAILABLE, + MALI_ERROR_MCLP_MEM_COPY_OVERLAP, + MALI_ERROR_MCLP_IMAGE_FORMAT_MISMATCH, + MALI_ERROR_MCLP_IMAGE_FORMAT_NOT_SUPPORTED, + MALI_ERROR_MCLP_BUILD_PROGRAM_FAILURE, + MALI_ERROR_MCLP_MAP_FAILURE, + MALI_ERROR_MCLP_MISALIGNED_SUB_BUFFER_OFFSET, + MALI_ERROR_MCLP_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST, + MALI_ERROR_MCLP_INVALID_VALUE, + MALI_ERROR_MCLP_INVALID_DEVICE_TYPE, + MALI_ERROR_MCLP_INVALID_PLATFORM, + MALI_ERROR_MCLP_INVALID_DEVICE, + MALI_ERROR_MCLP_INVALID_CONTEXT, + MALI_ERROR_MCLP_INVALID_QUEUE_PROPERTIES, + MALI_ERROR_MCLP_INVALID_COMMAND_QUEUE, + MALI_ERROR_MCLP_INVALID_HOST_PTR, + MALI_ERROR_MCLP_INVALID_MEM_OBJECT, + MALI_ERROR_MCLP_INVALID_IMAGE_FORMAT_DESCRIPTOR, + MALI_ERROR_MCLP_INVALID_IMAGE_SIZE, + MALI_ERROR_MCLP_INVALID_SAMPLER, + MALI_ERROR_MCLP_INVALID_BINARY, + MALI_ERROR_MCLP_INVALID_BUILD_OPTIONS, + MALI_ERROR_MCLP_INVALID_PROGRAM, + MALI_ERROR_MCLP_INVALID_PROGRAM_EXECUTABLE, + MALI_ERROR_MCLP_INVALID_KERNEL_NAME, + MALI_ERROR_MCLP_INVALID_KERNEL_DEFINITION, + MALI_ERROR_MCLP_INVALID_KERNEL, + MALI_ERROR_MCLP_INVALID_ARG_INDEX, + MALI_ERROR_MCLP_INVALID_ARG_VALUE, + MALI_ERROR_MCLP_INVALID_ARG_SIZE, + MALI_ERROR_MCLP_INVALID_KERNEL_ARGS, + MALI_ERROR_MCLP_INVALID_WORK_DIMENSION, + MALI_ERROR_MCLP_INVALID_WORK_GROUP_SIZE, + MALI_ERROR_MCLP_INVALID_WORK_ITEM_SIZE, + MALI_ERROR_MCLP_INVALID_GLOBAL_OFFSET, + MALI_ERROR_MCLP_INVALID_EVENT_WAIT_LIST, + MALI_ERROR_MCLP_INVALID_EVENT, + MALI_ERROR_MCLP_INVALID_OPERATION, + MALI_ERROR_MCLP_INVALID_GL_OBJECT, + MALI_ERROR_MCLP_INVALID_BUFFER_SIZE, + MALI_ERROR_MCLP_INVALID_MIP_LEVEL, + MALI_ERROR_MCLP_INVALID_GLOBAL_WORK_SIZE, + /* @} */ + /** + * @brief Mali errors for the BASE module + * These errors must only be used within the private components of the Base implementation. They will not + * passed to other modules by the base driver. + * These are errors in the mali error space specifically for the BASE module, hence the BASEP prefix. + * @{ + */ + MALI_ERROR_BASEP_INVALID_FUNCTION + /* @} */ +} mali_error; +/* @} */ + +/* @} */ + +/* @} */ + +#endif /* _MALISW_STDTYPES_H_ */ diff --git a/exynos5/hal/include/malisw/mali_version_macros.h b/exynos5/hal/include/malisw/mali_version_macros.h new file mode 100644 index 0000000..e7dc43e --- /dev/null +++ b/exynos5/hal/include/malisw/mali_version_macros.h @@ -0,0 +1,243 @@ +/* + * + * (C) COPYRIGHT 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +#ifndef _MALISW_VERSION_MACROS_H_ +#define _MALISW_VERSION_MACROS_H_ + +/** + * @file mali_version_macros.h + * Mali version control macros. + */ + +/** + * @addtogroup malisw + * @{ + */ + +/** + * @defgroup malisw_version Mali module version control + * + * This file provides a set of macros used to check a module's version. This + * version information can be used to perform compile time checks of a module's + * suitability for use with another. + * + * Module versions have both a Major and Minor value which specify the version + * of the interface only. These are defined in the following way: + * + * @li Major: This version is incremented whenever a compatibility-breaking + * change is made. For example, removing an interface function. + * @li Minor: This version is incremented whenever an interface change is made + * that does not break compatibility. For example, adding a new function to the + * interface. This value is reset to zero whenever the major number is + * incremented. + * + * When providing a driver module that will be used with this system, the public + * header must include a major and minor define of the following form: + * + * @code + * #define MALI_MODULE__MAJOR X + * #define MALI_MODULE__MINOR Y + * @endcode + * e.g. for a module CZAM with include czam/mali_czam.h + * @code + * + * #define MALI_MODULE_CZAM_MAJOR 1 + * #define MALI_MODULE_CZAM_MINOR 0 + * @endcode + * + * The version assertion macros outlined below are wrapped with a static function. + * This provides more useful error messages when the assertions fail, and allows + * the assertions to be specified adjacent to the inclusion of the module header. + * + * These macros should be used in the global scope of the file. Normal use would be: + * + * @code + * #include + * #include + * #include + * #include + * + * // This module added an enum we needed on minor 4 of major release 2 + * MALI_MODULE_ASSERT_MAJOR_EQUALS_MINOR_AT_LEAST( MODULEW, 2, 4 ) + * + * // this module really needs to be a specific version + * MALI_MODULE_ASSERT_EQUALS( MODULEX, 2, 0 ) + * + * // 1.4 has performance problems + * MALI_MODULE_ASSERT_MAXIMUM( MODULEY, 1, 3 ) + * + * // Major defines a backward compatible series of versions + * MALI_MODULE_ASSERT_MAJOR_EQUALS( MODULEZ, 1 ) + * @endcode + * + * @par Version Assertions + * + * This module provides the following compile time version assertion macros. + * + * @li #MALI_MODULE_ASSERT_MAJOR_EQUALS_MINOR_AT_LEAST + * @li #MALI_MODULE_ASSERT_MAJOR_EQUALS + * @li #MALI_MODULE_ASSERT_EQUALS + * @li #MALI_MODULE_ASSERT_MINIMUM + * @li #MALI_MODULE_ASSERT_MAXIMUM + * + * @par Limitations + * + * To allow the macros to be placed in the global scope and report more readable + * errors, they produce a static function. This makes them unsuitable for use + * within headers as the names are only unique on the name of the module under test, + * the line number of the current file, and assert type (min, max, equals, ...). + */ + +/** + * @addtogroup malisw_version + * @{ + */ + +#include "arm_cstd/arm_cstd.h" + +/** + * Private helper macro, indirection so that __LINE__ resolves correctly. + */ +#define MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE2( module, type, line ) \ + static INLINE void _mali_module_##module##_version_check_##type##_##line(void) + +#define MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, type, line ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE2( module, type, line ) + +/** + * @hideinitializer + * This macro provides a compile time assert that a module interface that has been + * @#included in the source base has is greater than or equal to the version specified. + * + * Expected use is for cases where a module version before the requested minimum + * does not support a specific function or is missing an enum affecting the code that is + * importing the module. + * + * It should be invoked at the global scope and ideally following straight after + * the module header has been included. For example: + * + * @code + * #include + * + * MALI_MODULE_ASSERT_MINIMUM( MODULEX, 1, 3 ) + * @endcode + */ +#define MALI_MODULE_ASSERT_MINIMUM( module, major, minor ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, minimum, __LINE__ ) \ + { \ + CSTD_COMPILE_TIME_ASSERT( ( ( MALI_MODULE_##module##_MAJOR << 16 ) | MALI_MODULE_##module##_MINOR ) \ + >= ( ( (major) << 16 ) | (minor) ) ); \ + } + +/** + * @hideinitializer + * This macro provides a compile time assert that a module interface that has been + * @#included in the source base is less than or equal to the version specified. + * + * Expected use is for cases where a later published minor version is found to be + * incompatible in some way after the new minor has been issued. + * + * It should be invoked at the global scope and ideally following straight after + * the module header has been included. For example: + * + * @code + * #include + * + * MALI_MODULE_ASSERT_MAXIMUM( MODULEX, 1, 3 ) + * @endcode + */ +#define MALI_MODULE_ASSERT_MAXIMUM( module, major, minor ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, maximum, __LINE__ ) \ + { \ + CSTD_COMPILE_TIME_ASSERT( ( ( MALI_MODULE_##module##_MAJOR << 16 ) | MALI_MODULE_##module##_MINOR ) \ + <= ( ( (major) << 16 ) | (minor) ) ); \ + } + +/** + * @hideinitializer + * This macro provides a compile time assert that a module interface that has been + * @#included in the source base is equal to the version specified. + * + * Expected use is for cases where a specific version is known to work and other + * versions are considered to be risky. + * + * It should be invoked at the global scope and ideally following straight after + * the module header has been included. For example: + * + * @code + * #include + * + * MALI_MODULE_ASSERT_EQUALS( MODULEX, 1, 3 ) + * @endcode + */ +#define MALI_MODULE_ASSERT_EQUALS( module, major, minor ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, equals, __LINE__ ) \ + { \ + CSTD_COMPILE_TIME_ASSERT( MALI_MODULE_##module##_MAJOR == major ); \ + CSTD_COMPILE_TIME_ASSERT( MALI_MODULE_##module##_MINOR == minor ); \ + } + +/** + * @hideinitializer + * This macro provides a compile time assert that a module interface that has been + * @#included in the source base has a major version equal to the major version specified. + * + * Expected use is for cases where a module is considered low risk and any minor changes + * are not considered to be important. + * + * It should be invoked at the global scope and ideally following straight after + * the module header has been included. For example: + * + * @code + * #include + * + * MALI_MODULE_ASSERT_MAJOR_EQUALS( MODULEX, 1, 3 ) + * @endcode + */ +#define MALI_MODULE_ASSERT_MAJOR_EQUALS( module, major ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, major_equals, __LINE__ ) \ + { \ + CSTD_COMPILE_TIME_ASSERT( MALI_MODULE_##module##_MAJOR == major ); \ + } + +/** + * @hideinitializer + * This macro provides a compile time assert that a module interface that has been + * @#included in the source base has a major version equal to the major version specified + * and that the minor version is at least that which is specified. + * + * Expected use is for cases where a major revision is suitable from a specific minor + * revision but future major versions are a risk. + * + * It should be invoked at the global scope and ideally following straight after + * the module header has been included. For example: + * + * @code + * #include + * + * MALI_MODULE_ASSERT_MAJOR_EQUALS_MINOR_AT_LEAST( MODULEX, 1, 3 ) + * @endcode + */ +#define MALI_MODULE_ASSERT_MAJOR_EQUALS_MINOR_AT_LEAST( module, major, minor ) \ + MALIP_MODULE_ASSERT_FUNCTION_SIGNATURE( module, major_equals_minor_at_least, __LINE__ ) \ + { \ + CSTD_COMPILE_TIME_ASSERT( MALI_MODULE_##module##_MAJOR == major ); \ + CSTD_COMPILE_TIME_ASSERT( MALI_MODULE_##module##_MINOR >= minor ); \ + } + +/* @} */ + +/* @} */ + +#endif /* _MALISW_VERSION_MACROS_H_ */ diff --git a/exynos5/hal/include/media.h b/exynos5/hal/include/media.h new file mode 100644 index 0000000..0ef8833 --- /dev/null +++ b/exynos5/hal/include/media.h @@ -0,0 +1,132 @@ +/* + * Multimedia device API + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_MEDIA_H +#define __LINUX_MEDIA_H + +#include +#include +#include + +#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) + +struct media_device_info { + char driver[16]; + char model[32]; + char serial[40]; + char bus_info[32]; + __u32 media_version; + __u32 hw_revision; + __u32 driver_version; + __u32 reserved[31]; +}; + +#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) + +#define MEDIA_ENT_TYPE_SHIFT 16 +#define MEDIA_ENT_TYPE_MASK 0x00ff0000 +#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff + +#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) +#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) +#define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) +#define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) + +#define MEDIA_ENT_FL_DEFAULT (1 << 0) + +struct media_entity_desc { + __u32 id; + char name[32]; + __u32 type; + __u32 revision; + __u32 flags; + __u32 group_id; + __u16 pads; + __u16 links; + + __u32 reserved[4]; + + union { + /* Node specifications */ + struct { + __u32 major; + __u32 minor; + } v4l; + struct { + __u32 major; + __u32 minor; + } fb; + struct { + __u32 card; + __u32 device; + __u32 subdevice; + } alsa; + int dvb; + + /* Sub-device specifications */ + /* Nothing needed yet */ + __u8 raw[184]; + }; +}; + +#define MEDIA_PAD_FL_SINK (1 << 0) +#define MEDIA_PAD_FL_SOURCE (1 << 1) + +struct media_pad_desc { + __u32 entity; /* entity ID */ + __u16 index; /* pad index */ + __u32 flags; /* pad flags */ + __u32 reserved[2]; +}; + +#define MEDIA_LNK_FL_ENABLED (1 << 0) +#define MEDIA_LNK_FL_IMMUTABLE (1 << 1) +#define MEDIA_LNK_FL_DYNAMIC (1 << 2) + +struct media_link_desc { + struct media_pad_desc source; + struct media_pad_desc sink; + __u32 flags; + __u32 reserved[2]; +}; + +struct media_links_enum { + __u32 entity; + /* Should have enough room for pads elements */ + struct media_pad_desc __user *pads; + /* Should have enough room for links elements */ + struct media_link_desc __user *links; + __u32 reserved[4]; +}; + +#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) +#define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) +#define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) +#define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) + +#endif /* __LINUX_MEDIA_H */ diff --git a/exynos5/hal/include/s3c_lcd.h b/exynos5/hal/include/s3c_lcd.h new file mode 100644 index 0000000..22ebf86 --- /dev/null +++ b/exynos5/hal/include/s3c_lcd.h @@ -0,0 +1,83 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _S3CFB_LCD_ +#define _S3CFB_LCD_ + +/* + * S T R U C T U R E S F O R C U S T O M I O C T L S + * +*/ +struct s3cfb_user_window { + int x; + int y; +}; + +struct s3cfb_user_plane_alpha { + int channel; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +struct s3cfb_user_chroma { + int enabled; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +typedef struct { + unsigned int phy_start_addr; + unsigned int xres; /* visible resolution*/ + unsigned int yres; + unsigned int xres_virtual; /* virtual resolution*/ + unsigned int yres_virtual; + unsigned int xoffset; /* offset from virtual to visible */ + unsigned int yoffset; /* resolution */ + unsigned int lcd_offset_x; + unsigned int lcd_offset_y; +} s3c_fb_next_info_t; + +struct s3c_fb_user_ion_client { + int fd; +}; + +/* + * C U S T O M I O C T L S + * +*/ + +#define S3CFB_WIN_POSITION _IOW ('F', 203, struct s3cfb_user_window) +#define S3CFB_WIN_SET_PLANE_ALPHA _IOW ('F', 204, struct s3cfb_user_plane_alpha) +#define S3CFB_WIN_SET_CHROMA _IOW ('F', 205, struct s3cfb_user_chroma) +#define S3CFB_SET_VSYNC_INT _IOW ('F', 206, unsigned int) +#define S3CFB_SET_SUSPEND_FIFO _IOW ('F', 300, unsigned long) +#define S3CFB_SET_RESUME_FIFO _IOW ('F', 301, unsigned long) +#define S3CFB_GET_LCD_WIDTH _IOR ('F', 302, int) +#define S3CFB_GET_LCD_HEIGHT _IOR ('F', 303, int) +#define S3CFB_GET_FB_PHY_ADDR _IOR ('F', 310, unsigned int) +#define S3C_FB_GET_CURR_FB_INFO _IOR ('F', 305, s3c_fb_next_info_t) +#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, struct s3c_fb_user_ion_client) + +/***************** LCD frame buffer *****************/ +#define FB0_NAME "/dev/fb0" +#define FB1_NAME "/dev/fb1" +#define FB2_NAME "/dev/fb2" +#define FB3_NAME "/dev/fb3" +#define FB4_NAME "/dev/fb4" + +#endif diff --git a/exynos5/hal/include/s3c_mem.h b/exynos5/hal/include/s3c_mem.h new file mode 100644 index 0000000..dd4cbdb --- /dev/null +++ b/exynos5/hal/include/s3c_mem.h @@ -0,0 +1,48 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _S3C_MEM_COMMON_H_ +#define _S3C_MEM_COMMON_H_ + +#define MEM_IOCTL_MAGIC 'M' + +#define S3C_MEM_ALLOC _IOWR(MEM_IOCTL_MAGIC, 310, struct s3c_mem_alloc) +#define S3C_MEM_FREE _IOWR(MEM_IOCTL_MAGIC, 311, struct s3c_mem_alloc) + +#define S3C_MEM_SHARE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 314, struct s3c_mem_alloc) +#define S3C_MEM_SHARE_FREE _IOWR(MEM_IOCTL_MAGIC, 315, struct s3c_mem_alloc) + +#define S3C_MEM_CACHEABLE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 316, struct s3c_mem_alloc) +#define S3C_MEM_CACHEABLE_SHARE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 317, struct s3c_mem_alloc) + +#define S3C_MEM_CACHE_FLUSH _IOWR(MEM_IOCTL_MAGIC, 318, struct s3c_mem_alloc) +#define S3C_MEM_CACHE_INVAL _IOWR(MEM_IOCTL_MAGIC, 319, struct s3c_mem_alloc) +#define S3C_MEM_CACHE_CLEAN _IOWR(MEM_IOCTL_MAGIC, 320, struct s3c_mem_alloc) + +struct s3c_mem_alloc { + int size; + unsigned int vir_addr; + unsigned int phy_addr; +}; + +struct s3c_mem_dma_param { + int size; + unsigned int src_addr; + unsigned int dst_addr; + int cfg; +}; + +#endif // _S3C_MEM_COMMON_H_ diff --git a/exynos5/hal/include/s5p_fimc.h b/exynos5/hal/include/s5p_fimc.h new file mode 100644 index 0000000..d41fee1 --- /dev/null +++ b/exynos5/hal/include/s5p_fimc.h @@ -0,0 +1,160 @@ +/* Copyright(c) 2011 Samsung Electronics Co, Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _S5P_FIMC_H_ +#define _S5P_FIMC_H_ + +#include +#include "SecBuffer.h" +/* + * G E N E R A L S + * +*/ +#define MIN(x, y) ((x < y) ? x : y) + +/* + * P I X E L F O R M A T G U I D E + * + * The 'x' means 'DO NOT CARE' + * The '*' means 'FIMC SPECIFIC' + * For some fimc formats, we couldn't find equivalent format in the V4L2 FOURCC. + * + * FIMC TYPE PLANES ORDER V4L2_PIX_FMT + * --------------------------------------------------------- + * RGB565 x x V4L2_PIX_FMT_RGB565 + * RGB888 x x V4L2_PIX_FMT_RGB24 + * YUV420 2 LSB_CBCR V4L2_PIX_FMT_NV12 + * YUV420 2 LSB_CRCB V4L2_PIX_FMT_NV21 + * YUV420 2 MSB_CBCR V4L2_PIX_FMT_NV21X* + * YUV420 2 MSB_CRCB V4L2_PIX_FMT_NV12X* + * YUV420 3 x V4L2_PIX_FMT_YUV420 + * YUV422 1 YCBYCR V4L2_PIX_FMT_YUYV + * YUV422 1 YCRYCB V4L2_PIX_FMT_YVYU + * YUV422 1 CBYCRY V4L2_PIX_FMT_UYVY + * YUV422 1 CRYCBY V4L2_PIX_FMT_VYUY* + * YUV422 2 LSB_CBCR V4L2_PIX_FMT_NV16* + * YUV422 2 LSB_CRCB V4L2_PIX_FMT_NV61* + * YUV422 2 MSB_CBCR V4L2_PIX_FMT_NV16X* + * YUV422 2 MSB_CRCB V4L2_PIX_FMT_NV61X* + * YUV422 3 x V4L2_PIX_FMT_YUV422P + * +*/ + +/* + * V 4 L 2 F I M C E X T E N S I O N S + * +*/ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + +/* FOURCC for FIMC specific */ +#define V4L2_PIX_FMT_NV12X v4l2_fourcc('N', '1', '2', 'X') +#define V4L2_PIX_FMT_NV21X v4l2_fourcc('N', '2', '1', 'X') +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#define V4L2_PIX_FMT_NV16X v4l2_fourcc('N', '1', '6', 'X') +#define V4L2_PIX_FMT_NV61X v4l2_fourcc('N', '6', '1', 'X') + +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_GET_PHY_SRC_YADDR (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_GET_PHY_SRC_CADDR (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +/* + * U S E R D E F I N E D T Y P E S + * +*/ +#define FIMC1_RESERVED_SIZE 32768 + +enum fimc_overlay_mode { + FIMC_OVLY_NOT_FIXED = 0x0, /* Overlay mode isn't fixed. */ + FIMC_OVLY_FIFO = 0x1, /* Non-destructive Overlay with FIFO */ + FIMC_OVLY_DMA_AUTO = 0x2, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_DMA_MANUAL = 0x3, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_NONE_SINGLE_BUF = 0x4, /* Destructive Overlay with DMA single destination buffer */ + FIMC_OVLY_NONE_MULTI_BUF = 0x5, /* Destructive Overlay with DMA multiple dstination buffer */ +}; + +typedef unsigned int dma_addr_t; + +struct fimc_buf { + dma_addr_t base[3]; + size_t length[3]; +}; + +struct fimc_buffer { + void *virt_addr; + void *phys_addr; + size_t length; +}; + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int bpp; + int planes; +}; + +struct img_offset { + int y_h; + int y_v; + int cb_h; + int cb_v; + int cr_h; + int cr_v; +}; + +//------------ STRUCT ---------------------------------------------------------// + +typedef struct +{ + unsigned int full_width; // Source Image Full Width (Virtual screen size) + unsigned int full_height; // Source Image Full Height (Virtual screen size) + unsigned int start_x; // Source Image Start width offset + unsigned int start_y; // Source Image Start height offset + unsigned int width; // Source Image Width + unsigned int height; // Source Image Height + unsigned int buf_addr_phy_rgb_y; // Base Address of the Source Image (RGB or Y): Physical Address + unsigned int buf_addr_phy_cb; // Base Address of the Source Image (CB Component) : Physical Address + unsigned int buf_addr_phy_cr; // Base Address of the Source Image (CR Component) : Physical Address + unsigned int color_space; // Color Space of the Source Image +} s5p_fimc_img_info; + +typedef struct +{ + s5p_fimc_img_info src; + s5p_fimc_img_info dst; +} s5p_fimc_params_t; + +typedef struct _s5p_fimc_t { + int dev_fd; + struct fimc_buffer out_buf; + + s5p_fimc_params_t params; + + int use_ext_out_mem; +}s5p_fimc_t; + +#endif diff --git a/exynos5/hal/include/s5p_fimc_v4l2.h b/exynos5/hal/include/s5p_fimc_v4l2.h new file mode 100644 index 0000000..e69951d --- /dev/null +++ b/exynos5/hal/include/s5p_fimc_v4l2.h @@ -0,0 +1,162 @@ +/* Copyright(c) 2011 Samsung Electronics Co, Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _S5P_FIMC_H_ +#define _S5P_FIMC_H_ + +#include "videodev2.h" +#include "SecBuffer.h" + +/* + * G E N E R A L S + * +*/ + +/* + * P I X E L F O R M A T G U I D E + * + * The 'x' means 'DO NOT CARE' + * The '*' means 'FIMC SPECIFIC' + * For some fimc formats, we couldn't find equivalent format in the V4L2 FOURCC. + * + * FIMC TYPE PLANES ORDER V4L2_PIX_FMT + * --------------------------------------------------------- + * RGB565 x x V4L2_PIX_FMT_RGB565 + * RGB888 x x V4L2_PIX_FMT_RGB24 + * YUV420 2 LSB_CBCR V4L2_PIX_FMT_NV12 + * YUV420 2 LSB_CRCB V4L2_PIX_FMT_NV21 + * YUV420 2 MSB_CBCR V4L2_PIX_FMT_NV21X* + * YUV420 2 MSB_CRCB V4L2_PIX_FMT_NV12X* + * YUV420 3 x V4L2_PIX_FMT_YUV420 + * YUV422 1 YCBYCR V4L2_PIX_FMT_YUYV + * YUV422 1 YCRYCB V4L2_PIX_FMT_YVYU + * YUV422 1 CBYCRY V4L2_PIX_FMT_UYVY + * YUV422 1 CRYCBY V4L2_PIX_FMT_VYUY* + * YUV422 2 LSB_CBCR V4L2_PIX_FMT_NV16* + * YUV422 2 LSB_CRCB V4L2_PIX_FMT_NV61* + * YUV422 2 MSB_CBCR V4L2_PIX_FMT_NV16X* + * YUV422 2 MSB_CRCB V4L2_PIX_FMT_NV61X* + * YUV422 3 x V4L2_PIX_FMT_YUV422P + * +*/ + +/* + * V 4 L 2 F I M C E X T E N S I O N S + * +*/ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + +/* FOURCC for FIMC specific */ +#define V4L2_PIX_FMT_NV12X v4l2_fourcc('N', '1', '2', 'X') +#define V4L2_PIX_FMT_NV21X v4l2_fourcc('N', '2', '1', 'X') +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#define V4L2_PIX_FMT_NV16X v4l2_fourcc('N', '1', '6', 'X') +#define V4L2_PIX_FMT_NV61X v4l2_fourcc('N', '6', '1', 'X') + +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_GET_PHY_SRC_YADDR (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_GET_PHY_SRC_CADDR (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +/* + * U S E R D E F I N E D T Y P E S + * +*/ +#define FIMC1_RESERVED_SIZE 32768 + +enum fimc_overlay_mode { + FIMC_OVLY_NOT_FIXED = 0x0, /* Overlay mode isn't fixed. */ + FIMC_OVLY_FIFO = 0x1, /* Non-destructive Overlay with FIFO */ + FIMC_OVLY_DMA_AUTO = 0x2, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_DMA_MANUAL = 0x3, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_NONE_SINGLE_BUF = 0x4, /* Destructive Overlay with DMA single destination buffer */ + FIMC_OVLY_NONE_MULTI_BUF = 0x5, /* Destructive Overlay with DMA multiple dstination buffer */ +}; + +typedef unsigned int dma_addr_t; + +struct fimc_buf { + dma_addr_t base[3]; + size_t size[3]; + int planes; +}; + +struct fimc_buffer { + void *virt_addr; + void *phys_addr; + size_t length; +}; + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int bpp; + int planes; +}; + +struct img_offset { + int y_h; + int y_v; + int cb_h; + int cb_v; + int cr_h; + int cr_v; +}; + +//------------ STRUCT ---------------------------------------------------------// + +typedef struct +{ + unsigned int full_width; // Source Image Full Width (Virtual screen size) + unsigned int full_height; // Source Image Full Height (Virtual screen size) + unsigned int start_x; // Source Image Start width offset + unsigned int start_y; // Source Image Start height offset + unsigned int width; // Source Image Width + unsigned int height; // Source Image Height + unsigned int buf_addr_phy_rgb_y; // Base Address of the Source Image (RGB or Y): Physical Address + unsigned int buf_addr_phy_cb; // Base Address of the Source Image (CB Component) : Physical Address + unsigned int buf_addr_phy_cr; // Base Address of the Source Image (CR Component) : Physical Address + unsigned int color_space; // Color Space of the Source Image + unsigned int planes; // number of planes for the Image +} s5p_fimc_img_info; + +typedef struct +{ + s5p_fimc_img_info src; + s5p_fimc_img_info dst; +} s5p_fimc_params_t; + +typedef struct _s5p_fimc_t { + int dev_fd; + struct fimc_buffer out_buf; + + s5p_fimc_params_t params; + + int use_ext_out_mem; +} s5p_fimc_t; + +#endif diff --git a/exynos5/hal/include/s5p_tvout.h b/exynos5/hal/include/s5p_tvout.h new file mode 100644 index 0000000..fd31bec --- /dev/null +++ b/exynos5/hal/include/s5p_tvout.h @@ -0,0 +1,198 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __S5P_TVOUT_H__ +#define __S5P_TVOUT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************* + * Define + *******************************************/ +/* TVOUT control */ +#ifdef SAMSUNG_EXYNOS4210 +#define TVOUT_DEV "/dev/video14" +#else +#define TVOUT_DEV "/dev/video16" +#endif +#define HPD_DEV "/dev/HPD" + +/* ------------- Output -----------------*/ +/* type */ +#define V4L2_OUTPUT_TYPE_MSDMA 4 +#define V4L2_OUTPUT_TYPE_COMPOSITE 5 +#define V4L2_OUTPUT_TYPE_SVIDEO 6 +#define V4L2_OUTPUT_TYPE_YPBPR_INERLACED 7 +#define V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE 8 +#define V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE 9 +#define V4L2_OUTPUT_TYPE_DIGITAL 10 +#define V4L2_OUTPUT_TYPE_HDMI V4L2_OUTPUT_TYPE_DIGITAL +#define V4L2_OUTPUT_TYPE_HDMI_RGB 11 +#define V4L2_OUTPUT_TYPE_DVI 12 + +/* ------------- STD -------------------*/ +#define V4L2_STD_PAL_BDGHI\ + (V4L2_STD_PAL_B|V4L2_STD_PAL_D|V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_PAL_I) + +#define V4L2_STD_480P_60_16_9 ((v4l2_std_id)0x04000000) +#define V4L2_STD_480P_60_4_3 ((v4l2_std_id)0x05000000) +#define V4L2_STD_576P_50_16_9 ((v4l2_std_id)0x06000000) +#define V4L2_STD_576P_50_4_3 ((v4l2_std_id)0x07000000) +#define V4L2_STD_720P_60 ((v4l2_std_id)0x08000000) +#define V4L2_STD_720P_50 ((v4l2_std_id)0x09000000) +#define V4L2_STD_1080P_60 ((v4l2_std_id)0x0a000000) +#define V4L2_STD_1080P_50 ((v4l2_std_id)0x0b000000) +#define V4L2_STD_1080I_60 ((v4l2_std_id)0x0c000000) +#define V4L2_STD_1080I_50 ((v4l2_std_id)0x0d000000) +#define V4L2_STD_480P_59 ((v4l2_std_id)0x0e000000) +#define V4L2_STD_720P_59 ((v4l2_std_id)0x0f000000) +#define V4L2_STD_1080I_59 ((v4l2_std_id)0x10000000) +#define V4L2_STD_1080P_59 ((v4l2_std_id)0x11000000) +#define V4L2_STD_1080P_30 ((v4l2_std_id)0x12000000) +#define V4L2_STD_TVOUT_720P_60_SBS_HALF ((v4l2_std_id)0x13000000) +#define V4L2_STD_TVOUT_720P_59_SBS_HALF ((v4l2_std_id)0x14000000) +#define V4L2_STD_TVOUT_720P_50_TB ((v4l2_std_id)0x15000000) +#define V4L2_STD_TVOUT_1080P_24_TB ((v4l2_std_id)0x16000000) +#define V4L2_STD_TVOUT_1080P_23_TB ((v4l2_std_id)0x17000000) + +/* TVOUT video */ +#ifdef SAMSUNG_EXYNOS4210 +#define TVOUT_DEV_V "/dev/video21" +#else +#define TVOUT_DEV_V "/dev/video20" +#endif + +/* ------------- Input ------------------*/ +/* type */ +#define V4L2_INPUT_TYPE_MSDMA 3 +#define V4L2_INPUT_TYPE_FIFO 4 + +/* TVOUT video */ +#define PFX_NODE_FB "/dev/graphics/fb" + +/******************************************* + * structures + *******************************************/ + +/* TVOUT */ +struct v4l2_vid_overlay_src { + void *base_y; + void *base_c; + struct v4l2_pix_format pix_fmt; +}; + +struct v4l2_window_s5p_tvout { + __u32 capability; + __u32 flags; + __u32 priority; + struct v4l2_window win; +}; + +struct v4l2_pix_format_s5p_tvout { + void *base_y; + void *base_c; + __u32 src_img_endian; + struct v4l2_pix_format pix_fmt; +}; + +struct vid_overlay_param { + struct v4l2_vid_overlay_src src; + struct v4l2_rect src_crop; + struct v4l2_framebuffer dst; + struct v4l2_window dst_win; +}; + +struct tvout_param { + struct v4l2_pix_format_s5p_tvout tvout_src; + struct v4l2_window_s5p_tvout tvout_rect; + struct v4l2_rect tvout_dst; +}; + +struct overlay_param { + struct v4l2_framebuffer overlay_frame; + struct v4l2_window_s5p_tvout overlay_rect; + struct v4l2_rect overlay_dst; +}; + +/* FB */ +struct s5ptvfb_user_window { + int x; + int y; +}; + +struct s5ptvfb_user_plane_alpha { + int channel; + unsigned char alpha; +}; + +struct s5ptvfb_user_chroma { + int enabled; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +enum s5ptvfb_ver_scaling_t { + VERTICAL_X1, + VERTICAL_X2, +}; + +enum s5ptvfb_hor_scaling_t { + HORIZONTAL_X1, + HORIZONTAL_X2, +}; + +struct s5ptvfb_user_scaling { + enum s5ptvfb_ver_scaling_t ver; + enum s5ptvfb_hor_scaling_t hor; +}; + +/******************************************* + * custom ioctls + *******************************************/ + +#define VIDIOC_S_BASEADDR _IOR('V', 83, int) + +#define VIDIOC_HDCP_ENABLE _IOWR('V', 100, unsigned int) +#define VIDIOC_HDCP_STATUS _IOR('V', 101, unsigned int) +#define VIDIOC_HDCP_PROT_STATUS _IOR('V', 102, unsigned int) + +#define VIDIOC_INIT_AUDIO _IOR('V', 103, unsigned int) +#define VIDIOC_AV_MUTE _IOR('V', 104, unsigned int) +#define VIDIOC_G_AVMUTE _IOR('V', 105, unsigned int) +#define HPD_GET_STATE _IOR('H', 100, unsigned int) + +#define S5PTVFB_WIN_POSITION _IOW('F', 213, struct s5ptvfb_user_window) +#define S5PTVFB_WIN_SET_PLANE_ALPHA _IOW('F', 214, struct s5ptvfb_user_plane_alpha) +#define S5PTVFB_WIN_SET_CHROMA _IOW('F', 215, struct s5ptvfb_user_chroma) + +#define S5PTVFB_SET_VSYNC_INT _IOW('F', 216, unsigned int) +#define S5PTVFB_WAITFORVSYNC _IO('F', 32) +#define S5PTVFB_WIN_SET_ADDR _IOW('F', 219, unsigned int) +#define S5PTVFB_SET_WIN_ON _IOW('F', 220, unsigned int) +#define S5PTVFB_SET_WIN_OFF _IOW('F', 221, unsigned int) +#define S5PTVFB_SCALING _IOW('F', 222, struct s5ptvfb_user_scaling) + +#ifdef __cplusplus +} +#endif + +#endif /* __S5P_TVOUT_H__ */ diff --git a/exynos5/hal/include/s5p_tvout_v4l2.h b/exynos5/hal/include/s5p_tvout_v4l2.h new file mode 100644 index 0000000..49ac288 --- /dev/null +++ b/exynos5/hal/include/s5p_tvout_v4l2.h @@ -0,0 +1,207 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __S5P_TVOUT_H__ +#define __S5P_TVOUT_H__ + +#include + +#include "videodev2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************* + * Define + *******************************************/ +/* TVOUT control */ +#define PFX_NODE_FB "/dev/graphics/fb" + +#define PFX_NODE_MEDIADEV "/dev/media" +#define PFX_NODE_SUBDEV "/dev/v4l-subdev" +#define PFX_NODE_VIDEODEV "/dev/video" +#define PFX_ENTITY_SUBDEV_MIXER "s5p-mixer%d" + +/* Sub-Mixer 0 */ +#define TVOUT0_DEV_G0 "/dev/video16" +#define TVOUT0_DEV_G1 "/dev/video17" +/* Sub-Mixer 1 */ +#define TVOUT1_DEV_G0 "/dev/video18" +#define TVOUT1_DEV_G1 "/dev/video19" + +#define MIXER_V_SUBDEV_PAD_SINK (0) +#define MIXER_V_SUBDEV_PAD_SOURCE (3) +#define MIXER_G0_SUBDEV_PAD_SINK (1) +#define MIXER_G0_SUBDEV_PAD_SOURCE (4) +#define MIXER_G1_SUBDEV_PAD_SINK (2) +#define MIXER_G1_SUBDEV_PAD_SOURCE (5) + +#define GSCALER_SUBDEV_PAD_SOURCE (1) + +#define HPD_DEV "/dev/HPD" + +/* ------------- Output -----------------*/ +/* type */ +#define V4L2_OUTPUT_TYPE_MSDMA 4 +#define V4L2_OUTPUT_TYPE_COMPOSITE 5 +#define V4L2_OUTPUT_TYPE_SVIDEO 6 +#define V4L2_OUTPUT_TYPE_YPBPR_INERLACED 7 +#define V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE 8 +#define V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE 9 +#define V4L2_OUTPUT_TYPE_DIGITAL 10 +#define V4L2_OUTPUT_TYPE_HDMI V4L2_OUTPUT_TYPE_DIGITAL +#define V4L2_OUTPUT_TYPE_HDMI_RGB 11 +#define V4L2_OUTPUT_TYPE_DVI 12 + +/* ------------- STD -------------------*/ +#define V4L2_STD_PAL_BDGHI\ + (V4L2_STD_PAL_B|V4L2_STD_PAL_D|V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_PAL_I) + +#define V4L2_STD_480P_60_16_9 ((v4l2_std_id)0x04000000) +#define V4L2_STD_480P_60_4_3 ((v4l2_std_id)0x05000000) +#define V4L2_STD_576P_50_16_9 ((v4l2_std_id)0x06000000) +#define V4L2_STD_576P_50_4_3 ((v4l2_std_id)0x07000000) +#define V4L2_STD_720P_60 ((v4l2_std_id)0x08000000) +#define V4L2_STD_720P_50 ((v4l2_std_id)0x09000000) +#define V4L2_STD_1080P_60 ((v4l2_std_id)0x0a000000) +#define V4L2_STD_1080P_50 ((v4l2_std_id)0x0b000000) +#define V4L2_STD_1080I_60 ((v4l2_std_id)0x0c000000) +#define V4L2_STD_1080I_50 ((v4l2_std_id)0x0d000000) +#define V4L2_STD_480P_59 ((v4l2_std_id)0x0e000000) +#define V4L2_STD_720P_59 ((v4l2_std_id)0x0f000000) +#define V4L2_STD_1080I_59 ((v4l2_std_id)0x10000000) +#define V4L2_STD_1080P_59 ((v4l2_std_id)0x11000000) +#define V4L2_STD_1080P_30 ((v4l2_std_id)0x12000000) +#define V4L2_STD_TVOUT_720P_60_SBS_HALF ((v4l2_std_id)0x13000000) +#define V4L2_STD_TVOUT_720P_59_SBS_HALF ((v4l2_std_id)0x14000000) +#define V4L2_STD_TVOUT_720P_50_TB ((v4l2_std_id)0x15000000) +#define V4L2_STD_TVOUT_1080P_24_TB ((v4l2_std_id)0x16000000) +#define V4L2_STD_TVOUT_1080P_23_TB ((v4l2_std_id)0x17000000) + +/* ------------- Input ------------------*/ +/* type */ +#define V4L2_INPUT_TYPE_MSDMA 3 +#define V4L2_INPUT_TYPE_FIFO 4 + +/******************************************* + * structures + *******************************************/ + +/* TVOUT */ +struct v4l2_vid_overlay_src { + void *base_y; + void *base_c; + struct v4l2_pix_format pix_fmt; +}; + +struct v4l2_window_s5p_tvout { + __u32 capability; + __u32 flags; + __u32 priority; + struct v4l2_window win; +}; + +struct v4l2_pix_format_s5p_tvout { + void *base_y; + void *base_c; + __u32 src_img_endian; + struct v4l2_pix_format pix_fmt; +}; + +struct vid_overlay_param { + struct v4l2_vid_overlay_src src; + struct v4l2_rect src_crop; + struct v4l2_framebuffer dst; + struct v4l2_window dst_win; +}; + +struct tvout_param { + struct v4l2_pix_format_s5p_tvout tvout_src; + struct v4l2_window_s5p_tvout tvout_rect; + struct v4l2_rect tvout_dst; +}; + +struct overlay_param { + struct v4l2_framebuffer overlay_frame; + struct v4l2_window_s5p_tvout overlay_rect; + struct v4l2_rect overlay_dst; +}; + +/* FB */ +struct s5ptvfb_user_window { + int x; + int y; +}; + +struct s5ptvfb_user_plane_alpha { + int channel; + unsigned char alpha; +}; + +struct s5ptvfb_user_chroma { + int enabled; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +enum s5ptvfb_ver_scaling_t { + VERTICAL_X1, + VERTICAL_X2, +}; + +enum s5ptvfb_hor_scaling_t { + HORIZONTAL_X1, + HORIZONTAL_X2, +}; + +struct s5ptvfb_user_scaling { + enum s5ptvfb_ver_scaling_t ver; + enum s5ptvfb_hor_scaling_t hor; +}; + +/******************************************* + * custom ioctls + *******************************************/ + +#define VIDIOC_S_BASEADDR _IOR('V', 83, int) + +#define VIDIOC_HDCP_ENABLE _IOWR('V', 100, unsigned int) +#define VIDIOC_HDCP_STATUS _IOR('V', 101, unsigned int) +#define VIDIOC_HDCP_PROT_STATUS _IOR('V', 102, unsigned int) + +#define VIDIOC_INIT_AUDIO _IOR('V', 103, unsigned int) +#define VIDIOC_AV_MUTE _IOR('V', 104, unsigned int) +#define VIDIOC_G_AVMUTE _IOR('V', 105, unsigned int) +#define HPD_GET_STATE _IOR('H', 100, unsigned int) + +#define S5PTVFB_WIN_POSITION _IOW('F', 213, struct s5ptvfb_user_window) +#define S5PTVFB_WIN_SET_PLANE_ALPHA _IOW('F', 214, struct s5ptvfb_user_plane_alpha) +#define S5PTVFB_WIN_SET_CHROMA _IOW('F', 215, struct s5ptvfb_user_chroma) + +#define S5PTVFB_SET_VSYNC_INT _IOW('F', 216, unsigned int) +#define S5PTVFB_WAITFORVSYNC _IO('F', 32) +#define S5PTVFB_WIN_SET_ADDR _IOW('F', 219, unsigned int) +#define S5PTVFB_SET_WIN_ON _IOW('F', 220, unsigned int) +#define S5PTVFB_SET_WIN_OFF _IOW('F', 221, unsigned int) +#define S5PTVFB_SCALING _IOW('F', 222, struct s5ptvfb_user_scaling) + +#ifdef __cplusplus +} +#endif + +#endif /* __S5P_TVOUT_H__ */ diff --git a/exynos5/hal/include/sec_format.h b/exynos5/hal/include/sec_format.h new file mode 100644 index 0000000..1f7b70b --- /dev/null +++ b/exynos5/hal/include/sec_format.h @@ -0,0 +1,48 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _SEC_FORMAT_H_ +#define _SEC_FORMAT_H_ + +/* enum related to pixel format */ + +enum { + HAL_PIXEL_FORMAT_YCbCr_422_P = 0x100, + HAL_PIXEL_FORMAT_YCbCr_420_P = 0x101, + HAL_PIXEL_FORMAT_YCbCr_420_I = 0x102, + HAL_PIXEL_FORMAT_CbYCrY_422_I = 0x103, + HAL_PIXEL_FORMAT_CbYCrY_420_I = 0x104, + HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x105, + HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106, + // support custom format for zero copy + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED = 0x112, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP = 0x113, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP = 0x114, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I = 0x115, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I = 0x116, + HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I = 0x117, + HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I = 0x118, + HAL_PIXEL_FORMAT_CUSTOM_CbYCr_422_I = 0x11B, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR = 0x11C, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL = 0x11D, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR = 0x11E, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL = 0x11F, + HAL_PIXEL_FORMAT_CUSTOM_MAX +}; + +#endif diff --git a/exynos5/hal/include/sec_g2d.h b/exynos5/hal/include/sec_g2d.h new file mode 100644 index 0000000..772cbf8 --- /dev/null +++ b/exynos5/hal/include/sec_g2d.h @@ -0,0 +1,251 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SEC_G2D_DRIVER_H_ +#define _SEC_G2D_DRIVER_H_ +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + +#define SEC_G2D_DEV_NAME "/dev/fimg2d" + +#define G2D_IOCTL_MAGIC 'G' + +#define G2D_BLIT _IO(G2D_IOCTL_MAGIC,0) +#define G2D_GET_VERSION _IO(G2D_IOCTL_MAGIC,1) +#define G2D_GET_MEMORY _IOR(G2D_IOCTL_MAGIC,2, unsigned int) +#define G2D_GET_MEMORY_SIZE _IOR(G2D_IOCTL_MAGIC,3, unsigned int) +#define G2D_DMA_CACHE_CLEAN _IOWR(G2D_IOCTL_MAGIC,4, struct g2d_dma_info) +#define G2D_DMA_CACHE_FLUSH _IOWR(G2D_IOCTL_MAGIC,5, struct g2d_dma_info) +#define G2D_SYNC _IO(G2D_IOCTL_MAGIC,6) +#define G2D_RESET _IO(G2D_IOCTL_MAGIC,7) + +#define G2D_MAX_WIDTH (2048) +#define G2D_MAX_HEIGHT (2048) + +#define G2D_ALPHA_VALUE_MAX (255) + +#define G2D_POLLING (1<<0) +#define G2D_INTERRUPT (0<<0) +#define G2D_CACHE_OP (1<<1) +#define G2D_NONE_INVALIDATE (0<<1) +#define G2D_HYBRID_MODE (1<<2) + +typedef enum { + G2D_ROT_0 = 0, + G2D_ROT_90, + G2D_ROT_180, + G2D_ROT_270, + G2D_ROT_X_FLIP, + G2D_ROT_Y_FLIP +} G2D_ROT_DEG; + +typedef enum { + G2D_ALPHA_BLENDING_MIN = 0, // wholly transparent + G2D_ALPHA_BLENDING_MAX = 255, // 255 + G2D_ALPHA_BLENDING_OPAQUE = 256, // opaque +} G2D_ALPHA_BLENDING_MODE; + +typedef enum { + G2D_COLORKEY_NONE = 0, + G2D_COLORKEY_SRC_ON, + G2D_COLORKEY_DST_ON, + G2D_COLORKEY_SRC_DST_ON, +} G2D_COLORKEY_MODE; + +typedef enum { + G2D_BLUE_SCREEN_NONE = 0, + G2D_BLUE_SCREEN_TRANSPARENT, + G2D_BLUE_SCREEN_WITH_COLOR, +} G2D_BLUE_SCREEN_MODE; + +typedef enum { + G2D_ROP_SRC = 0, + G2D_ROP_DST, + G2D_ROP_SRC_AND_DST, + G2D_ROP_SRC_OR_DST, + G2D_ROP_3RD_OPRND, + G2D_ROP_SRC_AND_3RD_OPRND, + G2D_ROP_SRC_OR_3RD_OPRND, + G2D_ROP_SRC_XOR_3RD_OPRND, + G2D_ROP_DST_OR_3RD, +} G2D_ROP_TYPE; + +typedef enum { + G2D_THIRD_OP_NONE = 0, + G2D_THIRD_OP_PATTERN, + G2D_THIRD_OP_FG, + G2D_THIRD_OP_BG +} G2D_THIRD_OP_MODE; + +typedef enum { + G2D_BLACK = 0, + G2D_RED, + G2D_GREEN, + G2D_BLUE, + G2D_WHITE, + G2D_YELLOW, + G2D_CYAN, + G2D_MAGENTA +} G2D_COLOR; + +typedef enum { + G2D_RGB_565 = ((0<<4)|2), + + G2D_ABGR_8888 = ((2<<4)|1), + G2D_BGRA_8888 = ((3<<4)|1), + G2D_ARGB_8888 = ((0<<4)|1), + G2D_RGBA_8888 = ((1<<4)|1), + + G2D_XBGR_8888 = ((2<<4)|0), + G2D_BGRX_8888 = ((3<<4)|0), + G2D_XRGB_8888 = ((0<<4)|0), + G2D_RGBX_8888 = ((1<<4)|0), + + G2D_ABGR_1555 = ((2<<4)|4), + G2D_BGRA_5551 = ((3<<4)|4), + G2D_ARGB_1555 = ((0<<4)|4), + G2D_RGBA_5551 = ((1<<4)|4), + + G2D_XBGR_1555 = ((2<<4)|3), + G2D_BGRX_5551 = ((3<<4)|3), + G2D_XRGB_1555 = ((0<<4)|3), + G2D_RGBX_5551 = ((1<<4)|3), + + G2D_ABGR_4444 = ((2<<4)|6), + G2D_BGRA_4444 = ((3<<4)|6), + G2D_ARGB_4444 = ((0<<4)|6), + G2D_RGBA_4444 = ((1<<4)|6), + + G2D_XBGR_4444 = ((2<<4)|5), + G2D_BGRX_4444 = ((3<<4)|5), + G2D_XRGB_4444 = ((0<<4)|5), + G2D_RGBX_4444 = ((1<<4)|5), + + G2D_PACKED_BGR_888 = ((2<<4)|7), + G2D_PACKED_RGB_888 = ((0<<4)|7), + + G2D_MAX_COLOR_SPACE +} G2D_COLOR_SPACE; + +typedef enum { + G2D_Clear_Mode, //!< [0, 0] + G2D_Src_Mode, //!< [Sa, Sc] + G2D_Dst_Mode, //!< [Da, Dc] + G2D_SrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc] + G2D_DstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc] + G2D_SrcIn_Mode, //!< [Sa * Da, Sc * Da] + G2D_DstIn_Mode, //!< [Sa * Da, Sa * Dc] + G2D_SrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] + G2D_DstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] + G2D_SrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] + G2D_DstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] + G2D_Xor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] + + // these modes are defined in the SVG Compositing standard + // http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/ + G2D_Plus_Mode, + G2D_Multiply_Mode, + G2D_Screen_Mode, + G2D_Overlay_Mode, + G2D_Darken_Mode, + G2D_Lighten_Mode, + G2D_ColorDodge_Mode, + G2D_ColorBurn_Mode, + G2D_HardLight_Mode, + G2D_SoftLight_Mode, + G2D_Difference_Mode, + G2D_Exclusion_Mode, + + kLastMode = G2D_Exclusion_Mode +} G2D_PORTTERDUFF_MODE; + +typedef enum { + G2D_MEMORY_KERNEL, + G2D_MEMORY_USER +} G2D_MEMORY_TYPE; + +typedef struct { + int x; + int y; + unsigned int w; + unsigned int h; + unsigned int full_w; + unsigned int full_h; + int color_format; + unsigned int bytes_per_pixel; + unsigned char * addr; +} g2d_rect; + +typedef struct { + unsigned int rotate_val; + unsigned int alpha_val; + + unsigned int blue_screen_mode; //true : enable, false : disable + unsigned int color_key_val; //screen color value + unsigned int color_switch_val; //one color + + unsigned int src_color; // when set one color on SRC + + unsigned int third_op_mode; + unsigned int rop_mode; + unsigned int mask_mode; + unsigned int render_mode; + unsigned int potterduff_mode; + unsigned int memory_type; +} g2d_flag; + +typedef struct { + unsigned int t; + unsigned int b; + unsigned int l; + unsigned int r; +} g2d_clip; + +typedef struct { + g2d_rect src_rect; + g2d_rect dst_rect; + g2d_clip clip; + g2d_flag flag; +} g2d_params; + +struct g2d_dma_info { + unsigned long addr; + unsigned int size; +}; + +typedef struct _sec_g2d_t { + int dev_fd; + g2d_params params; +}sec_g2d_t; + +typedef struct __s5p_rect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +} __s5p_rect; + +typedef struct __s5p_img { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t offset; + uint32_t base; + int memory_id; +} __s5p_img; + +#endif /*_SEC_G2D_DRIVER_H_*/ diff --git a/exynos5/hal/include/sec_utils.h b/exynos5/hal/include/sec_utils.h new file mode 100644 index 0000000..4aed6e0 --- /dev/null +++ b/exynos5/hal/include/sec_utils.h @@ -0,0 +1,306 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef __SAMSUNG_SYSLSI_SEC_COMMON_H__ +#define __SAMSUNG_SYSLSI_SEC_COMMON_H__ + +//---------------------------------------------------------// +// Include +//---------------------------------------------------------// + +#include +#include "sec_format.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "videodev2_samsung.h" + +#ifdef __cplusplus +} +#endif + +//---------------------------------------------------------// +// Common structure // +//---------------------------------------------------------// +struct ADDRS { + unsigned int addr_y; + unsigned int addr_cbcr; + unsigned int buf_idx; + unsigned int reserved; +}; + +//---------------------------------------------------------// +// Common function // +//---------------------------------------------------------// +inline int HAL_PIXEL_FORMAT_2_V4L2_PIX(int HAL_PIXEL_FORMAT) +{ + int V4L2_PIX = -1; + + switch (HAL_PIXEL_FORMAT) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + V4L2_PIX = V4L2_PIX_FMT_RGB32; + break; + + case HAL_PIXEL_FORMAT_RGB_888: + V4L2_PIX = V4L2_PIX_FMT_RGB24; + break; + + case HAL_PIXEL_FORMAT_RGB_565: + V4L2_PIX = V4L2_PIX_FMT_RGB565; + break; + + case HAL_PIXEL_FORMAT_BGRA_8888: + V4L2_PIX = V4L2_PIX_FMT_RGB32; + break; + + case HAL_PIXEL_FORMAT_RGBA_5551: + V4L2_PIX = V4L2_PIX_FMT_RGB555X; + break; + + case HAL_PIXEL_FORMAT_RGBA_4444: + V4L2_PIX = V4L2_PIX_FMT_RGB444; + break; + + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + V4L2_PIX = V4L2_PIX_FMT_YUV420; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + V4L2_PIX = V4L2_PIX_FMT_NV61; + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + V4L2_PIX = V4L2_PIX_FMT_NV12; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + V4L2_PIX = V4L2_PIX_FMT_YUYV; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_P: + V4L2_PIX = V4L2_PIX_FMT_YUV422P; + break; + + case HAL_PIXEL_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + V4L2_PIX = V4L2_PIX_FMT_UYVY; + break; + + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + V4L2_PIX = V4L2_PIX_FMT_NV16; + break; + + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + V4L2_PIX = V4L2_PIX_FMT_NV21; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + V4L2_PIX = V4L2_PIX_FMT_NV12T; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + V4L2_PIX = V4L2_PIX_FMT_YVYU; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + V4L2_PIX = V4L2_PIX_FMT_VYUY; + break; + + default: + LOGE("%s::unmatched HAL_PIXEL_FORMAT color_space(0x%x)\n", + __func__, HAL_PIXEL_FORMAT); + break; + } + + return V4L2_PIX; +} + +inline int V4L2_PIX_2_HAL_PIXEL_FORMAT(int V4L2_PIX) +{ + int HAL_PIXEL_FORMAT = -1; + + switch (V4L2_PIX) { + case V4L2_PIX_FMT_RGB32: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888; + break; + + case V4L2_PIX_FMT_RGB24: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_888; + break; + + case V4L2_PIX_FMT_RGB565: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_565; + break; + + case V4L2_PIX_FMT_BGR32: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_BGRA_8888; + break; + + case V4L2_PIX_FMT_RGB555X: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_5551; + break; + + case V4L2_PIX_FMT_RGB444: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_4444; + break; + + case V4L2_PIX_FMT_YUV420: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + + case V4L2_PIX_FMT_NV16: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP; + break; + + case V4L2_PIX_FMT_NV12: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP; + break; + + case V4L2_PIX_FMT_YUYV: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I; + break; + + case V4L2_PIX_FMT_YUV422P: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_422_P; + break; + + case V4L2_PIX_FMT_UYVY: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I; + break; + + case V4L2_PIX_FMT_NV21: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP; + break; + + case V4L2_PIX_FMT_NV12T: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + break; + + case V4L2_PIX_FMT_NV61: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP; + break; + + case V4L2_PIX_FMT_YVYU: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I; + break; + + case V4L2_PIX_FMT_VYUY: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I; + break; + + default: + LOGE("%s::unmatched V4L2_PIX color_space(%d)\n", + __func__, V4L2_PIX); + break; + } + + return HAL_PIXEL_FORMAT; +} + +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) + +#define GET_32BPP_FRAME_SIZE(w, h) (((w) * (h)) << 2) +#define GET_24BPP_FRAME_SIZE(w, h) (((w) * (h)) * 3) +#define GET_16BPP_FRAME_SIZE(w, h) (((w) * (h)) << 1) + +inline unsigned int FRAME_SIZE(int HAL_PIXEL_FORMAT, int w, int h) +{ + unsigned int frame_size = 0; + unsigned int size = 0; + + switch (HAL_PIXEL_FORMAT) { + // 16bpp + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + frame_size = GET_16BPP_FRAME_SIZE(w, h); + break; + + // 24bpp + case HAL_PIXEL_FORMAT_RGB_888: + frame_size = GET_24BPP_FRAME_SIZE(w, h); + break; + + // 32bpp + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + frame_size = GET_32BPP_FRAME_SIZE(w, h); + break; + + // 12bpp + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + case HAL_PIXEL_FORMAT_YCbCr_420_I: + case HAL_PIXEL_FORMAT_CbYCrY_420_I: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + size = w * h; + frame_size = size + ((size >> 2) << 1); + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + frame_size = ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h)) + + ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h >> 1)); + break; + + // 16bpp + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_YCbCr_422_P: + case HAL_PIXEL_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + frame_size = GET_16BPP_FRAME_SIZE(w, h); + break; + + default: + LOGD("%s::no matching source colorformat(0x%x), w(%d), h(%d) fail\n", + __func__, HAL_PIXEL_FORMAT, w, h); + break; + } + + return frame_size; +} + +#endif //__SAMSUNG_SYSLSI_SEC_COMMON_H__ \ No newline at end of file diff --git a/exynos5/hal/include/sec_utils_v4l2.h b/exynos5/hal/include/sec_utils_v4l2.h new file mode 100644 index 0000000..5c05c1d --- /dev/null +++ b/exynos5/hal/include/sec_utils_v4l2.h @@ -0,0 +1,330 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* + * file sec_utils_v4l2.h + * brief header file for sec_utils_v4l2.h + * author Sangwoo, Park(sw5771.park@samsung.com) + * date 2011/06/02 + * + * Revision History: + * - 2010/06/03 : Sangwoo, Park(sw5771.park@samsung.com) + * Initial version + * + * - 2011/12/07 : Hyeonmyeong Choi( hyeon.choi@samsung.com) + * Add V4L2_PIX_FMT_YVU420M + * + */ + +#ifndef __SAMSUNG_SYSLSI_SEC_COMMON_H__ +#define __SAMSUNG_SYSLSI_SEC_COMMON_H__ + +//---------------------------------------------------------// +// Include +//---------------------------------------------------------// + +#include +#include "sec_format.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "videodev2.h" + +#ifdef __cplusplus +} +#endif + +//---------------------------------------------------------// +// Common structure // +//---------------------------------------------------------// +struct ADDRS { + unsigned int addr_y; + unsigned int addr_cbcr; + unsigned int buf_idx; + unsigned int reserved; +}; + +//---------------------------------------------------------// +// Common function // +//---------------------------------------------------------// +inline int HAL_PIXEL_FORMAT_2_V4L2_PIX(int HAL_PIXEL_FORMAT) +{ + int V4L2_PIX = -1; + + switch (HAL_PIXEL_FORMAT) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + V4L2_PIX = V4L2_PIX_FMT_RGB32; + break; + + case HAL_PIXEL_FORMAT_RGB_888: + V4L2_PIX = V4L2_PIX_FMT_RGB24; + break; + + case HAL_PIXEL_FORMAT_RGB_565: + V4L2_PIX = V4L2_PIX_FMT_RGB565; + break; + + case HAL_PIXEL_FORMAT_BGRA_8888: + V4L2_PIX = V4L2_PIX_FMT_BGR32; + break; + + case HAL_PIXEL_FORMAT_RGBA_5551: + V4L2_PIX = V4L2_PIX_FMT_RGB555X; + break; + + case HAL_PIXEL_FORMAT_RGBA_4444: + V4L2_PIX = V4L2_PIX_FMT_RGB444; + break; + + case HAL_PIXEL_FORMAT_YV12: + V4L2_PIX = V4L2_PIX_FMT_YVU420M; + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + V4L2_PIX = V4L2_PIX_FMT_YUV420M; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + V4L2_PIX = V4L2_PIX_FMT_NV61; + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + V4L2_PIX = V4L2_PIX_FMT_NV12M; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + V4L2_PIX = V4L2_PIX_FMT_YUYV; + break; + + case HAL_PIXEL_FORMAT_YCbCr_422_P: + V4L2_PIX = V4L2_PIX_FMT_YUV422P; + break; + + case HAL_PIXEL_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + V4L2_PIX = V4L2_PIX_FMT_UYVY; + break; + + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + V4L2_PIX = V4L2_PIX_FMT_NV16; + break; + + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + V4L2_PIX = V4L2_PIX_FMT_NV21; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + V4L2_PIX = V4L2_PIX_FMT_NV12MT; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + V4L2_PIX = V4L2_PIX_FMT_YVYU; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + V4L2_PIX = V4L2_PIX_FMT_VYUY; + break; + + default: + LOGE("%s::unmatched HAL_PIXEL_FORMAT color_space(0x%x)\n", + __func__, HAL_PIXEL_FORMAT); + break; + } + + return V4L2_PIX; +} + +inline int V4L2_PIX_2_HAL_PIXEL_FORMAT(int V4L2_PIX) +{ + int HAL_PIXEL_FORMAT = -1; + + switch (V4L2_PIX) { + case V4L2_PIX_FMT_RGB32: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888; + break; + + case V4L2_PIX_FMT_RGB24: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_888; + break; + + case V4L2_PIX_FMT_RGB565: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGB_565; + break; + + case V4L2_PIX_FMT_BGR32: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_BGRA_8888; + break; + + case V4L2_PIX_FMT_RGB555X: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_5551; + break; + + case V4L2_PIX_FMT_RGB444: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_RGBA_4444; + break; + + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV420M: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_420_P; + break; + + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YVU420M: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YV12; + break; + + case V4L2_PIX_FMT_NV16: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP; + break; + + case V4L2_PIX_FMT_NV12: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP; + break; + + case V4L2_PIX_FMT_YUYV: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I; + break; + + case V4L2_PIX_FMT_YUV422P: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_YCbCr_422_P; + break; + + case V4L2_PIX_FMT_UYVY: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I; + break; + + case V4L2_PIX_FMT_NV21: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP; + break; + case V4L2_PIX_FMT_NV12MT: + + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + break; + + case V4L2_PIX_FMT_NV61: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP; + break; + + case V4L2_PIX_FMT_YVYU: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I; + break; + + case V4L2_PIX_FMT_VYUY: + HAL_PIXEL_FORMAT = HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I; + break; + + default: + LOGE("%s::unmatched V4L2_PIX color_space(%d)\n", + __func__, V4L2_PIX); + break; + } + + return HAL_PIXEL_FORMAT; +} + +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +#define GET_32BPP_FRAME_SIZE(w, h) (((w) * (h)) << 2) +#define GET_24BPP_FRAME_SIZE(w, h) (((w) * (h)) * 3) +#define GET_16BPP_FRAME_SIZE(w, h) (((w) * (h)) << 1) + +inline unsigned int FRAME_SIZE(int HAL_PIXEL_FORMAT, int w, int h) +{ + unsigned int frame_size = 0; + unsigned int size = 0; + + switch (HAL_PIXEL_FORMAT) { + // 16bpp + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + frame_size = GET_16BPP_FRAME_SIZE(w, h); + break; + + // 24bpp + case HAL_PIXEL_FORMAT_RGB_888: + frame_size = GET_24BPP_FRAME_SIZE(w, h); + break; + + // 32bpp + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + frame_size = GET_32BPP_FRAME_SIZE(w, h); + break; + + // 12bpp + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + case HAL_PIXEL_FORMAT_YCbCr_420_I: + case HAL_PIXEL_FORMAT_CbYCrY_420_I: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + size = w * h; + frame_size = size + ((size >> 2) << 1); + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: + frame_size = ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h)) + + ALIGN_TO_8KB(ALIGN_TO_128B(w) * ALIGN_TO_32B(h >> 1)); + break; + + // 16bpp + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_YCbCr_422_P: + case HAL_PIXEL_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: + frame_size = GET_16BPP_FRAME_SIZE(w, h); + break; + + default: + LOGD("%s::no matching source colorformat(0x%x), w(%d), h(%d) fail\n", + __func__, HAL_PIXEL_FORMAT, w, h); + break; + } + + return frame_size; +} + +#endif //__SAMSUNG_SYSLSI_SEC_COMMON_H__ diff --git a/exynos5/hal/include/ump.h b/exynos5/hal/include/ump.h new file mode 100644 index 0000000..487e2c2 --- /dev/null +++ b/exynos5/hal/include/ump.h @@ -0,0 +1,627 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2008-2011 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump.h + * + * This file contains the user space part of the UMP API. + * + */ + +#ifndef _UMP_H_ +#define _UMP_H_ + +/** + * @page page_base_ump Unified Memory Provider API + * + * UMP(Universal Memory Provider) is an API to allocate memory with some special unique requirements; + * @li Known physical addresses + * @li Non-relocatable/pinned + * @li Won't be paged out + * @li Shareable between processes (selectable per allocation for security reasons) + * @li Shareable with multiple hardware devices + * @li Physically contiguous (optional) + * @li Extended (not valid with the physically contiguous requirement for obvious reasons) + * + * Allocations from UMP can safely be used with hardware devices and other processes. + * All uses are reference counted, so memory won't be released until all participating hardware devices and processes have released their use of the allocation. + * This means that even if a process frees memory too early or crashes any hardware using the memory won't corrupt freed memory. + * + * Allocations inside a process is represented using an UMP memory handle. + * + * Each allocation is represented by a system-wide unique ID (called a secure ID), + * which can be obtained from a handle and be shared with other processes or given to a device driver. + * + * Based on a secure ID a new handle can be created either in kernel space by a driver + * or in user space by some other process to use the same allocation. + * + * Based on the handle a driver in kernel space can obtain information about the physical memory block(s) + * an allocation consists of and increment or decrement the reference count. + * + * Usage in user-space also adds a reference to the memory, but it's managed by the UMP device driver. + * + * The user-space reference count is only local to the process, so a process can't by accident decrement + * the count one time too many and cause the memory to be freed while it's in use by a hardware device. + * + * This is all handled by the UMP kernel code, no user-space code cooperation is needed. + * + * By default an allocation is only accessible in the same process or what other security boundary the OS uses. + * If marked as shared it can be accessed in all processes, the kernel space customer defined security filter permitting of course. + * See @ref ump_dd_security_filter for more information about this security filter. + * + * @sa ump_api + * @sa example_user_api.c + * @sa example_kernel_api.c + * + * @example example_user_api.c + * @example example_kernel_api.c + * + */ + +/** @defgroup ump_api Unified Memory Provider APIs + */ + +/** + * @addtogroup ump_api + * @{ + */ + +/** @defgroup ump_user_space_api UMP User Space API + * @{ */ + + +#include "ump_platform.h" +#include "ump_common.h" +#include "ion.h" + +#ifndef __KERNEL__ +#include +#include +#include +#include +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * External representation of a UMP handle in user space. + */ +typedef void * ump_handle; + +/** + * Value to indicate an invalid UMP memory handle. + */ +#define UMP_INVALID_MEMORY_HANDLE ((ump_handle)0) + +/** + * Opens and initializes the UMP library. + * + * This function must be called at least once before calling any other UMP API functions. + * Each successful open call is reference counted and must be matched with a call to @ref ump_close. + * It is safe to call @a ump_open after a @a ump_close has terminated a previous session. + * + * UMP_ERROR will be returned if: + * - the reference count is ULONG_MAX so would overflow. + * - the reference count is 0 and the backend fails to open. + * + * UMP API: v1 and v2 + * @see ump_close + * + * @return UMP_OK indicates success, UMP_ERROR indicates failure. + */ +UMP_API_EXPORT ump_result ump_open(void) CHECK_RESULT; + + +/** + * Terminate the UMP library. + * + * This must be called once for every successful @ref ump_open. The UMP library is + * terminated when, and only when, the last open reference to the UMP interface is closed. + * + * If this is called while having active allocations or mappings the behavior is undefined. + * + * UMP API: v1 and v2 + * @see ump_open + */ +UMP_API_EXPORT void ump_close(void); + + +/** + * Retrieves the secure ID for the specified UMP memory. + * + * This identifier is unique across the entire system, and uniquely identifies + * the specified UMP memory allocation. This identifier can later be used through the + * v2 API: + * @ref ump_from_secure_id or + * @ref ump_dd_from_secure_id + * v1 API: + * @ref ump_handle_create_from_secure_id or + * @ref ump_dd_handle_create_from_secure_id + * + * functions in order to access this UMP memory, for instance from another process. + * Unless the allocation was marked as shared the returned ID will only be resolvable in the same process as did the allocation. + * + * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return @a UMP_INVALID_SECURE_ID. + * + * @note There is a kernel space equivalent function called @ref ump_dd_secure_id_get + * + * UMP API: v1 and v2 + * + * @see ump_dd_secure_id_get + * v2 API: + * @see ump_from_secure_id + * @see ump_dd_from_secure_id + * v1 API: + * @see ump_handle_create_from_secure_id + * @see ump_dd_from_secure_id + * + * @param mem Handle to UMP memory. + * + * @return Returns the secure ID for the specified UMP memory. + */ +UMP_API_EXPORT ump_secure_id ump_secure_id_get(const ump_handle mem) CHECK_RESULT; + + +/** + * Synchronous mapping cache sync operation. + * + * Performs the requested CPU side cache sync operations before returning. + * A clean must be done before the memory is guaranteed to be visible in main memory. + * Any device-specific cache clean/invalidate must be done in combination with this routine, if needed. + * Function returns cache status for the allocation. + * + * Example: + * @code + * ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN, ptr, size); + * device_invalidate(...); + * // ... run device ... + * device_clean(...); + * ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, ptr, size); + * // ... safe to access on the cpu side again ... + * @endcode + * + * + * Calls to operate on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior. + * Debug builds will assert on this. + * + * If @a address is not inside a mapping previously obtained from the @a ump_handle provided results in undefined behavior. + * If @a address combined with @a size results on reaching beyond the end of the buffer results in undefined behavior. + * + * UMP API: v1 and v2 + * @param mem Handle to UMP memory + * @param op Cache operation to perform + * @param[in] address The CPU address where to start the sync operation, this can be at an offset from the start of the allocation. + * @param size The number of bytes to be synced. + * + * @return Returns 1 if cache is enabled, 0 if cache is disabled for the given allocation. + * + */ +UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void * address, size_t size); + + +#ifndef UMP_BLOCK_V2_API + +/** + * Allocate a buffer. + * The life-time of the allocation is controlled by a reference count. + * The reference count of the returned buffer is set to 1. + * The memory will be freed once the reference count reaches 0. + * Use @ref ump_retain and @ref ump_release to control the reference count. + * The contens of the memory returned will be zero initialized. + * + * The @ref UMP_V1_API_DEFAULT_ALLOCATION_FLAGS can be used + * to create a buffer that can be shared with v1 API applications. + * The allocation will be limited to 32-bit PA. + * + * The @ref UMP_CONSTRAINT_UNCACHED flag disables cache for all cpu mappings for this allocation. + * + * UMP API: v2 + * @param size Number of bytes to allocate. Will be padded up to a multiple of the page size. + * @param flags Bit-wise OR of zero or more of the allocation flag bits. + * @return Handle to the new allocation, or @a UMP_INVALID_MEMORY_HANDLE on allocation failure. + */ +UMP_API_EXPORT ump_handle ump_allocate_64(u64 size, ump_alloc_flags flags) CHECK_RESULT; + + +/** + * Creates a handle based on a shared UMP memory allocation. + * + * The usage of UMP memory is reference counted, so this will increment the reference + * count by one for the specified UMP memory. + * + * If called on an @a UMP_INVALID_SECURE_ID this will return @a UMP_INVALID_MEMORY_HANDLE. + * If called on an non-shared allocation and this is a different process @a UMP_INVALID_MEMORY_HANDLE will be returned. + * + * Use @ref ump_release when there is no longer any + * use for the retrieved handle. + * + * @note There is a kernel space equivalent function called @ref ump_dd_from_secure_id + * + * UMP API: v2 + * @see ump_release + * @see ump_dd_from_secure_id + * + * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get function. + * + * @return @a UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. + */ +UMP_API_EXPORT ump_handle ump_from_secure_id(ump_secure_id secure_id) CHECK_RESULT; + + +/** + * 64 bit version of @ref ump_size_get. Retrieves the actual size of the specified UMP memory. + * + * The size is reported in bytes, and is typically a multiple of the page size. + * If called on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior. + * Debug builds will assert on this. + * + * @note There is a kernel space equivalent function called @ref ump_dd_size_get_64 + * + * UMP API: v2 + * @see ump_dd_size_get_64 + * + * @param mem Handle to UMP memory. + * + * @return Returns the allocated 64-bit size of the specified UMP memory, in bytes. + */ +UMP_API_EXPORT u64 ump_size_get_64(const ump_handle mem) CHECK_RESULT; + + +/** + * Retrieves a memory mapped pointer to the specified UMP memory. + * + * This function retrieves a memory mapped pointer to the specified UMP memory, that can be used by the CPU.@n + * Every successful call to @a ump_map must be matched with a call to @ref ump_unmap when the mapping is no longer needed. + * + * An offset and/or size resulting in going beyond the end of the buffer will case the function to return NULL. + * + * Calling on @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior. + * Debug builds will assert on this. + * + * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required. + * + * UMP API: v2 + * @see ump_unmap + * + * @param mem Handle to UMP memory. + * @param offset An offset at which the mapping begins. + * @param size The number of bytes to map. Passing 0 does not retrieve a memory mapped + * pointer - instead NULL is returned. + * + * @return NULL indicates failure, otherwise a CPU mapped pointer is returned. + */ +UMP_API_EXPORT void * ump_map(ump_handle mem, u64 offset, size_t size) CHECK_RESULT; + + +/** + * Releases a previously mapped pointer to the specified UMP memory. + * + * Every successful call to @ref ump_map must be matched with a call to @a ump_unmap when the mapping is no longer needed. + * + * The following results in undefined behavior: + * - Called with an address not returned from @ref ump_map + * - Called with a different @a ump_handle than was used to obtain the pointer + * - Called with a different @a size than was used to obtain the pointer + * + * @note Systems without a MMU must still implement this function, even though no unmapping should be needed. + * + * UMP API: v2 + * @param mem Handle to UMP memory. + * @param[in] address The CPU virtual address returned by @ref ump_map + * @param size Size matching argument given to ump_map + */ +UMP_API_EXPORT void ump_unmap(ump_handle mem, void* address, size_t size); + + +/** + * Adds an extra reference to the specified UMP memory. + * + * This function adds an extra reference to the specified UMP memory. This function should + * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle + * variable. The function @ref ump_release must then be used + * to release each copy of the UMP memory handle. + * + * It's safe to call this on both shared and non-shared handles. + * Calling on an @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior. + * Debug builds will assert on this. + * + * @note You are not required to call @ref ump_retain + * for UMP handles returned from + * @ref ump_from_secure_id, + * because these handles are already reference counted by this function. + * + * @note There is a kernel space equivalent function called @ref ump_dd_retain + * + * UMP API: v2 + * @see ump_dd_retain + * + * @param mem Handle to UMP memory. + * @return UMP_OK indicates success, UMP_ERROR indicates failure. + */ +UMP_API_EXPORT ump_result ump_retain(ump_handle mem); + + +/** + * Releases a reference from the specified UMP memory. + * + * This function should be called once for every reference to the UMP memory handle. + * When the last reference is released, all resources associated with this UMP memory + * handle are freed. + * + * One can only call ump_release when matched with a successful ump_retain, ump_allocate_64 or ump_from_secure_id + * It's safe to call this on both shared and non-shared handles. + * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return early. + * + * @note There is a kernel space equivalent function called @ref ump_dd_release + * + * UMP API: v2 + * @see ump_release + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_release(ump_handle mem); + + +/** + * Import external memory into UMP. + * + * This function creates a ump_handle wrapping memory provided by some external source. + * + * For reference counted types the returned handle represents one new reference, + * which must be freed using @a ump_release. + * The handle passed in still holds its reference and can still be used and must be released + * as it would be normally. + * + * For ownership based types the returned handle has claimed the ownership which will be released + * with @a ump_release. + * The handle passed in is no longer valid. + * + * A pointer to the handle type is required, not the type it self. + * + * The flags are used in the same way as for @a ump_allocate_64, except that these flags are ignored: + * @li UMP_CONSTRAINT_32BIT_ADDRESSABLE + * @li UMP_CONSTRAINT_PHYSICALLY_LINEAR + * + * The returned UMP handle can be used as any other ump_handle. + * + * Example for UMP_EXTERNAL_MEM_TYPE_ION: + * + * @code + * ump_handle h; + * ump_alloc_flags flags = get_requested_flags(); + * int fd = ion_fd_get(); + * h = ump_import(UMP_EXTERNAL_MEM_TYPE_ION, &fd, flags); + * // native release + * close(fd); + * ... + * ump_release(h); + * @endcode + * + * Example for a generic ownership based type: + * + * @code + * ump_handle h; + * ump_alloc_flags = get_requested_flags(); + * type t = type_claim(); + * h = ump_import(UMP_OWNERSHIP_BASED_TYPE, &t, flags); + * // native handle no longer valid + * t = INVALID; + * ... + * ump_release(h); + * @endcode + * + * UMP API: v2 + * @see ump_release + * + * @param type Type of external memory to import + * @param phandle Pointer to the handle to import. + * @param flags Bit-wise OR of zero or more of the allocation flag bits. + * @return Handle wrapping the imported memory, or @a UMP_INVALID_MEMORY_HANDLE on import failure. + */ +UMP_API_EXPORT ump_handle ump_import(enum ump_external_memory_type type, void * phandle, ump_alloc_flags flags) CHECK_RESULT; + +#endif /* UMP_BLOCK_V2_API */ + +/** @name UMP v1 API + * Functions provided to support compatibility with UMP v1 API + * + * You should use v1 API only with handles created with @ref ump_ref_drv_allocate + * and @ref ump_handle_create_from_secure_id. + * Using v1 API for handles created with v2 API can cause undefined behavior. + * + *@{ + */ + +#ifndef UMP_BLOCK_V1_API + +/** Allocate an UMP handle containing a memory buffer. + * + * If usage is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu. + * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached. + * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported. + * + * UMP API: v1 + * @param size The minimum size for the allocation. + * @param usage The allocation constraints. + */ + +UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage); + + +/** + * Retrieves the actual size of the specified UMP memory. + * + * The size is reported in bytes, and is typically page aligned. + * + * @note There is a kernel space equivalent function called @ref ump_dd_size_get "ump_dd_size_get" + * + * UMP API: v1 + * @see ump_dd_size_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the allocated size of the specified UMP memory, in bytes. + */ +UMP_API_EXPORT unsigned long ump_size_get(ump_handle mem) CHECK_RESULT; + + +/** + * Retrieves a handle to allocated UMP memory. + * + * The usage of UMP memory is reference counted, so this will increment the reference + * count by one for the specified UMP memory. + * Use @ref ump_reference_release "ump_reference_release" when there is no longer any + * use for the retrieved handle. + * + * @note There is a kernel space equivalent function called @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" + * + * UMP API: v1 + * @see ump_reference_release + * @see ump_dd_handle_create_from_secure_id + * + * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. + * + * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. + */ +UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id) CHECK_RESULT; + + +/** + * Adds an extra reference to the specified UMP memory. + * + * This function adds an extra reference to the specified UMP memory. This function should + * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle + * variable. The function @ref ump_reference_release "ump_reference_release" must then be used + * to release each copy of the UMP memory handle. + * + * @note You are not required to call @ref ump_reference_add "ump_reference_add" + * for UMP handles returned from + * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id", + * because these handles are already reference counted by this function. + * + * @note There is a kernel space equivalent function called @ref ump_dd_reference_add "ump_dd_reference_add" + * + * UMP API: v1 + * @see ump_dd_reference_add + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_reference_add(ump_handle mem); + + +/** + * Releases a reference from the specified UMP memory. + * + * This function should be called once for every reference to the UMP memory handle. + * When the last reference is released, all resources associated with this UMP memory + * handle are freed. + * + * @note There is a kernel space equivalent function called @ref ump_dd_reference_release "ump_dd_reference_release" + * + * UMP API: v1 + * @see ump_dd_reference_release + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_reference_release(ump_handle mem); + + +/** + * Retrieves a memory mapped pointer to the specified UMP memory. + * + * This function retrieves a memory mapped pointer to the specified UMP memory, + * that can be used by the CPU. Every successful call to + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" is reference counted, + * and must therefor be followed by a call to + * @ref ump_mapped_pointer_release "ump_mapped_pointer_release " when the + * memory mapping is no longer needed. + * + * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required. + * + * UMP API: v1 + * @see ump_mapped_pointer_release + * + * @param mem Handle to UMP memory. + * + * @return NULL indicates failure, otherwise a CPU mapped pointer is returned. + */ +UMP_API_EXPORT void * ump_mapped_pointer_get(ump_handle mem); + + +/** + * Releases a previously mapped pointer to the specified UMP memory. + * + * The CPU mapping of the specified UMP memory memory is reference counted, + * so every call to @ref ump_mapped_pointer_get "ump_mapped_pointer_get" must + * be matched with a call to this function when the mapping is no longer needed. + * + * The CPU mapping is not removed before all references to the mapping is released. + * + * UMP API: v1 + * @note Systems without a MMU must still implement this function, even though no unmapping should be needed. + * + * @param mem Handle to UMP memory. + */ +UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle mem); + + +/** + * Read from specified UMP memory. + * + * Another way of reading from (and writing to) UMP memory is to use the + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve + * a CPU mapped pointer to the memory. + * + * UMP API: v1 + * @see ump_mapped_pointer_get + * + * @param dst Destination buffer. + * @param src Handle to UMP memory to read from. + * @param offset Where to start reading, given in bytes. + * @param length How much to read, given in bytes. + */ +UMP_API_EXPORT void ump_read(void * dst, ump_handle src, unsigned long offset, unsigned long length); + + +/** + * Write to specified UMP memory. + * + * Another way of writing to (and reading from) UMP memory is to use the + * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve + * a CPU mapped pointer to the memory. + * + * UMP API: v1 + * @see ump_mapped_pointer_get + * + * @param dst Handle to UMP memory to write to. + * @param offset Where to start writing, given in bytes. + * @param src Buffer to read from. + * @param length How much to write, given in bytes. + */ +UMP_API_EXPORT void ump_write(ump_handle dst, unsigned long offset, const void * src, unsigned long length); + +#endif /* UMP_BLOCK_V1_API */ + +/* @} */ + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* end group ump_user_space_api */ + +/** @} */ /* end group ump_api */ + +#endif /* _UMP_H_ */ diff --git a/exynos5/hal/include/ump_common.h b/exynos5/hal/include/ump_common.h new file mode 100644 index 0000000..8fdeef1 --- /dev/null +++ b/exynos5/hal/include/ump_common.h @@ -0,0 +1,232 @@ +/* + * + * (C) COPYRIGHT 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + + +/** + * @file ump_common.h + * + * This file contains some common enum values used both in both the user and kernel space side of UMP. + */ + +#ifndef _UMP_COMMON_H_ +#define _UMP_COMMON_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/** + * Values to identify major and minor version of UMP + */ +#define UMP_VERSION_MAJOR 2 +#define UMP_VERSION_MINOR 0 + +/** + * Typedef for a secure ID, a system wide identifier for UMP memory buffers. + */ +typedef uint32_t ump_secure_id; + +/** + * Value to indicate an invalid secure Id. + */ +#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) + +/** + * UMP error codes. + */ +typedef enum +{ + UMP_OK = 0, /**< indicates success */ + UMP_ERROR = 1 /**< indicates failure */ +} ump_result; + +/** + * Allocation flag bits. + * + * ump_allocate accepts zero or more flags to specify the type of memory to allocate and how to expose it to devices. + * + * For each supported device there are 4 flags to control access permissions and give usage characteristic hints to optimize the allocation/mapping. + * They are; + * @li @a UMP_PROT__RD read permission + * @li @a UMP_PROT__WR write permission + * @li @a UMP_HINT__RD read often + * @li @a UMP_HINT__WR written often + * + * 5 devices are currently supported, with a device being the CPU itself. + * The other 4 devices will be mapped to real devices per SoC design. + * They are just named W,X,Y,Z by UMP as it has no knowledge of their real names/identifiers. + * As an example device W could be a camera device while device Z could be an ARM GPU device, leaving X and Y unused. + * + * 2 additional flags control the allocation; + * @li @a UMP_CONSTRAINT_PHYSICALLY_LINEAR the allocation must be physical linear. Typical for devices without an MMU and no IOMMU to help it. + * @li @a UMP_PROT_SHAREABLE the allocation can be shared with other processes on the system. Without this flag the returned allocation won't be resolvable in other processes. + * + * All UMP allocation are growable unless they're @a UMP_PROT_SHAREABLE. + * The hint bits should be used to indicate the access pattern so the driver can select the most optimal memory type and cache settings based on the what the system supports. + */ +typedef enum +{ + /* Generic helpers */ + UMP_PROT_DEVICE_RD = (1u << 0), + UMP_PROT_DEVICE_WR = (1u << 1), + UMP_HINT_DEVICE_RD = (1u << 2), + UMP_HINT_DEVICE_WR = (1u << 3), + UMP_DEVICE_MASK = 0xF, + UMP_DEVICE_CPU_SHIFT = 0, + UMP_DEVICE_W_SHIFT = 4, + UMP_DEVICE_X_SHIFT = 8, + UMP_DEVICE_Y_SHIFT = 12, + UMP_DEVICE_Z_SHIFT = 16, + + /* CPU protection and hints. */ + UMP_PROT_CPU_RD = (1u << 0), + UMP_PROT_CPU_WR = (1u << 1), + UMP_HINT_CPU_RD = (1u << 2), + UMP_HINT_CPU_WR = (1u << 3), + + /* device W */ + UMP_PROT_W_RD = (1u << 4), + UMP_PROT_W_WR = (1u << 5), + UMP_HINT_W_RD = (1u << 6), + UMP_HINT_W_WR = (1u << 7), + + /* device X */ + UMP_PROT_X_RD = (1u << 8), + UMP_PROT_X_WR = (1u << 9), + UMP_HINT_X_RD = (1u << 10), + UMP_HINT_X_WR = (1u << 11), + + /* device Y */ + UMP_PROT_Y_RD = (1u << 12), + UMP_PROT_Y_WR = (1u << 13), + UMP_HINT_Y_RD = (1u << 14), + UMP_HINT_Y_WR = (1u << 15), + + /* device Z */ + UMP_PROT_Z_RD = (1u << 16), + UMP_PROT_Z_WR = (1u << 17), + UMP_HINT_Z_RD = (1u << 18), + UMP_HINT_Z_WR = (1u << 19), + + /* 20-26 reserved for future use */ + UMPP_ALLOCBITS_UNUSED = (0x7Fu << 20), + /** Allocations marked as @ UMP_CONSTRAINT_UNCACHED won't be mapped as cached by the cpu */ + UMP_CONSTRAINT_UNCACHED = (1u << 27), + /** Require 32-bit physically addressable memory */ + UMP_CONSTRAINT_32BIT_ADDRESSABLE = (1u << 28), + /** For devices without an MMU and with no IOMMU assistance. */ + UMP_CONSTRAINT_PHYSICALLY_LINEAR = (1u << 29), + /** Shareable must be set to allow the allocation to be used by other processes, the default is non-shared */ + UMP_PROT_SHAREABLE = (1u << 30) + /* (1u << 31) should not be used to ensure compiler portability */ +} ump_allocation_bits; + +/** + * ump_allocation_bits combination argument type. + * + * Type used to pass zero or more bits from the @ref ump_allocation_bits enum + */ +typedef uint32_t ump_alloc_flags; + + +/** + * Default allocation flags for UMP v1 compatible allocations. + */ +#define UMP_V1_API_DEFAULT_ALLOCATION_FLAGS UMP_PROT_CPU_RD | UMP_PROT_CPU_WR | \ + UMP_PROT_W_RD | UMP_PROT_W_WR | \ + UMP_PROT_X_RD | UMP_PROT_X_WR | \ + UMP_PROT_Y_RD | UMP_PROT_Y_WR | \ + UMP_PROT_Z_RD | UMP_PROT_Z_WR | \ + UMP_PROT_SHAREABLE | \ + UMP_CONSTRAINT_32BIT_ADDRESSABLE + +/** + * CPU cache sync operations. + * + * Cache synchronization operations to pass to @ref ump_cpu_msync_now + */ +enum +{ + /** + * Cleans any dirty cache lines to main memory, but the data will still be available in the cache. + * After a clean the contents of memory is considered to be "owned" by the device. + * */ + UMP_MSYNC_CLEAN = 1, + + /** Cleans any dirty cache lines to main memory and Ejects all lines from the cache. + * After an clean&invalidate the contents of memory is considered to be "owned" by the CPU. + * Any subsequent access will fetch data from main memory. + * + * @note Due to CPUs doing speculative prefetching a UMP_MSYNC_CLEAN_AND_INVALIDATE must be done before and after interacting with hardware. + * */ + UMP_MSYNC_CLEAN_AND_INVALIDATE + +}; + +typedef u32 ump_cpu_msync_op; + +/** + * Memory import types supported. + * If new import types are added they will appear here. + * They must be added before UMPP_EXTERNAL_MEM_COUNT and + * must be assigned an explicit sequantial number. + * + * @li UMP_EXTERNAL_MEM_TYPE_ION - Import an ION allocation + * Takes a int* (pointer to a file descriptor) + * Another ION reference is taken which is released on the final ump_release + */ +enum ump_external_memory_type +{ + UMPP_EXTERNAL_MEM_TYPE_UNUSED = 0, /* reserve type 0 */ + UMP_EXTERNAL_MEM_TYPE_ION = 1, + UMPP_EXTERNAL_MEM_COUNT +}; + +/** @name UMP v1 API + * + *@{ + */ + +/** + * Allocation constraints. + * + * Allocation flags to pass @ref ump_ref_drv_allocate + * + * UMP v1 API only. + */ +typedef enum +{ + /** the allocation is mapped as noncached. */ + UMP_REF_DRV_CONSTRAINT_NONE = 0, + /** not supported. */ + UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR = 1, + /** the allocation is mapped as cached by the cpu. */ + UMP_REF_DRV_CONSTRAINT_USE_CACHE = 4 +} ump_alloc_constraints; + +/* @} */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* _UMP_COMMON_H_ */ diff --git a/exynos5/hal/include/ump_platform.h b/exynos5/hal/include/ump_platform.h new file mode 100644 index 0000000..31f9343 --- /dev/null +++ b/exynos5/hal/include/ump_platform.h @@ -0,0 +1,57 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2008-2010 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump_platform.h + * + * This file should define UMP_API_EXPORT, + * which dictates how the UMP user space API should be exported/imported. + * Modify this file, if needed, to match your platform setup. + */ + + +#ifndef _UMP_PLATFORM_H_ +#define _UMP_PLATFORM_H_ + +#include "malisw/mali_stdtypes.h" + +/** @addtogroup ump_user_space_api + * @{ */ + +/** + * A define which controls how UMP user space API functions are imported and exported. + * + * Functions exported by the driver is tagged with UMP_API_EXPORT to allow + * the compiler/build system/OS loader to detect and handle functions which is to be exported/imported from a shared library. @n + * This define should be set by the implementor of the UMP API to match their needs if needed. + * + * Typical usage example in the driver: + * + * UMP_API_EXPORT void my_api_call(void); + */ + +#if defined(_WIN32) + +#define UMP_API_EXPORT + +#elif defined(__SYMBIAN32__) + +#define UMP_API_EXPORT IMPORT_C + +#else + +#define UMP_API_EXPORT + +#endif + +/** @} */ /* end group ump_user_space_api */ + + +#endif /* _UMP_PLATFORM_H_ */ diff --git a/exynos5/hal/include/ump_ref_drv.h b/exynos5/hal/include/ump_ref_drv.h new file mode 100644 index 0000000..6320f1d --- /dev/null +++ b/exynos5/hal/include/ump_ref_drv.h @@ -0,0 +1,59 @@ +/* + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2009-2010 ARM Limited + * ALL RIGHTS RESERVED + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + */ + +/** + * @file ump_ref_drv.h + * + * Reference driver extensions to the UMP user space API for allocating UMP memory + */ + +#ifndef _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ +#define _UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ + +#include "ump.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + /* This enum must match with the IOCTL enum in ump_ioctl.h */ + UMP_REF_DRV_CONSTRAINT_NONE = 0, + UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR = 1, + /* This enum is included by samsung */ + UMP_REF_DRV_CONSTRAINT_USE_CACHE = 128, +} ump_alloc_constraints; + +/** Allocate an UMP handle containing a memory buffer. + * Input: Size: The minimum size for the allocation. + * Usage: If this is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu. + * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached. + * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported.*/ +UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage); + +UMP_API_EXPORT ump_handle ump_ref_drv_ion_import(int ion_fd, ump_alloc_constraints constraints); +typedef enum { + UMP_MSYNC_CLEAN = 0 , + UMP_MSYNC_CLEAN_AND_INVALIDATE = 1, + UMP_MSYNC_READOUT_CACHE_ENABLED = 128, +} ump_cpu_msync_op; + +/** Flushing cache for an ump_handle. + * The function will always CLEAN_AND_INVALIDATE as long as the \a op is not UMP_MSYNC_READOUT_CACHE_ENABLED. + * If so it will only report back if the given ump_handle is cacheable. + * At the momement the implementation does not use \a address or \a size. + * Return value is 1 if cache is enabled, and 0 if it is disabled for the given allocation.*/ +UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void* address, int size); + +#ifdef __cplusplus +} +#endif + +#endif /*_UNIFIED_MEMORY_PROVIDER_REF_DRV_H_ */ diff --git a/exynos5/hal/include/v4l2-mediabus.h b/exynos5/hal/include/v4l2-mediabus.h new file mode 100644 index 0000000..1a13cf3 --- /dev/null +++ b/exynos5/hal/include/v4l2-mediabus.h @@ -0,0 +1,116 @@ +/* + * Media Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_V4L2_MEDIABUS_H +#define __LINUX_V4L2_MEDIABUS_H + +#include +#include + +/* + * These pixel codes uniquely identify data formats on the media bus. Mostly + * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is + * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the + * data format is fixed. Additionally, "2X8" means that one pixel is transferred + * in two 8-bit samples, "BE" or "LE" specify in which order those samples are + * transferred over the bus: "LE" means that the least significant bits are + * transferred first, "BE" means that the most significant bits are transferred + * first, and "PADHI" and "PADLO" define which bits - low or high, in the + * incomplete high byte, are filled with padding bits. + * + * The pixel codes are grouped by type, bus_width, bits per component, samples + * per pixel and order of subsamples. Numerical values are sorted using generic + * numerical sort order (8 thus comes before 10). + * + * As their value can't change when a new pixel code is inserted in the + * enumeration, the pixel codes are explicitly given a numerical value. The next + * free values for each category are listed below, update them when inserting + * new pixel codes. + */ +enum v4l2_mbus_pixelcode { + V4L2_MBUS_FMT_FIXED = 0x0001, + + /* RGB - next is 0x1009 */ + V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001, + V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004, + V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005, + V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006, + V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, + V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, + V4L2_MBUS_FMT_XRGB8888_4X8_LE = 0x1009, + + /* YUV (including grey) - next is 0x2014 */ + V4L2_MBUS_FMT_Y8_1X8 = 0x2001, + V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, + V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, + V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004, + V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005, + V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006, + V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007, + V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008, + V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009, + V4L2_MBUS_FMT_Y10_1X10 = 0x200a, + V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, + V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, + V4L2_MBUS_FMT_Y12_1X12 = 0x2013, + V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, + V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, + V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, + V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, + V4L2_MBUS_FMT_YUV8_1X24 = 0x2014, + V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, + V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, + + /* Bayer - next is 0x3015 */ + V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, + V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013, + V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, + V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014, + V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, + V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, + V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, + V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d, + V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003, + V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004, + V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005, + V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006, + V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007, + V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e, + V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a, + V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f, + V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008, + V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010, + V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011, + V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012, + + /* JPEG compressed formats - next is 0x4002 */ + V4L2_MBUS_FMT_JPEG_1X8 = 0x4001, +}; + +/** + * struct v4l2_mbus_framefmt - frame format on the media bus + * @width: frame width + * @height: frame height + * @code: data format code (from enum v4l2_mbus_pixelcode) + * @field: used interlacing type (from enum v4l2_field) + * @colorspace: colorspace of the data (from enum v4l2_colorspace) + */ +struct v4l2_mbus_framefmt { + __u32 width; + __u32 height; + __u32 code; + __u32 field; + __u32 colorspace; + __u32 reserved[7]; +}; + +#endif diff --git a/exynos5/hal/include/v4l2-subdev.h b/exynos5/hal/include/v4l2-subdev.h new file mode 100644 index 0000000..f5dd9a1 --- /dev/null +++ b/exynos5/hal/include/v4l2-subdev.h @@ -0,0 +1,141 @@ +/* + * V4L2 subdev userspace API + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_V4L2_SUBDEV_H +#define __LINUX_V4L2_SUBDEV_H + +#include +#include +#include "v4l2-mediabus.h" + +/** + * enum v4l2_subdev_format_whence - Media bus format type + * @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only + * @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device + */ +enum v4l2_subdev_format_whence { + V4L2_SUBDEV_FORMAT_TRY = 0, + V4L2_SUBDEV_FORMAT_ACTIVE = 1, +}; + +/** + * struct v4l2_subdev_format - Pad-level media bus format + * @which: format type (from enum v4l2_subdev_format_whence) + * @pad: pad number, as reported by the media API + * @format: media bus format (format code and frame size) + */ +struct v4l2_subdev_format { + __u32 which; + __u32 pad; + struct v4l2_mbus_framefmt format; + __u32 reserved[8]; +}; + +/** + * struct v4l2_subdev_crop - Pad-level crop settings + * @which: format type (from enum v4l2_subdev_format_whence) + * @pad: pad number, as reported by the media API + * @rect: pad crop rectangle boundaries + */ +struct v4l2_subdev_crop { + __u32 which; + __u32 pad; + struct v4l2_rect rect; + __u32 reserved[8]; +}; + +/** + * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration + * @pad: pad number, as reported by the media API + * @index: format index during enumeration + * @code: format code (from enum v4l2_mbus_pixelcode) + */ +struct v4l2_subdev_mbus_code_enum { + __u32 pad; + __u32 index; + __u32 code; + __u32 reserved[9]; +}; + +/** + * struct v4l2_subdev_frame_size_enum - Media bus format enumeration + * @pad: pad number, as reported by the media API + * @index: format index during enumeration + * @code: format code (from enum v4l2_mbus_pixelcode) + */ +struct v4l2_subdev_frame_size_enum { + __u32 index; + __u32 pad; + __u32 code; + __u32 min_width; + __u32 max_width; + __u32 min_height; + __u32 max_height; + __u32 reserved[9]; +}; + +/** + * struct v4l2_subdev_frame_interval - Pad-level frame rate + * @pad: pad number, as reported by the media API + * @interval: frame interval in seconds + */ +struct v4l2_subdev_frame_interval { + __u32 pad; + struct v4l2_fract interval; + __u32 reserved[9]; +}; + +/** + * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration + * @pad: pad number, as reported by the media API + * @index: frame interval index during enumeration + * @code: format code (from enum v4l2_mbus_pixelcode) + * @width: frame width in pixels + * @height: frame height in pixels + * @interval: frame interval in seconds + */ +struct v4l2_subdev_frame_interval_enum { + __u32 index; + __u32 pad; + __u32 code; + __u32 width; + __u32 height; + struct v4l2_fract interval; + __u32 reserved[9]; +}; + +#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) +#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) +#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ + _IOWR('V', 21, struct v4l2_subdev_frame_interval) +#define VIDIOC_SUBDEV_S_FRAME_INTERVAL \ + _IOWR('V', 22, struct v4l2_subdev_frame_interval) +#define VIDIOC_SUBDEV_ENUM_MBUS_CODE \ + _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) +#define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \ + _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) +#define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ + _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) +#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) +#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) + +#endif diff --git a/exynos5/hal/include/video.h b/exynos5/hal/include/video.h new file mode 100644 index 0000000..0565b85 --- /dev/null +++ b/exynos5/hal/include/video.h @@ -0,0 +1,363 @@ +#ifndef _VIDEO_H_ +#define _VIDEO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __HDMI_VIDEO_VIDEOFORMAT__ +#define __HDMI_VIDEO_VIDEOFORMAT__ +/** + * @enum VideoFormat + * Video format + */ +enum VideoFormat { + /** 640x480p\@60Hz */ + v640x480p_60Hz = 0, + /** 720x480p\@60Hz */ + v720x480p_60Hz, + /** 1280x700p\@60Hz */ + v1280x720p_60Hz, + /** 1920x1080i\@60Hz */ + v1920x1080i_60Hz, + /** 720x480i\@60Hz */ + v720x480i_60Hz, + /** 720x240p\@60Hz */ + v720x240p_60Hz, + /** 2880x480i\@60Hz */ + v2880x480i_60Hz, + /** 2880x240p\@60Hz */ + v2880x240p_60Hz, + /** 1440x480p\@60Hz */ + v1440x480p_60Hz, + /** 1920x1080p\@60Hz */ + v1920x1080p_60Hz, + /** 720x576p\@60Hz */ + v720x576p_50Hz, + /** 1280x720p\@50Hz */ + v1280x720p_50Hz, + /** 1920x1080i\@50Hz (V total = 1125) */ + v1920x1080i_50Hz, + /** 720x576i\@50Hz */ + v720x576i_50Hz, + /** 720x288p\@50Hz */ + v720x288p_50Hz, + /** 2880x576i\@50Hz */ + v2880x576i_50Hz, + /** 2880x288p\@50Hz */ + v2880x288p_50Hz, + /** 1440x576p\@50Hz */ + v1440x576p_50Hz, + /** 1920x1080p\@50Hz */ + v1920x1080p_50Hz, + /** 1920x1080p\@24Hz */ + v1920x1080p_24Hz, + /** 1920x1080p\@25Hz */ + v1920x1080p_25Hz, + /** 1920x1080p\@30Hz */ + v1920x1080p_30Hz, + /** 2880x480p\@60Hz */ + v2880x480p_60Hz, + /** 2880x576p\@60Hz */ + v2880x576p_50Hz, + /** 1920x1080i\@50Hz (V total = 1250) */ + v1920x1080i_50Hz_1250, + /** 1920x1080i\@100Hz */ + v1920x1080i_100Hz, + /** 1280x720p\@100Hz */ + v1280x720p_100Hz, + /** 720x576p\@100Hz */ + v720x576p_100Hz, + /** 720x576i\@100Hz */ + v720x576i_100Hz, + /** 1920x1080i\@120Hz */ + v1920x1080i_120Hz, + /** 1280x720p\@120Hz */ + v1280x720p_120Hz, + /** 720x480p\@120Hz */ + v720x480p_120Hz, + /** 720x480i\@120Hz */ + v720x480i_120Hz, + /** 720x576p\@200Hz */ + v720x576p_200Hz, + /** 720x576i\@200Hz */ + v720x576i_200Hz, + /** 720x480p\@240Hz */ + v720x480p_240Hz, + /** 720x480i\@240Hz */ + v720x480i_240Hz, + /** 1280x720p\@24Hz */ + v1280x720p_24Hz, + /** 1280x720p\@25Hz */ + v1280x720p_25Hz, + /** 1280x720p\@30Hz */ + v1280x720p_30Hz, + /** 1920x1080p\@120Hz */ + v1920x1080p_120Hz, + /** 1920x1080p\@100Hz */ + v1920x1080p_100Hz, + /** 4Kx2K\@30Hz */ + v4Kx2K_30Hz, +}; +#endif /* __HDMI_VIDEO_VIDEOFORMAT__ */ +#ifndef __HDMI_VIDEO_COLORSPACE__ +#define __HDMI_VIDEO_COLORSPACE__ +/** + * @enum ColorSpace + * Color space of video stream. + */ +enum ColorSpace { + /** RGB color space */ + HDMI_CS_RGB, + /** YCbCr 4:4:4 color space */ + HDMI_CS_YCBCR444, + /** YCbCr 4:2:2 color space */ + HDMI_CS_YCBCR422 +}; +#endif /* __HDMI_VIDEO_COLORSPACE__ */ + +#ifndef __HDMI_VIDEO_COLORDEPTH__ +#define __HDMI_VIDEO_COLORDEPTH__ +/** + * @enum ColorDepth + * Color depth per pixel of video stream + */ +enum ColorDepth { + /** 36 bit color depth per pixel */ + HDMI_CD_36, + /** 30 bit color depth per pixel */ + HDMI_CD_30, + /** 24 bit color depth per pixel */ + HDMI_CD_24 +}; +#endif /* __HDMI_VIDEO_COLORDEPTH__ */ + +#ifndef __HDMI_VIDEO_HDMIMODE__ +#define __HDMI_VIDEO_HDMIMODE__ +/** + * @enum HDMIMode + * System mode + */ +enum HDMIMode { + /** DVI mode */ + DVI = 0, + /** HDMI mode */ + HDMI +}; +#endif /* __HDMI_VIDEO_HDMIMODE__ */ + +#ifndef __HDMI_VIDEO_PIXELLIMIT__ +#define __HDMI_VIDEO_PIXELLIMIT__ +/** + * @enum PixelLimit + * Pixel limitation of video stream + */ +enum PixelLimit { + /** Full range */ + HDMI_FULL_RANGE, + /** Limit range for RGB color space */ + HDMI_RGB_LIMIT_RANGE, + /** Limit range for YCbCr color space */ + HDMI_YCBCR_LIMIT_RANGE +}; +#endif /* __HDMI_VIDEO_PIXELLIMIT__ */ + +#ifndef __HDMI_VIDEO_COLORIMETRY__ +#define __HDMI_VIDEO_COLORIMETRY__ +/** + * @enum HDMIColorimetry + * Colorimetry of video stream + */ +enum HDMIColorimetry { + /** Colorimetry is not defined */ + HDMI_COLORIMETRY_NO_DATA, + /** ITU601 colorimetry */ + HDMI_COLORIMETRY_ITU601, + /** ITU709 colorimetry */ + HDMI_COLORIMETRY_ITU709, + /** Extended ITU601 colorimetry */ + HDMI_COLORIMETRY_EXTENDED_xvYCC601, + /** Extended ITU709 colorimetry */ + HDMI_COLORIMETRY_EXTENDED_xvYCC709 +}; +#endif /* __HDMI_VIDEO_COLORIMETRY__ */ + +#ifndef __HDMI_VIDEO_PIXELASPECTRATIO__ +#define __HDMI_VIDEO_PIXELASPECTRATIO__ +/** + * @enum PixelAspectRatio + * Pixel aspect ratio of video stream + */ +enum PixelAspectRatio { + /** as picutre pixel ratio */ + HDMI_PIXEL_RATIO_AS_PICTURE, + /** 4:3 pixel ratio */ + HDMI_PIXEL_RATIO_4_3, + /** 16:9 pixel ratio */ + HDMI_PIXEL_RATIO_16_9 +}; +#endif /* __HDMI_VIDEO_PIXELASPECTRATIO__ */ + +#ifndef __HDMI_VIDEO_PIXELFREQUENCY__ +#define __HDMI_VIDEO_PIXELFREQUENCY__ +/** + * @enum PixelFreq + * Pixel Frequency + */ +enum PixelFreq { + /** 25.2 MHz pixel frequency */ + PIXEL_FREQ_25_200 = 2520, + /** 25.175 MHz pixel frequency */ + PIXEL_FREQ_25_175 = 2517, + /** 27 MHz pixel frequency */ + PIXEL_FREQ_27 = 2700, + /** 27.027 MHz pixel frequency */ + PIXEL_FREQ_27_027 = 2702, + /** 54 MHz pixel frequency */ + PIXEL_FREQ_54 = 5400, + /** 54.054 MHz pixel frequency */ + PIXEL_FREQ_54_054 = 5405, + /** 74.25 MHz pixel frequency */ + PIXEL_FREQ_74_250 = 7425, + /** 74.176 MHz pixel frequency */ + PIXEL_FREQ_74_176 = 7417, + /** 148.5 MHz pixel frequency */ + PIXEL_FREQ_148_500 = 14850, + /** 148.352 MHz pixel frequency */ + PIXEL_FREQ_148_352 = 14835, + /** 108.108 MHz pixel frequency */ + PIXEL_FREQ_108_108 = 10810, + /** 72 MHz pixel frequency */ + PIXEL_FREQ_72 = 7200, + /** 25 MHz pixel frequency */ + PIXEL_FREQ_25 = 2500, + /** 65 MHz pixel frequency */ + PIXEL_FREQ_65 = 6500, + /** 108 MHz pixel frequency */ + PIXEL_FREQ_108 = 10800, + /** 162 MHz pixel frequency */ + PIXEL_FREQ_162 = 16200, + /** 59.4 MHz pixel frequency */ + PIXEL_FREQ_59_400 = 5940, +}; +#endif /* __HDMI_VIDEO_PIXELFREQUENCY__ */ + +#ifndef __HDMI_PHY_PIXELFREQUENCY__ +#define __HDMI_PHY_PIXELFREQUENCY__ + +/** + * @enum PHYFreq + * PHY Frequency + */ +enum PHYFreq { + /** Not supported */ + PHY_FREQ_NOT_SUPPORTED = -1, + /** 25.2 MHz pixel frequency */ + PHY_FREQ_25_200 = 0, + /** 25.175 MHz pixel frequency */ + PHY_FREQ_25_175, + /** 27 MHz pixel frequency */ + PHY_FREQ_27, + /** 27.027 MHz pixel frequency */ + PHY_FREQ_27_027, + /** 54 MHz pixel frequency */ + PHY_FREQ_54, + /** 54.054 MHz pixel frequency */ + PHY_FREQ_54_054, + /** 74.25 MHz pixel frequency */ + PHY_FREQ_74_250, + /** 74.176 MHz pixel frequency */ + PHY_FREQ_74_176, + /** 148.5 MHz pixel frequency */ + PHY_FREQ_148_500, + /** 148.352 MHz pixel frequency */ + PHY_FREQ_148_352, + /** 108.108 MHz pixel frequency */ + PHY_FREQ_108_108, + /** 72 MHz pixel frequency */ + PHY_FREQ_72, + /** 25 MHz pixel frequency */ + PHY_FREQ_25, + /** 65 MHz pixel frequency */ + PHY_FREQ_65, + /** 108 MHz pixel frequency */ + PHY_FREQ_108, + /** 162 MHz pixel frequency */ + PHY_FREQ_162, + /** 59.4 MHz pixel frequency */ + PHY_FREQ_59_400, +}; + +#endif /* __HDMI_PHY_PIXELFREQUENCY__ */ + +#ifndef __HDMI_VIDEO_SOURCE__ +#define __HDMI_VIDEO_SOURCE__ +/** + * @enum HDMIVideoSource + * Type of video source. + */ +enum HDMIVideoSource { + /** Internal Video Source */ + HDMI_SOURCE_INTERNAL, + /** External Video Source */ + HDMI_SOURCE_EXTERNAL, +}; +#endif /* __HDMI_VIDEO_SOURCE__ */ + +#ifndef __HDMI_3D_VIDEO_STRUCTURE__ +#define __HDMI_3D_VIDEO_STRUCTURE__ +/** + * @enum HDMI3DVideoStructure + * Type of 3D Video Structure + */ +enum HDMI3DVideoStructure { + /** 2D Video Format */ + HDMI_2D_VIDEO_FORMAT = -1, + /** 3D Frame Packing Structure */ + HDMI_3D_FP_FORMAT = 0, + /** 3D Field Alternative Structure */ + HDMI_3D_FA_FORMAT, + /** 3D Line Alternative Structure */ + HDMI_3D_LA_FORMAT, + /** Side-by-Side(Full)Structure */ + HDMI_3D_SSF_FORMAT, + /** 3D L+Depth Structure */ + HDMI_3D_LD_FORMAT, + /** 3D L+Depth+Graphics Structure */ + HDMI_3D_LDGFX_FORMAT, + /** 3D Top-and-Bottom Structure */ + HDMI_3D_TB_FORMAT, + /** HDMI VIC Structure (ex. 4Kx2K) */ + HDMI_VIC_FORMAT, + /** Side-by-Side(Half)Structure */ + HDMI_3D_SSH_FORMAT, +}; +#endif /* __HDMI_3D_VIDEO_STRUCTURE__ */ + +#ifndef __HDMI_VIDEO_PARAMETER__ +#define __HDMI_VIDEO_PARAMETER__ +//! Structure for HDMI video +struct HDMIVideoParameter { + /** Video interface */ + enum HDMIMode mode; + /** Video format */ + enum VideoFormat resolution; + /** Color space */ + enum ColorSpace colorSpace; + /** Color depth */ + enum ColorDepth colorDepth; + /** Colorimetry */ + enum HDMIColorimetry colorimetry; + /** Pixel aspect ratio */ + enum PixelAspectRatio pixelAspectRatio; + /** Video Source */ + enum HDMIVideoSource videoSrc; + /** 3D Video Structure */ + enum HDMI3DVideoStructure hdmi_3d_format; +}; +#endif /* __HDMI_VIDEO_PARAMETER__*/ + +#ifdef __cplusplus +} +#endif +#endif /* _VIDEO_H_ */ diff --git a/exynos5/hal/include/videodev2.h b/exynos5/hal/include/videodev2.h new file mode 100644 index 0000000..48b3081 --- /dev/null +++ b/exynos5/hal/include/videodev2.h @@ -0,0 +1,2227 @@ +/* + * Video for Linux Two header file + * + * Copyright (C) 1999-2007 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The names of its contributors may not 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 AND FITNESS FOR + * A PARTICULAR PURPOSE 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. + * + * Header file for v4l or V4L2 drivers and applications + * with public API. + * All kernel-specific stuff were moved to media/v4l2-dev.h, so + * no #if __KERNEL tests are allowed here + * + * See http://linuxtv.org for more info + * + * Author: Bill Dirks + * Justin Schoeman + * Hans Verkuil + * et al. + */ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H + +#ifdef __KERNEL__ +#include /* need struct timeval */ +#else +#include +#endif +#include +#include +#include + +/* + * Common stuff for both V4L1 and V4L2 + * Moved from videodev.h + */ +#define VIDEO_MAX_FRAME 32 +#define VIDEO_MAX_PLANES 8 + +#ifndef __KERNEL__ + +/* These defines are V4L1 specific and should not be used with the V4L2 API! + They will be removed from this header in the future. */ + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ +#endif + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a, b, c, d)\ + ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ + V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field + first and the top field is + transmitted first */ + V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field + first and the bottom field is + transmitted first */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, + V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, +#if 1 + /* Experimental */ + V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, +#endif + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +#define V4L2_TYPE_IS_MULTIPLANAR(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + +#define V4L2_TYPE_IS_OUTPUT(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ + || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, + V4L2_TUNER_DIGITAL_TV = 3, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability { + __u8 driver[16]; /* i.e. "bttv" */ + __u8 card[32]; /* i.e. "Hauppauge WinTV" */ + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ + __u32 version; /* should use KERNEL_VERSION() */ + __u32 capabilities; /* Device capabilities */ + __u32 reserved[4]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ +#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ +#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ +#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ + +/* Is a video capture device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 +/* Is a video output device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ +#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format { + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ + +/* RGB formats */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ + +/* Grey formats */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ +#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ +#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ + +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + +/* Palette formats */ +#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ + +/* Luminance+Chrominance formats */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ +#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ +#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ +#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'U', 'V', 'M') /* 12 YUV420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'V', 'U', 'M') /* 12 YVU420 planar */ + +/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ + /* 10bit raw bayer DPCM compressed to 8 bits */ +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') + /* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ + + +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 */ +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ +#define V4L2_PIX_FMT_MPEG12 v4l2_fourcc('M', 'P', '1', '2') /* MPEG-1/2 */ +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 */ +#define V4L2_PIX_FMT_FIMV v4l2_fourcc('F', 'I', 'M', 'V') /* FIMV */ +#define V4L2_PIX_FMT_FIMV1 v4l2_fourcc('F', 'I', 'M', '1') /* FIMV1 */ +#define V4L2_PIX_FMT_FIMV2 v4l2_fourcc('F', 'I', 'M', '2') /* FIMV2 */ +#define V4L2_PIX_FMT_FIMV3 v4l2_fourcc('F', 'I', 'M', '3') /* FIMV3 */ +#define V4L2_PIX_FMT_FIMV4 v4l2_fourcc('F', 'I', 'M', '4') /* FIMV4 */ +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ +#define V4L2_PIX_FMT_VC1 v4l2_fourcc('V', 'C', '1', 'A') /* VC-1 */ +#define V4L2_PIX_FMT_VC1_RCV v4l2_fourcc('V', 'C', '1', 'R') /* VC-1 RCV */ +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ +#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ +#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ +#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ +#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ +#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ + +#define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4') /* yuv444 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2') /* yuv422 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0') /* yuv420 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G') /* grey of JFIF JPEG */ +#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P') /* 16 xxxxyyyy uuuuvvvv */ +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc { + __u32 index; /* Format number */ + enum v4l2_buf_type type; /* buffer type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 +#define V4L2_FMT_FLAG_EMULATED 0x0002 + +#if 1 + /* Experimental Frame Size and frame rate enumeration */ +/* + * F R A M E S I Z E E N U M E R A T I O N + */ +enum v4l2_frmsizetypes { + V4L2_FRMSIZE_TYPE_DISCRETE = 1, + V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, + V4L2_FRMSIZE_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmsize_discrete { + __u32 width; /* Frame width [pixel] */ + __u32 height; /* Frame height [pixel] */ +}; + +struct v4l2_frmsize_stepwise { + __u32 min_width; /* Minimum frame width [pixel] */ + __u32 max_width; /* Maximum frame width [pixel] */ + __u32 step_width; /* Frame width step size [pixel] */ + __u32 min_height; /* Minimum frame height [pixel] */ + __u32 max_height; /* Maximum frame height [pixel] */ + __u32 step_height; /* Frame height step size [pixel] */ +}; + +struct v4l2_frmsizeenum { + __u32 index; /* Frame size number */ + __u32 pixel_format; /* Pixel format */ + __u32 type; /* Frame size type the device supports. */ + + union { /* Frame size */ + struct v4l2_frmsize_discrete discrete; + struct v4l2_frmsize_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; + +/* + * F R A M E R A T E E N U M E R A T I O N + */ +enum v4l2_frmivaltypes { + V4L2_FRMIVAL_TYPE_DISCRETE = 1, + V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, + V4L2_FRMIVAL_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmival_stepwise { + struct v4l2_fract min; /* Minimum frame interval [s] */ + struct v4l2_fract max; /* Maximum frame interval [s] */ + struct v4l2_fract step; /* Frame interval step size [s] */ +}; + +struct v4l2_frmivalenum { + __u32 index; /* Frame format index */ + __u32 pixel_format; /* Pixel format */ + __u32 width; /* Frame width */ + __u32 height; /* Frame height */ + __u32 type; /* Frame interval type the device supports. */ + + union { /* Frame interval */ + struct v4l2_fract discrete; + struct v4l2_frmival_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; +#endif + +/* + * T I M E C O D E + */ +struct v4l2_timecode { + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + +struct v4l2_jpegcompression { + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer applications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers { + __u32 count; + enum v4l2_buf_type type; + enum v4l2_memory memory; + __u32 reserved[2]; +}; + +/** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) + * @length: size of this plane (NOT the payload) in bytes + * @mem_offset: when memory in the associated struct v4l2_buffer is + * V4L2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a "cookie" that + * should be passed to mmap() called on the video node) + * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * pointing to this plane + * @data_offset: offset in the plane to the start of data; usually 0, + * unless there is a header in front of the data + * + * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer + * with two planes can have one plane for Y, and another for interleaved CbCr + * components. Each plane can reside in a separate memory buffer, or even in + * a completely separate memory node (e.g. in embedded devices). + */ +struct v4l2_plane { + __u32 bytesused; + __u32 length; + union { + __u32 mem_offset; + unsigned long userptr; + } m; + __u32 data_offset; + void *cookie; + void *share; + __u32 reserved[9]; +}; + +/** + * struct v4l2_buffer - video buffer info + * @index: id number of the buffer + * @type: buffer type (type == *_MPLANE for multiplanar buffers) + * @bytesused: number of bytes occupied by data in the buffer (payload); + * unused (set to 0) for multiplanar buffers + * @flags: buffer informational flags + * @field: field order of the image in the buffer + * @timestamp: frame timestamp + * @timecode: frame timecode + * @sequence: sequence count of this frame + * @memory: the method, in which the actual video data is passed + * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; + * offset from the start of the device memory for this plane, + * (or a "cookie" that should be passed to mmap() as offset) + * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; + * a userspace pointer pointing to this buffer + * @planes: for multiplanar buffers; userspace pointer to the array of plane + * info structs for this buffer + * @length: size in bytes of the buffer (NOT its payload) for single-plane + * buffers (when type != *_MPLANE); number of elements in the + * planes array for multi-plane buffers + * @input: input number from which the video data has has been captured + * + * Contains data exchanged by application and driver using one of the Streaming + * I/O methods. + */ +struct v4l2_buffer { + __u32 index; + enum v4l2_buf_type type; + __u32 bytesused; + __u32 flags; + enum v4l2_field field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + enum v4l2_memory memory; + union { + __u32 offset; + unsigned long userptr; + struct v4l2_plane *planes; + } m; + __u32 length; + __u32 input; + __u32 reserved; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +/* Buffer is ready, but the data contained within is corrupted. */ +#define V4L2_BUF_FLAG_ERROR 0x0040 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ +#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer { + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void *base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 +#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 +#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 +#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 +#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 +#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 +#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 +#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 + +struct v4l2_clip { + struct v4l2_rect c; + struct v4l2_clip __user *next; +}; + +struct v4l2_window { + struct v4l2_rect w; + enum v4l2_field field; + __u32 chromakey; + struct v4l2_clip __user *clips; + __u32 clipcount; + void __user *bitmap; + __u8 global_alpha; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm { + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; + +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm { + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap { + enum v4l2_buf_type type; + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + enum v4l2_buf_type type; + struct v4l2_rect c; +}; + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) +#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) +#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* FIXME: + Although std_id is 64 bits, there is an issue on PPC32 architecture that + makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding + this value to 32 bits. + As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), + it should work fine. However, if needed to add more than two standards, + v4l2-common.c should be fixed. + */ + +/* some merged standards */ +#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) +#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) +#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) + +/* some common needed stuff */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1) +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_DK |\ + V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) + +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC |\ + V4L2_STD_NTSC_443) +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) +#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ + V4L2_STD_ATSC_16_VSB) + +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard { + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + +/* + * V I D E O T I M I N G S D V P R E S E T + */ +struct v4l2_dv_preset { + __u32 preset; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T S E N U M E R A T I O N + */ +struct v4l2_dv_enum_preset { + __u32 index; + __u32 preset; + __u8 name[32]; /* Name of the preset timing */ + __u32 width; + __u32 height; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T V A L U E S + */ +#define V4L2_DV_INVALID 0 +#define V4L2_DV_480P59_94 1 /* BT.1362 */ +#define V4L2_DV_576P50 2 /* BT.1362 */ +#define V4L2_DV_720P24 3 /* SMPTE 296M */ +#define V4L2_DV_720P25 4 /* SMPTE 296M */ +#define V4L2_DV_720P30 5 /* SMPTE 296M */ +#define V4L2_DV_720P50 6 /* SMPTE 296M */ +#define V4L2_DV_720P59_94 7 /* SMPTE 274M */ +#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ +#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I25 11 /* BT.1120 */ +#define V4L2_DV_1080I50 12 /* SMPTE 296M */ +#define V4L2_DV_1080I60 13 /* SMPTE 296M */ +#define V4L2_DV_1080P24 14 /* SMPTE 296M */ +#define V4L2_DV_1080P25 15 /* SMPTE 296M */ +#define V4L2_DV_1080P30 16 /* SMPTE 296M */ +#define V4L2_DV_1080P50 17 /* BT.1120 */ +#define V4L2_DV_1080P60 18 /* BT.1120 */ + +#define V4L2_DV_480P60 19 +#define V4L2_DV_1080I59_94 20 +#define V4L2_DV_1080P59_94 21 + +#define V4L2_DV_720P60_FP 22 +#define V4L2_DV_720P60_SB_HALF 23 +#define V4L2_DV_720P60_TB 24 +#define V4L2_DV_720P59_94_FP 25 +#define V4L2_DV_720P59_94_SB_HALF 26 +#define V4L2_DV_720P59_94_TB 27 +#define V4L2_DV_720P50_FP 28 +#define V4L2_DV_720P50_SB_HALF 29 +#define V4L2_DV_720P50_TB 30 +#define V4L2_DV_1080P24_FP 31 +#define V4L2_DV_1080P24_SB_HALF 32 +#define V4L2_DV_1080P24_TB 33 +#define V4L2_DV_1080P23_98_FP 34 +#define V4L2_DV_1080P23_98_SB_HALF 35 +#define V4L2_DV_1080P23_98_TB 36 +#define V4L2_DV_1080I60_SB_HALF 37 +#define V4L2_DV_1080I59_94_SB_HALF 38 +#define V4L2_DV_1080I50_SB_HALF 39 +#define V4L2_DV_1080P60_SB_HALF 40 +#define V4L2_DV_1080P60_TB 41 +#define V4L2_DV_1080P30_FP 42 +#define V4L2_DV_1080P30_SB_HALF 43 +#define V4L2_DV_1080P30_TB 44 + +/* + * D V B T T I M I N G S + */ + +/* BT.656/BT.1120 timing data */ +struct v4l2_bt_timings { + __u32 width; /* width in pixels */ + __u32 height; /* height in lines */ + __u32 interlaced; /* Interlaced or progressive */ + __u32 polarities; /* Positive or negative polarity */ + __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ + __u32 hfrontporch; /* Horizpontal front porch in pixels */ + __u32 hsync; /* Horizontal Sync length in pixels */ + __u32 hbackporch; /* Horizontal back porch in pixels */ + __u32 vfrontporch; /* Vertical front porch in pixels */ + __u32 vsync; /* Vertical Sync length in lines */ + __u32 vbackporch; /* Vertical back porch in lines */ + __u32 il_vfrontporch; /* Vertical front porch for bottom field of + * interlaced field formats + */ + __u32 il_vsync; /* Vertical sync length for bottom field of + * interlaced field formats + */ + __u32 il_vbackporch; /* Vertical back porch for bottom field of + * interlaced field formats + */ + __u32 reserved[16]; +} __attribute__ ((packed)); + +/* Interlaced or progressive format */ +#define V4L2_DV_PROGRESSIVE 0 +#define V4L2_DV_INTERLACED 1 + +/* Polarities. If bit is not set, it is assumed to be negative polarity */ +#define V4L2_DV_VSYNC_POS_POL 0x00000001 +#define V4L2_DV_HSYNC_POS_POL 0x00000002 + + +/* DV timings */ +struct v4l2_dv_timings { + __u32 type; + union { + struct v4l2_bt_timings bt; + __u32 reserved[32]; + }; +} __attribute__ ((packed)); + +/* Values for the type field */ +#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ + +/* + * V I D E O I N P U T S + */ +struct v4l2_input { + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 capabilities; + __u32 reserved[3]; +}; + +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - sensor orientation */ +/* If sensor is mounted upside down set both bits */ +#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ +#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* capabilities flags */ +#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output { + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 capabilities; + __u32 reserved[3]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* capabilities flags */ +#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * C O N T R O L S + */ +struct v4l2_control { + __u32 id; + __s32 value; +}; + +struct v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + }; +} __attribute__ ((packed)); + +struct v4l2_ext_controls { + __u32 ctrl_class; + __u32 count; + __u32 error_idx; + __u32 reserved[2]; + struct v4l2_ext_control *controls; +}; + +/* Values for ctrl_class field */ +#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ +#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ +#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ +#define V4L2_CTRL_CLASS_CODEC 0x009c0000 /* Codec control class */ + +#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, + V4L2_CTRL_TYPE_INTEGER64 = 5, + V4L2_CTRL_TYPE_CTRL_CLASS = 6, + V4L2_CTRL_TYPE_STRING = 7, +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl { + __u32 id; + enum v4l2_ctrl_type type; + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu { + __u32 id; + __u32 index; + __u8 name[32]; /* Whatever */ + __u32 reserved; +}; + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 + +/* Query flag, to be ORed with the control ID */ +#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 + +/* User-class control IDs defined by V4L2 */ +#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) + +/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) +#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, + V4L2_COLORFX_NEGATIVE = 3, + V4L2_COLORFX_EMBOSS = 4, + V4L2_COLORFX_SKETCH = 5, + V4L2_COLORFX_SKY_BLUE = 6, + V4L2_COLORFX_GRASS_GREEN = 7, + V4L2_COLORFX_SKIN_WHITEN = 8, + V4L2_COLORFX_VIVID = 9, +}; +#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) + +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) + +#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) + +#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) +#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) + +/* + * This is custom CID + */ +/* for rgb alpha function */ +#define V4L2_CID_GLOBAL_ALPHA (V4L2_CID_BASE+39) + +/* cacheable configuration */ +#define V4L2_CID_CACHEABLE (V4L2_CID_BASE+40) + +/* jpeg captured size */ +#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_BASE+41) +#define V4L2_CID_CAM_JPEG_ENCODEDSIZE (V4L2_CID_BASE+42) + +#define V4L2_CID_SET_SHAREABLE (V4L2_CID_BASE+43) + +/* TV configuration */ +#define V4L2_CID_TV_LAYER_BLEND_ENABLE (V4L2_CID_BASE+44) +#define V4L2_CID_TV_LAYER_BLEND_ALPHA (V4L2_CID_BASE+45) +#define V4L2_CID_TV_PIXEL_BLEND_ENABLE (V4L2_CID_BASE+46) +#define V4L2_CID_TV_CHROMA_ENABLE (V4L2_CID_BASE+47) +#define V4L2_CID_TV_CHROMA_VALUE (V4L2_CID_BASE+48) +#define V4L2_CID_TV_HPD_STATUS (V4L2_CID_BASE+49) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+50) + +/* MPEG-class control IDs defined by V4L2 */ +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) + +/* MPEG streams */ +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +enum v4l2_mpeg_stream_type { + V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ +}; +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +enum v4l2_mpeg_stream_vbi_fmt { + V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ + V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ +}; + +/* MPEG audio */ +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +enum v4l2_mpeg_audio_sampling_freq { + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +enum v4l2_mpeg_audio_encoding { + V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, +}; +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +enum v4l2_mpeg_audio_l1_bitrate { + V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, + V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, + V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, + V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, + V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, + V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, + V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, + V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, + V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, + V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, + V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, + V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, + V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +enum v4l2_mpeg_audio_l2_bitrate { + V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, + V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, + V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, + V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, + V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, + V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, + V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, + V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, + V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, + V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, + V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, + V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, + V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +enum v4l2_mpeg_audio_l3_bitrate { + V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +enum v4l2_mpeg_audio_mode { + V4L2_MPEG_AUDIO_MODE_STEREO = 0, + V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, + V4L2_MPEG_AUDIO_MODE_DUAL = 2, + V4L2_MPEG_AUDIO_MODE_MONO = 3, +}; +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +enum v4l2_mpeg_audio_mode_extension { + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, +}; +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +enum v4l2_mpeg_audio_emphasis { + V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, + V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +enum v4l2_mpeg_audio_crc { + V4L2_MPEG_AUDIO_CRC_NONE = 0, + V4L2_MPEG_AUDIO_CRC_CRC16 = 1, +}; +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; + +/* MPEG video */ +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +enum v4l2_mpeg_video_encoding { + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, +}; +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +enum v4l2_mpeg_video_aspect { + V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, + V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, + V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, + V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, +}; +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +enum v4l2_mpeg_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, +}; +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) + +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +enum v4l2_mpeg_cx2341x_video_median_filter_type { + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) + +/* For codecs */ + +#define V4L2_CID_CODEC_BASE (V4L2_CTRL_CLASS_CODEC | 0x900) +#define V4L2_CID_CODEC_CLASS (V4L2_CTRL_CLASS_CODEC | 1) + +/* Codec class control IDs specific to the MFC5X driver */ +#define V4L2_CID_CODEC_MFC5X_BASE (V4L2_CTRL_CLASS_CODEC | 0x1000) + +/* For both decoding and encoding */ + +/* For decoding */ + +#define V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE (V4L2_CID_CODEC_BASE + 110) +#define V4L2_CID_CODEC_DISPLAY_DELAY (V4L2_CID_CODEC_BASE + 137) +#define V4L2_CID_CODEC_REQ_NUM_BUFS (V4L2_CID_CODEC_BASE + 140) +#define V4L2_CID_CODEC_SLICE_INTERFACE (V4L2_CID_CODEC_BASE + 141) +#define V4L2_CID_CODEC_PACKED_PB (V4L2_CID_CODEC_BASE + 142) +#define V4L2_CID_CODEC_FRAME_TAG (V4L2_CID_CODEC_BASE + 143) +#define V4L2_CID_CODEC_CRC_ENABLE (V4L2_CID_CODEC_BASE + 144) +#define V4L2_CID_CODEC_CRC_DATA_LUMA (V4L2_CID_CODEC_BASE + 145) +#define V4L2_CID_CODEC_CRC_DATA_CHROMA (V4L2_CID_CODEC_BASE + 146) +#define V4L2_CID_CODEC_CRC_DATA_LUMA_BOT (V4L2_CID_CODEC_BASE + 147) +#define V4L2_CID_CODEC_CRC_DATA_CHROMA_BOT (V4L2_CID_CODEC_BASE + 148) +#define V4L2_CID_CODEC_CRC_GENERATED (V4L2_CID_CODEC_BASE + 149) +#define V4L2_CID_CODEC_FRAME_TYPE (V4L2_CID_CODEC_BASE + 154) +#define V4L2_CID_CODEC_CHECK_STATE (V4L2_CID_CODEC_BASE + 155) +#define V4L2_CID_CODEC_DISPLAY_STATUS (V4L2_CID_CODEC_BASE + 156) +#define V4L2_CID_CODEC_FRAME_PACK_SEI_PARSE (V4L2_CID_CODEC_BASE + 157) +#define V4L2_CID_CODEC_FRAME_PACK_SEI_AVAIL (V4L2_CID_CODEC_BASE + 158) +#define V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_ID (V4L2_CID_CODEC_BASE + 159) +#define V4L2_CID_CODEC_FRAME_PACK_SEI_INFO (V4L2_CID_CODEC_BASE + 160) +#define V4L2_CID_CODEC_FRAME_PACK_GRID_POS (V4L2_CID_CODEC_BASE + 161) + +/* For encoding */ +#define V4L2_CID_CODEC_LOOP_FILTER_H264 (V4L2_CID_CODEC_BASE + 9) +enum v4l2_cid_codec_loop_filter_h264 { + V4L2_CID_CODEC_LOOP_FILTER_H264_ENABLE = 0, + V4L2_CID_CODEC_LOOP_FILTER_H264_DISABLE = 1, + V4L2_CID_CODEC_LOOP_FILTER_H264_DISABLE_AT_BOUNDARY = 2, +}; + +#define V4L2_CID_CODEC_FRAME_INSERTION (V4L2_CID_CODEC_BASE + 10) +enum v4l2_cid_codec_frame_insertion { + V4L2_CID_CODEC_FRAME_INSERT_NONE = 0x0, + V4L2_CID_CODEC_FRAME_INSERT_I_FRAME = 0x1, + V4L2_CID_CODEC_FRAME_INSERT_NOT_CODED = 0x2, +}; + +#define V4L2_CID_CODEC_ENCODED_LUMA_ADDR (V4L2_CID_CODEC_BASE + 11) +#define V4L2_CID_CODEC_ENCODED_CHROMA_ADDR (V4L2_CID_CODEC_BASE + 12) + +#define V4L2_CID_CODEC_ENCODED_I_PERIOD_CH V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE +#define V4L2_CID_CODEC_ENCODED_FRAME_RATE_CH V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE +#define V4L2_CID_CODEC_ENCODED_BIT_RATE_CH V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE + +#define V4L2_CID_CODEC_FRAME_PACK_SEI_GEN (V4L2_CID_CODEC_BASE + 13) +#define V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG (V4L2_CID_CODEC_BASE + 14) +enum v4l2_codec_mfc5x_enc_flag { + V4L2_CODEC_MFC5X_ENC_FLAG_DISABLE = 0, + V4L2_CODEC_MFC5X_ENC_FLAG_ENABLE = 1, +}; +#define V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE (V4L2_CID_CODEC_BASE + 15) +enum v4l2_codec_mfc5x_enc_frame_pack_arrgment_type { + V4L2_CODEC_MFC5X_ENC_FRAME_PACK_SIDE_BY_SIDE = 0, + V4L2_CODEC_MFC5X_ENC_FRAME_PACK_TOP_AND_BOT = 1, + V4L2_CODEC_MFC5X_ENC_FRAME_PACK_TMP_INTER = 2, +}; + +/* common */ +enum v4l2_codec_mfc5x_enc_switch { + V4L2_CODEC_MFC5X_ENC_SW_DISABLE = 0, + V4L2_CODEC_MFC5X_ENC_SW_ENABLE = 1, +}; +enum v4l2_codec_mfc5x_enc_switch_inv { + V4L2_CODEC_MFC5X_ENC_SW_INV_ENABLE = 0, + V4L2_CODEC_MFC5X_ENC_SW_INV_DISABLE = 1, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE (V4L2_CID_CODEC_MFC5X_BASE+300) +#define V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE (V4L2_CID_CODEC_MFC5X_BASE+301) +enum v4l2_codec_mfc5x_enc_multi_slice_mode { + V4L2_CODEC_MFC5X_ENC_MULTI_SLICE_MODE_DISABLE = 0, + V4L2_CODEC_MFC5X_ENC_MULTI_SLICE_MODE_MACROBLOCK_COUNT = 1, + V4L2_CODEC_MFC5X_ENC_MULTI_SLICE_MODE_BIT_COUNT = 3, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB (V4L2_CID_CODEC_MFC5X_BASE+302) +#define V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT (V4L2_CID_CODEC_MFC5X_BASE+303) +#define V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB (V4L2_CID_CODEC_MFC5X_BASE+304) +#define V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+305) +#define V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE (V4L2_CID_CODEC_MFC5X_BASE+306) +#define V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE (V4L2_CID_CODEC_MFC5X_BASE+307) +#define V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE (V4L2_CID_CODEC_MFC5X_BASE+308) +#define V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+309) +#define V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE (V4L2_CID_CODEC_MFC5X_BASE+310) +#define V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF (V4L2_CID_CODEC_MFC5X_BASE+311) +#define V4L2_CID_CODEC_MFC5X_ENC_STREAM_SIZE (V4L2_CID_CODEC_MFC5X_BASE+312) +#define V4L2_CID_CODEC_MFC5X_ENC_FRAME_COUNT (V4L2_CID_CODEC_MFC5X_BASE+313) +#define V4L2_CID_CODEC_MFC5X_ENC_FRAME_TYPE (V4L2_CID_CODEC_MFC5X_BASE+314) +enum v4l2_codec_mfc5x_enc_frame_type { + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_NOT_CODED = 0, + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_I_FRAME = 1, + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_P_FRAME = 2, + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_B_FRAME = 3, + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_SKIPPED = 4, + V4L2_CODEC_MFC5X_ENC_FRAME_TYPE_OTHERS = 5, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_FORCE_FRAME_TYPE (V4L2_CID_CODEC_MFC5X_BASE+315) +enum v4l2_codec_mfc5x_enc_force_frame_type { + V4L2_CODEC_MFC5X_ENC_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_CODEC_MFC5X_ENC_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE (V4L2_CID_CODEC_MFC5X_BASE+316) +#define V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE (V4L2_CID_CODEC_MFC5X_BASE+317) +enum v4l2_codec_mfc5x_enc_seq_hdr_mode { + V4L2_CODEC_MFC5X_ENC_SEQ_HDR_MODE_SEQ = 0, + V4L2_CODEC_MFC5X_ENC_SEQ_HDR_MODE_SEQ_FRAME = 1, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE (V4L2_CID_CODEC_MFC5X_BASE+318) +enum v4l2_codec_mfc5x_enc_frame_skip_mode { + V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE = 0, + V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL = 1, + V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE = 2, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT (V4L2_CID_CODEC_MFC5X_BASE+319) +#define V4L2_CID_CODEC_MFC5X_ENC_FRAME_DELTA (V4L2_CID_CODEC_MFC5X_BASE+320) + +/* codec specific */ +#define V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES (V4L2_CID_CODEC_MFC5X_BASE+400) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE (V4L2_CID_CODEC_MFC5X_BASE+401) +enum v4l2_codec_mfc5x_enc_h264_profile { + V4L2_CODEC_MFC5X_ENC_H264_PROFILE_MAIN = 0, + V4L2_CODEC_MFC5X_ENC_H264_PROFILE_HIGH = 1, + V4L2_CODEC_MFC5X_ENC_H264_PROFILE_BASELINE = 2, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL (V4L2_CID_CODEC_MFC5X_BASE+402) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE (V4L2_CID_CODEC_MFC5X_BASE+403) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE (V4L2_CID_CODEC_MFC5X_BASE+404) +enum v4l2_codec_mfc5x_enc_h264_loop_filter { + V4L2_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ENABLE = 0, + V4L2_CODEC_MFC5X_ENC_H264_LOOP_FILTER_DISABLE = 1, + V4L2_CODEC_MFC5X_ENC_H264_LOOP_FILTER_DISABLE_AT_BOUNDARY = 2, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA (V4L2_CID_CODEC_MFC5X_BASE+405) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA (V4L2_CID_CODEC_MFC5X_BASE+406) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE (V4L2_CID_CODEC_MFC5X_BASE+407) +enum v4l2_codec_mfc5x_enc_h264_entropy_mode { + V4L2_CODEC_MFC5X_ENC_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_CODEC_MFC5X_ENC_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC (V4L2_CID_CODEC_MFC5X_BASE+408) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P (V4L2_CID_CODEC_MFC5X_BASE+409) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM (V4L2_CID_CODEC_MFC5X_BASE+410) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+411) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE (V4L2_CID_CODEC_MFC5X_BASE+412) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+413) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP (V4L2_CID_CODEC_MFC5X_BASE+414) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP (V4L2_CID_CODEC_MFC5X_BASE+415) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK (V4L2_CID_CODEC_MFC5X_BASE+416) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH (V4L2_CID_CODEC_MFC5X_BASE+417) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC (V4L2_CID_CODEC_MFC5X_BASE+418) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY (V4L2_CID_CODEC_MFC5X_BASE+419) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+420) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+421) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+422) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC (V4L2_CID_CODEC_MFC5X_BASE+423) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH (V4L2_CID_CODEC_MFC5X_BASE+424) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT (V4L2_CID_CODEC_MFC5X_BASE+425) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP (V4L2_CID_CODEC_MFC5X_BASE+426) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD (V4L2_CID_CODEC_MFC5X_BASE+427) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+428) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP (V4L2_CID_CODEC_MFC5X_BASE+429) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP (V4L2_CID_CODEC_MFC5X_BASE+430) +#define V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP (V4L2_CID_CODEC_MFC5X_BASE+431) + +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES (V4L2_CID_CODEC_MFC5X_BASE+440) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE (V4L2_CID_CODEC_MFC5X_BASE+441) +enum v4l2_codec_mfc5x_enc_mpeg4_profile { + V4L2_CODEC_MFC5X_ENC_MPEG4_PROFILE_SIMPLE = 0, + V4L2_CODEC_MFC5X_ENC_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, +}; +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL (V4L2_CID_CODEC_MFC5X_BASE+442) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+443) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP (V4L2_CID_CODEC_MFC5X_BASE+444) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP (V4L2_CID_CODEC_MFC5X_BASE+445) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL (V4L2_CID_CODEC_MFC5X_BASE+446) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+447) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+448) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES (V4L2_CID_CODEC_MFC5X_BASE+449) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA (V4L2_CID_CODEC_MFC5X_BASE+450) +#define V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MB_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+451) + +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE (V4L2_CID_CODEC_MFC5X_BASE+460) +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+461) +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP (V4L2_CID_CODEC_MFC5X_BASE+462) +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP (V4L2_CID_CODEC_MFC5X_BASE+463) +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP (V4L2_CID_CODEC_MFC5X_BASE+464) +#define V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MB_ENABLE (V4L2_CID_CODEC_MFC5X_BASE+465) + +/* Camera class control IDs */ +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + +#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) +#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) + +/* FM Modulator class control IDs */ +#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) +#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) + +#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) +#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) +#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) +#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) +#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) + +#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) +#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) +#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) + +#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) +#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) +#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) +#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) +#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) + +#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) +#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) +#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) + +#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) +enum v4l2_preemphasis { + V4L2_PREEMPHASIS_DISABLED = 0, + V4L2_PREEMPHASIS_50_uS = 1, + V4L2_PREEMPHASIS_75_uS = 2, +}; +#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) +#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) + +/* + * T U N I N G + */ +struct v4l2_tuner { + __u32 index; + __u8 name[32]; + enum v4l2_tuner_type type; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 +#define V4L2_TUNER_CAP_RDS 0x0080 +#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 +#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 +#define V4L2_TUNER_SUB_RDS 0x0010 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 +#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 + +struct v4l2_frequency { + __u32 tuner; + enum v4l2_tuner_type type; + __u32 frequency; + __u32 reserved[8]; +}; + +struct v4l2_hw_freq_seek { + __u32 tuner; + enum v4l2_tuner_type type; + __u32 seek_upward; + __u32 wrap_around; + __u32 spacing; + __u32 reserved[7]; +}; + +/* + * R D S + */ + +struct v4l2_rds_data { + __u8 lsb; + __u8 msb; + __u8 block; +} __attribute__ ((packed)); + +#define V4L2_RDS_BLOCK_MSK 0x7 +#define V4L2_RDS_BLOCK_A 0 +#define V4L2_RDS_BLOCK_B 1 +#define V4L2_RDS_BLOCK_C 2 +#define V4L2_RDS_BLOCK_D 3 +#define V4L2_RDS_BLOCK_C_ALT 4 +#define V4L2_RDS_BLOCK_INVALID 7 + +#define V4L2_RDS_BLOCK_CORRECTED 0x40 +#define V4L2_RDS_BLOCK_ERROR 0x80 + +/* + * A U D I O + */ +struct v4l2_audio { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * M P E G S E R V I C E S + * + * NOTE: EXPERIMENTAL API + */ +#if 1 +#define V4L2_ENC_IDX_FRAME_I (0) +#define V4L2_ENC_IDX_FRAME_P (1) +#define V4L2_ENC_IDX_FRAME_B (2) +#define V4L2_ENC_IDX_FRAME_MASK (0xf) + +struct v4l2_enc_idx_entry { + __u64 offset; + __u64 pts; + __u32 length; + __u32 flags; + __u32 reserved[2]; +}; + +#define V4L2_ENC_IDX_ENTRIES (64) +struct v4l2_enc_idx { + __u32 entries; + __u32 entries_cap; + __u32 reserved[4]; + struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; +}; + + +#define V4L2_ENC_CMD_START (0) +#define V4L2_ENC_CMD_STOP (1) +#define V4L2_ENC_CMD_PAUSE (2) +#define V4L2_ENC_CMD_RESUME (3) + +/* Flags for V4L2_ENC_CMD_STOP */ +#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) + +struct v4l2_encoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u32 data[8]; + } raw; + }; +}; + +#endif + + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +/* Raw VBI */ +struct v4l2_vbi_format { + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1 << 0) +#define V4L2_VBI_INTERLACED (1 << 1) + +/* Sliced VBI + * + * This implements is a proposal V4L2 API to allow SLICED VBI + * required for some hardware encoders. It should change without + * notice in the definitive implementation. + */ + +struct v4l2_sliced_vbi_format { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 io_size; + __u32 reserved[2]; /* must be zero */ +}; + +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_B (0x0001) +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x0400) +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x1000) +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x4000) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) + +struct v4l2_sliced_vbi_cap { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + enum v4l2_buf_type type; + __u32 reserved[3]; /* must be 0 */ +}; + +struct v4l2_sliced_vbi_data { + __u32 id; + __u32 field; /* 0: first field, 1: second field */ + __u32 line; /* 1-23 */ + __u32 reserved; /* must be 0 */ + __u8 data[48]; +}; + +/* + * Sliced VBI data inserted into MPEG Streams + */ + +/* + * V4L2_MPEG_STREAM_VBI_FMT_IVTV: + * + * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an + * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI + * data + * + * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header + * definitions are not included here. See the MPEG-2 specifications for details + * on these headers. + */ + +/* Line type IDs */ +#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) +#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) +#define V4L2_MPEG_VBI_IVTV_WSS_625 (5) +#define V4L2_MPEG_VBI_IVTV_VPS (7) + +struct v4l2_mpeg_vbi_itv0_line { + __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ + __u8 data[42]; /* Sliced VBI data for the line */ +} __attribute__ ((packed)); + +struct v4l2_mpeg_vbi_itv0 { + __le32 linemask[2]; /* Bitmasks of VBI service lines present */ + struct v4l2_mpeg_vbi_itv0_line line[35]; +} __attribute__ ((packed)); + +struct v4l2_mpeg_vbi_ITV0 { + struct v4l2_mpeg_vbi_itv0_line line[36]; +} __attribute__ ((packed)); + +#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" +#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" + +struct v4l2_mpeg_vbi_fmt_ivtv { + __u8 magic[4]; + union { + struct v4l2_mpeg_vbi_itv0 itv0; + struct v4l2_mpeg_vbi_ITV0 ITV0; + }; +} __attribute__ ((packed)); + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/** + * struct v4l2_plane_pix_format - additional, per-plane format definition + * @sizeimage: maximum size in bytes required for data, for which + * this plane will be used + * @bytesperline: distance in bytes between the leftmost pixels in two + * adjacent lines + */ +struct v4l2_plane_pix_format { + __u32 sizeimage; + __u16 bytesperline; + __u16 reserved[7]; +} __attribute__ ((packed)); + +/** + * struct v4l2_pix_format_mplane - multiplanar format definition + * @width: image width in pixels + * @height: image height in pixels + * @pixelformat: little endian four character code (fourcc) + * @field: field order (for interlaced video) + * @colorspace: supplemental to pixelformat + * @plane_fmt: per-plane information + * @num_planes: number of planes for this format + */ +struct v4l2_pix_format_mplane { + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + enum v4l2_colorspace colorspace; + + struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; + __u8 num_planes; + __u8 reserved[11]; +} __attribute__ ((packed)); + +/** + * struct v4l2_format - stream data format + * @type: type of the data stream + * @pix: definition of an image format + * @pix_mp: definition of a multiplanar image format + * @win: definition of an overlaid image + * @vbi: raw VBI capture or output parameters + * @sliced: sliced VBI capture or output parameters + * @raw_data: placeholder for future extensions and custom formats + */ +struct v4l2_format { + enum v4l2_buf_type type; + union { + struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ + struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ + struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ + struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ + struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm { + enum v4l2_buf_type type; + union { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + +/* + * E V E N T S + */ + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_VSYNC 1 +#define V4L2_EVENT_EOS 2 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* Payload for V4L2_EVENT_VSYNC */ +struct v4l2_event_vsync { + /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ + __u8 field; +} __attribute__ ((packed)); + +struct v4l2_event { + __u32 type; + union { + struct v4l2_event_vsync vsync; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + struct timespec timestamp; + __u32 reserved[9]; +}; + +struct v4l2_event_subscription { + __u32 type; + __u32 reserved[7]; +}; + +/* + * A D V A N C E D D E B U G G I N G + * + * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! + * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! + */ + +/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ + +#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ +#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ +#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ + +struct v4l2_dbg_match { + __u32 type; /* Match type */ + union { /* Match this chip, meaning determined by type */ + __u32 addr; + char name[32]; + }; +} __attribute__ ((packed)); + +struct v4l2_dbg_register { + struct v4l2_dbg_match match; + __u32 size; /* register size in bytes */ + __u64 reg; + __u64 val; +} __attribute__ ((packed)); + +/* VIDIOC_DBG_G_CHIP_IDENT */ +struct v4l2_dbg_chip_ident { + struct v4l2_dbg_match match; + __u32 ident; /* chip identifier as specified in */ + __u32 revision; /* chip revision, chip specific */ +} __attribute__ ((packed)); + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO('V', 1) +#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) +#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW('V', 14, int) +#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW('V', 18, int) +#define VIDIOC_STREAMOFF _IOW('V', 19, int) +#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR('V', 38, int) +#define VIDIOC_S_INPUT _IOWR('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority) +#define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority) +#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) +#define VIDIOC_LOG_STATUS _IO('V', 70) +#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) +#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) +#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) +#if 1 +#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) +#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) +#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) +#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) +#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) +#endif + +#if 1 +/* Experimental, meant for debugging, testing and internal use. + Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + You must be root to use these ioctls. Never use these in applications! */ +#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) +#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) + +/* Experimental, meant for debugging, testing and internal use. + Never use this ioctl in applications! */ +#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) +#endif + +#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) +#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) +#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) +#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) +#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) +#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) +#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) + +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + +#endif /* __LINUX_VIDEODEV2_H */ diff --git a/exynos5/hal/include/videodev2_samsung.h b/exynos5/hal/include/videodev2_samsung.h new file mode 100644 index 0000000..f93688c --- /dev/null +++ b/exynos5/hal/include/videodev2_samsung.h @@ -0,0 +1,1060 @@ +/* + * Video for Linux Two header file for samsung + * + * Copyright (C) 2009, Dongsoo Nathaniel Kim + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until bein accepted, will be used restrictly in Samsung's + * camera interface driver FIMC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LINUX_VIDEODEV2_SAMSUNG_H +#define __LINUX_VIDEODEV2_SAMSUNG_H + +/* Values for 'capabilities' field */ +/* Object detection device */ +#define V4L2_CAP_OBJ_RECOGNITION 0x10000000 +/* strobe control */ +#define V4L2_CAP_STROBE 0x20000000 + +#define V4L2_CID_FOCUS_MODE (V4L2_CID_CAMERA_CLASS_BASE+17) +/* Focus Methods */ +enum v4l2_focus_mode { + V4L2_FOCUS_MODE_AUTO = 0, + V4L2_FOCUS_MODE_MACRO = 1, + V4L2_FOCUS_MODE_MANUAL = 2, + V4L2_FOCUS_MODE_LASTP = 2, +}; + +#define V4L2_CID_ZOOM_MODE (V4L2_CID_CAMERA_CLASS_BASE+18) +/* Zoom Methods */ +enum v4l2_zoom_mode { + V4L2_ZOOM_MODE_CONTINUOUS = 0, + V4L2_ZOOM_MODE_OPTICAL = 1, + V4L2_ZOOM_MODE_DIGITAL = 2, + V4L2_ZOOM_MODE_LASTP = 2, +}; + +/* Exposure Methods */ +#define V4L2_CID_PHOTOMETRY (V4L2_CID_CAMERA_CLASS_BASE+19) +enum v4l2_photometry_mode { + V4L2_PHOTOMETRY_MULTISEG = 0, /*Multi Segment*/ + V4L2_PHOTOMETRY_CWA = 1, /*Centre Weighted Average*/ + V4L2_PHOTOMETRY_SPOT = 2, + V4L2_PHOTOMETRY_AFSPOT = 3, /*Spot metering on focused point*/ + V4L2_PHOTOMETRY_LASTP = V4L2_PHOTOMETRY_AFSPOT, +}; + +/* Manual exposure control items menu type: iris, shutter, iso */ +#define V4L2_CID_CAM_APERTURE (V4L2_CID_CAMERA_CLASS_BASE+20) +#define V4L2_CID_CAM_SHUTTER (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_CAM_ISO (V4L2_CID_CAMERA_CLASS_BASE+22) + +/* Following CIDs are menu type */ +#define V4L2_CID_SCENEMODE (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_CAM_STABILIZE (V4L2_CID_CAMERA_CLASS_BASE+24) +#define V4L2_CID_CAM_MULTISHOT (V4L2_CID_CAMERA_CLASS_BASE+25) + +/* Control dynamic range */ +#define V4L2_CID_CAM_DR (V4L2_CID_CAMERA_CLASS_BASE+26) + +/* White balance preset control */ +#define V4L2_CID_WHITE_BALANCE_PRESET (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_CID_CAM_SENSOR_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 28) +#define V4L2_CID_CAM_PHONE_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 29) + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5) +#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_DST_INFO (V4L2_CID_PRIVATE_BASE + 10) +/* UMP secure id control */ +#define V4L2_CID_GET_UMP_SECURE_ID (V4L2_CID_PRIVATE_BASE + 11) +#define V4L2_CID_GET_PHY_SRC_YADDR (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_GET_PHY_SRC_CADDR (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_IMAGE_EFFECT_FN (V4L2_CID_PRIVATE_BASE + 16) +#define V4L2_CID_IMAGE_EFFECT_APPLY (V4L2_CID_PRIVATE_BASE + 17) +#define V4L2_CID_IMAGE_EFFECT_CB (V4L2_CID_PRIVATE_BASE + 18) +#define V4L2_CID_IMAGE_EFFECT_CR (V4L2_CID_PRIVATE_BASE + 19) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) + +/* CID Extensions for camera sensor operations */ +#define V4L2_CID_CAM_PREVIEW_ONOFF (V4L2_CID_PRIVATE_BASE + 64) +#define V4L2_CID_CAM_CAPTURE (V4L2_CID_PRIVATE_BASE + 65) +//#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_PRIVATE_BASE + 66) + +#define V4L2_CID_CAM_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 14) +#define V4L2_CID_CAM_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 15) +#define V4L2_CID_CAM_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 22) +#define V4L2_CID_CAM_SENSOR_VER (V4L2_CID_PRIVATE_BASE + 23) +#define V4L2_CID_CAM_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 24) +#define V4L2_CID_CAM_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 25) +#define V4L2_CID_CAM_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 26) +#define V4L2_CID_CAM_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 27) +#define V4L2_CID_CAM_FW_VER (V4L2_CID_PRIVATE_BASE + 28) +#define V4L2_CID_CAM_SET_FW_ADDR (V4L2_CID_PRIVATE_BASE + 29) +#define V4L2_CID_CAM_SET_FW_SIZE (V4L2_CID_PRIVATE_BASE + 30) +#define V4L2_CID_CAM_UPDATE_FW (V4L2_CID_PRIVATE_BASE + 31) +enum v4l2_firmware_mode { + FW_MODE_UPDATE, + FW_MODE_VERSION, + FW_MODE_DUMP, +}; + +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) +#define V4L2_CID_CAM_SENSOR_MAKER (V4L2_CID_PRIVATE_BASE + 38) +#define V4L2_CID_CAM_SENSOR_OPTICAL (V4L2_CID_PRIVATE_BASE + 39) +#define V4L2_CID_CAM_AF_VER_LOW (V4L2_CID_PRIVATE_BASE + 40) +#define V4L2_CID_CAM_AF_VER_HIGH (V4L2_CID_PRIVATE_BASE + 41) +#define V4L2_CID_CAM_GAMMA_RG_LOW (V4L2_CID_PRIVATE_BASE + 42) +#define V4L2_CID_CAM_GAMMA_RG_HIGH (V4L2_CID_PRIVATE_BASE + 43) +#define V4L2_CID_CAM_GAMMA_BG_LOW (V4L2_CID_PRIVATE_BASE + 44) +#define V4L2_CID_CAM_GAMMA_BG_HIGH (V4L2_CID_PRIVATE_BASE + 45) +#define V4L2_CID_CAM_DUMP_FW (V4L2_CID_PRIVATE_BASE + 46) +#define V4L2_CID_CAM_GET_DUMP_SIZE (V4L2_CID_PRIVATE_BASE + 47) +#define V4L2_CID_CAMERA_VT_MODE (V4L2_CID_PRIVATE_BASE + 48) +#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49) +#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50) +#define V4L2_CID_CAMERA_HDR (V4L2_CID_PRIVATE_BASE + 51) + +#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54) +#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55) +#define V4L2_CID_MAIN_SW_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 56) +#define V4L2_CID_MAIN_SW_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 57) +#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58) +#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59) +#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60) + +#define V4L2_CID_FIMC_IS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x1000) + +#define V4L2_CID_IS_LOAD_FW (V4L2_CID_FIMC_IS_BASE + 10) +#define V4L2_CID_IS_INIT_PARAM (V4L2_CID_FIMC_IS_BASE + 11) +#define V4L2_CID_IS_RESET (V4L2_CID_FIMC_IS_BASE + 12) +#define V4L2_CID_IS_S_POWER (V4L2_CID_FIMC_IS_BASE + 13) +enum is_set_power { + IS_POWER_OFF, + IS_POWER_ON +}; + +#define V4L2_CID_IS_S_STREAM (V4L2_CID_FIMC_IS_BASE + 14) +enum is_set_stream { + IS_DISABLE_STREAM, + IS_ENABLE_STREAM +}; + +#define V4L2_CID_IS_S_SCENARIO_MODE (V4L2_CID_FIMC_IS_BASE + 15) +#define V4L2_CID_IS_S_FORMAT_SCENARIO (V4L2_CID_FIMC_IS_BASE + 16) +enum scenario_mode { + IS_MODE_PREVIEW_STILL, + IS_MODE_PREVIEW_VIDEO, + IS_MODE_CAPTURE_STILL, + IS_MODE_CAPTURE_VIDEO, + IS_MODE_MAX +}; + +/* global */ +#define V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL (V4L2_CID_FIMC_IS_BASE + 101) +/* value : 1 : single shot , >=2 : continuous shot */ + +#define V4L2_CID_IS_CAMERA_SENSOR_NUM (V4L2_CID_FIMC_IS_BASE + 201) +#define V4L2_CID_IS_CAMERA_FOCUS_MODE (V4L2_CID_FIMC_IS_BASE + 401) +enum is_focus_mode { + IS_FOCUS_MODE_AUTO, + IS_FOCUS_MODE_MACRO, + IS_FOCUS_MODE_INFINITY, + IS_FOCUS_MODE_CONTINUOUS, + IS_FOCUS_MODE_TOUCH, + IS_FOCUS_MODE_FACEDETECT, + IS_FOCUS_MODE_MAX, +}; + +#define V4L2_CID_IS_CAMERA_FLASH_MODE (V4L2_CID_FIMC_IS_BASE + 402) +enum is_flash_mode { + IS_FLASH_MODE_OFF, + IS_FLASH_MODE_AUTO, + IS_FLASH_MODE_AUTO_REDEYE, + IS_FLASH_MODE_ON, + IS_FLASH_MODE_TORCH, + IS_FLASH_MODE_MAX +}; + +#define V4L2_CID_IS_CAMERA_AWB_MODE (V4L2_CID_FIMC_IS_BASE + 403) +enum is_awb_mode { + IS_AWB_AUTO, + IS_AWB_DAYLIGHT, + IS_AWB_CLOUDY, + IS_AWB_TUNGSTEN, + IS_AWB_FLUORESCENT, + IS_AWB_MAX +}; + +#define V4L2_CID_IS_CAMERA_IMAGE_EFFECT (V4L2_CID_FIMC_IS_BASE + 404) +enum is_image_effect { + IS_IMAGE_EFFECT_DISABLE, + IS_IMAGE_EFFECT_MONOCHROME, + IS_IMAGE_EFFECT_NEGATIVE_MONO, + IS_IMAGE_EFFECT_NEGATIVE_COLOR, + IS_IMAGE_EFFECT_SEPIA, + IS_IMAGE_EFFECT_SEPIA_CB, + IS_IMAGE_EFFECT_SEPIA_CR, + IS_IMAGE_EFFECT_NEGATIVE, + IS_IMAGE_EFFECT_ARTFREEZE, + IS_IMAGE_EFFECT_EMBOSSING, + IS_IMAGE_EFFECT_SILHOUETTE, + IS_IMAGE_EFFECT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISO (V4L2_CID_FIMC_IS_BASE + 405) +enum is_iso { + IS_ISO_AUTO, + IS_ISO_50, + IS_ISO_100, + IS_ISO_200, + IS_ISO_400, + IS_ISO_800, + IS_ISO_1600, + IS_ISO_MAX +}; + +#define V4L2_CID_IS_CAMERA_CONTRAST (V4L2_CID_FIMC_IS_BASE + 406) +enum is_contrast { + IS_CONTRAST_AUTO, + IS_CONTRAST_MINUS_2, + IS_CONTRAST_MINUS_1, + IS_CONTRAST_DEFAULT, + IS_CONTRAST_PLUS_1, + IS_CONTRAST_PLUS_2, + IS_CONTRAST_MAX +}; + +#define V4L2_CID_IS_CAMERA_SATURATION (V4L2_CID_FIMC_IS_BASE + 407) +enum is_saturation { + IS_SATURATION_MINUS_2, + IS_SATURATION_MINUS_1, + IS_SATURATION_DEFAULT, + IS_SATURATION_PLUS1, + IS_SATURATION_PLUS2, + IS_SATURATION_MAX +}; + +#define V4L2_CID_IS_CAMERA_SHARPNESS (V4L2_CID_FIMC_IS_BASE + 408) +enum is_sharpness { + IS_SHARPNESS_MINUS_2, + IS_SHARPNESS_MINUS_1, + IS_SHARPNESS_DEFAULT, + IS_SHARPNESS_PLUS1, + IS_SHARPNESS_PLUS2, + IS_SHARPNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_EXPOSURE (V4L2_CID_FIMC_IS_BASE + 409) +enum is_exposure { + IS_EXPOSURE_MINUS_2, + IS_EXPOSURE_MINUS_1, + IS_EXPOSURE_DEFAULT, + IS_EXPOSURE_PLUS1, + IS_EXPOSURE_PLUS2, + IS_EXPOSURE_MAX +}; + +#define V4L2_CID_IS_CAMERA_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 410) +enum is_brightness { + IS_BRIGHTNESS_MINUS_2, + IS_BRIGHTNESS_MINUS_1, + IS_BRIGHTNESS_DEFAULT, + IS_BRIGHTNESS_PLUS1, + IS_BRIGHTNESS_PLUS2, + IS_BRIGHTNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_HUE (V4L2_CID_FIMC_IS_BASE + 411) +enum is_hue { + IS_HUE_MINUS_2, + IS_HUE_MINUS_1, + IS_HUE_DEFAULT, + IS_HUE_PLUS1, + IS_HUE_PLUS2, + IS_HUE_MAX +}; + +#define V4L2_CID_IS_CAMERA_METERING (V4L2_CID_FIMC_IS_BASE + 412) +enum is_metering { + IS_METERING_AVERAGE, + IS_METERING_SPOT, + IS_METERING_MATRIX, + IS_METERING_MAX +}; +#define V4L2_CID_IS_CAMERA_METERING_POSITION_X (V4L2_CID_FIMC_IS_BASE + 500) +#define V4L2_CID_IS_CAMERA_METERING_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 501) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_X (V4L2_CID_FIMC_IS_BASE + 502) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_Y (V4L2_CID_FIMC_IS_BASE + 503) + +#define V4L2_CID_IS_CAMERA_AFC_MODE (V4L2_CID_FIMC_IS_BASE + 413) +enum is_afc_mode { + IS_AFC_DISABLE, + IS_AFC_AUTO, + IS_AFC_MANUAL_50HZ, + IS_AFC_MANUAL_60HZ, + IS_AFC_MAX +}; + +#define V4L2_CID_IS_FD_NUM_FACE (V4L2_CID_FIMC_IS_BASE + 414) +/* value : maximum number of face */ + +#define V4L2_CID_IS_FD_GET_FACE_COUNT (V4L2_CID_FIMC_IS_BASE + 416) +#define V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 417) +#define V4L2_CID_IS_FD_GET_FACE_CONFIDENCE (V4L2_CID_FIMC_IS_BASE + 418) +#define V4L2_CID_IS_FD_GET_FACE_SMILELEVEL (V4L2_CID_FIMC_IS_BASE + 419) +#define V4L2_CID_IS_FD_GET_FACE_BLINKLEVEL (V4L2_CID_FIMC_IS_BASE + 420) +#define V4L2_CID_IS_FD_GET_FACE_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 421) +#define V4L2_CID_IS_FD_GET_FACE_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 422) +#define V4L2_CID_IS_FD_GET_FACE_SIZE_X (V4L2_CID_FIMC_IS_BASE + 423) +#define V4L2_CID_IS_FD_GET_FACE_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 424) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 425) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 426) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_SIZE_X (V4L2_CID_FIMC_IS_BASE + 427) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 428) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 429) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 430) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_SIZE_X (V4L2_CID_FIMC_IS_BASE + 431) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 432) +#define V4L2_CID_IS_FD_GET_MOUTH_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 433) +#define V4L2_CID_IS_FD_GET_MOUTH_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 434) +#define V4L2_CID_IS_FD_GET_MOUTH_SIZE_X (V4L2_CID_FIMC_IS_BASE + 435) +#define V4L2_CID_IS_FD_GET_MOUTH_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 436) +#define V4L2_CID_IS_FD_GET_ANGLE (V4L2_CID_FIMC_IS_BASE + 437) +#define V4L2_CID_IS_FD_SET_ORIENTATION (V4L2_CID_FIMC_IS_BASE + 438) +#define V4L2_CID_IS_FD_SET_DATA_ADDRESS (V4L2_CID_FIMC_IS_BASE + 439) +#define V4L2_CID_IS_FD_GET_DATA (V4L2_CID_FIMC_IS_BASE + 500) +#define V4L2_CID_IS_FD_SET_YAW_ANGLE (V4L2_CID_FIMC_IS_BASE + 501) +#define V4L2_CID_IS_FD_SET_ROLL_ANGLE (V4L2_CID_FIMC_IS_BASE + 502) + +#define V4L2_CID_IS_SET_ISP (V4L2_CID_FIMC_IS_BASE + 440) +enum is_isp_bypass_mode { + IS_ISP_BYPASS_DISABLE, + IS_ISP_BYPASS_ENABLE, + IS_ISP_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DRC (V4L2_CID_FIMC_IS_BASE + 441) +enum is_drc_bypass_mode { + IS_DRC_BYPASS_DISABLE, + IS_DRC_BYPASS_ENABLE, + IS_DRC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_FD (V4L2_CID_FIMC_IS_BASE + 442) +enum is_fd_bypass_mode { + IS_FD_BYPASS_DISABLE, + IS_FD_BYPASS_ENABLE, + IS_FD_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_ODC (V4L2_CID_FIMC_IS_BASE + 443) +enum is_odc_bypass_mode { + IS_ODC_BYPASS_DISABLE, + IS_ODC_BYPASS_ENABLE, + IS_ODC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DIS (V4L2_CID_FIMC_IS_BASE + 444) +enum is_dis_bypass_mode { + IS_DIS_BYPASS_DISABLE, + IS_DIS_BYPASS_ENABLE, + IS_DIS_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_3DNR (V4L2_CID_FIMC_IS_BASE + 445) +enum is_tdnr_bypass_mode { + IS_TDNR_BYPASS_DISABLE, + IS_TDNR_BYPASS_ENABLE, + IS_TDNR_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERC (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerc_bypass_mode { + IS_SCALERC_BYPASS_DISABLE, + IS_SCALERC_BYPASS_ENABLE, + IS_SCALERC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERP (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerp_bypass_mode { + IS_SCALERP_BYPASS_DISABLE, + IS_SCALERP_BYPASS_ENABLE, + IS_SCALERP_BYPASS_MAX +}; + +#define V4L2_CID_IS_ROTATION_MODE (V4L2_CID_FIMC_IS_BASE + 450) +enum is_rotation_mode { + IS_ROTATION_0, + IS_ROTATION_90, + IS_ROTATION_180, + IS_ROTATION_270, + IS_ROTATION_MAX +}; + +#define V4L2_CID_IS_3DNR_1ST_FRAME_MODE (V4L2_CID_FIMC_IS_BASE + 451) +enum is_tdnr_1st_frame_mode { + IS_TDNR_1ST_FRAME_NOPROCESSING, + IS_TDNR_1ST_FRAME_2DNR, + IS_TDNR_MAX +}; + +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_X (V4L2_CID_FIMC_IS_BASE + 452) +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 453) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_X (V4L2_CID_FIMC_IS_BASE + 454) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 455) + +#define V4L2_CID_IS_CAMERA_EXIF_EXPTIME (V4L2_CID_FIMC_IS_BASE + 456) +#define V4L2_CID_IS_CAMERA_EXIF_FLASH (V4L2_CID_FIMC_IS_BASE + 457) +#define V4L2_CID_IS_CAMERA_EXIF_ISO (V4L2_CID_FIMC_IS_BASE + 458) +#define V4L2_CID_IS_CAMERA_EXIF_SHUTTERSPEED (V4L2_CID_FIMC_IS_BASE + 459) +#define V4L2_CID_IS_CAMERA_EXIF_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 460) + +#define V4L2_CID_IS_CAMERA_ISP_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 461) +enum is_isp_sel_input { + IS_ISP_INPUT_OTF, + IS_ISP_INPUT_DMA1, + IS_ISP_INPUT_DMA2, + IS_ISP_INPUT_DMA12, + IS_ISP_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISP_SEL_OUTPUT (V4L2_CID_FIMC_IS_BASE + 462) +enum is_isp_sel_output { + IS_ISP_OUTPUT_OTF, + IS_ISP_OUTPUT_DMA1, + IS_ISP_OUTPUT_DMA2, + IS_ISP_OUTPUT_DMA12, + IS_ISP_OUTPUT_OTF_DMA1, + IS_ISP_OUTPUT_OTF_DMA2, + IS_ISP_OUTPUT_OTF_DMA12, + IS_ISP_OUTPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_DRC_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 463) +enum is_drc_sel_input { + IS_DRC_INPUT_OTF, + IS_DRC_INPUT_DMA, + IS_DRC_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_FD_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 464) +enum is_fd_sel_input { + IS_FD_INPUT_OTF, + IS_FD_INPUT_DMA, + IS_FD_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_INIT_WIDTH (V4L2_CID_FIMC_IS_BASE + 465) +#define V4L2_CID_IS_CAMERA_INIT_HEIGHT (V4L2_CID_FIMC_IS_BASE + 466) + +#define V4L2_CID_IS_CMD_ISP (V4L2_CID_FIMC_IS_BASE + 467) +enum is_isp_cmd_mode { + IS_ISP_COMMAND_STOP, + IS_ISP_COMMAND_START, + IS_ISP_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DRC (V4L2_CID_FIMC_IS_BASE + 468) +enum is_drc_cmd_mode { + IS_DRC_COMMAND_STOP, + IS_DRC_COMMAND_START, + IS_DRC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_FD (V4L2_CID_FIMC_IS_BASE + 469) +enum is_fd_cmd_mode { + IS_FD_COMMAND_STOP, + IS_FD_COMMAND_START, + IS_FD_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_ODC (V4L2_CID_FIMC_IS_BASE + 470) +enum is_odc_cmd_mode { + IS_ODC_COMMAND_STOP, + IS_ODC_COMMAND_START, + IS_ODC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DIS (V4L2_CID_FIMC_IS_BASE + 471) +enum is_dis_cmd_mode { + IS_DIS_COMMAND_STOP, + IS_DIS_COMMAND_START, + IS_DIS_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_TDNR (V4L2_CID_FIMC_IS_BASE + 472) +enum is_tdnr_cmd_mode { + IS_TDNR_COMMAND_STOP, + IS_TDNR_COMMAND_START, + IS_TDNR_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERC (V4L2_CID_FIMC_IS_BASE + 473) +enum is_scalerc_cmd_mode { + IS_SCALERC_COMMAND_STOP, + IS_SCALERC_COMMAND_START, + IS_SCALERC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERP (V4L2_CID_FIMC_IS_BASE + 474) +enum is_scalerp_cmd_mode { + IS_SCALERP_COMMAND_STOP, + IS_SCALERP_COMMAND_START, + IS_SCALERP_COMMAND_MAX +}; + +#define V4L2_CID_IS_GET_SENSOR_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 480) +#define V4L2_CID_IS_GET_SENSOR_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 481) +#define V4L2_CID_IS_GET_SENSOR_WIDTH (V4L2_CID_FIMC_IS_BASE + 482) +#define V4L2_CID_IS_GET_SENSOR_HEIGHT (V4L2_CID_FIMC_IS_BASE + 483) + +#define V4L2_CID_IS_GET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 484) +#define V4L2_CID_IS_SET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 485) +#define V4L2_CID_IS_GET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 486) +#define V4L2_CID_IS_SET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 487) +#define V4L2_CID_IS_GET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 488) +#define V4L2_CID_IS_SET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 489) +#define V4L2_CID_IS_SET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 490) +#define V4L2_CID_IS_GET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 491) +#define V4L2_CID_IS_CLEAR_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 492) +#define V4L2_CID_IS_GET_LOSTED_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 493) +#define V4L2_CID_IS_ISP_DMA_BUFFER_NUM (V4L2_CID_FIMC_IS_BASE + 494) +#define V4L2_CID_IS_ISP_DMA_BUFFER_ADDRESS (V4L2_CID_FIMC_IS_BASE + 495) + +enum v4l2_blur { + BLUR_LEVEL_0 = 0, + BLUR_LEVEL_1, + BLUR_LEVEL_2, + BLUR_LEVEL_3, + BLUR_LEVEL_MAX, +}; + +#if 1 +#define V4L2_CID_CAMERA_SCENE_MODE (V4L2_CID_PRIVATE_BASE+70) +enum v4l2_scene_mode { + SCENE_MODE_BASE, + SCENE_MODE_NONE, + SCENE_MODE_PORTRAIT, + SCENE_MODE_NIGHTSHOT, + SCENE_MODE_BACK_LIGHT, + SCENE_MODE_LANDSCAPE, + SCENE_MODE_SPORTS, + SCENE_MODE_PARTY_INDOOR, + SCENE_MODE_BEACH_SNOW, + SCENE_MODE_SUNSET, + SCENE_MODE_DUSK_DAWN, + SCENE_MODE_FALL_COLOR, + SCENE_MODE_FIREWORKS, + SCENE_MODE_TEXT, + SCENE_MODE_CANDLE_LIGHT, + SCENE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_FLASH_MODE (V4L2_CID_PRIVATE_BASE+71) +enum v4l2_flash_mode { + FLASH_MODE_BASE, + FLASH_MODE_OFF, + FLASH_MODE_AUTO, + FLASH_MODE_ON, + FLASH_MODE_TORCH, + FLASH_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRIGHTNESS (V4L2_CID_PRIVATE_BASE+72) +enum v4l2_ev_mode { + EV_MINUS_4 = -4, + EV_MINUS_3 = -3, + EV_MINUS_2 = -2, + EV_MINUS_1 = -1, + EV_DEFAULT = 0, + EV_PLUS_1 = 1, + EV_PLUS_2 = 2, + EV_PLUS_3 = 3, + EV_PLUS_4 = 4, + EV_MAX, +}; + +#define V4L2_CID_CAMERA_WHITE_BALANCE (V4L2_CID_PRIVATE_BASE+73) +enum v4l2_wb_mode { + WHITE_BALANCE_BASE = 0, + WHITE_BALANCE_AUTO, + WHITE_BALANCE_SUNNY, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_TUNGSTEN, + WHITE_BALANCE_FLUORESCENT, + WHITE_BALANCE_MAX, +}; + +#define V4L2_CID_CAMERA_EFFECT (V4L2_CID_PRIVATE_BASE+74) +enum v4l2_effect_mode { + IMAGE_EFFECT_BASE = 0, + IMAGE_EFFECT_NONE, + IMAGE_EFFECT_BNW, + IMAGE_EFFECT_SEPIA, + IMAGE_EFFECT_AQUA, + IMAGE_EFFECT_ANTIQUE, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_SHARPEN, + IMAGE_EFFECT_MAX, +}; + +#define V4L2_CID_CAMERA_ISO (V4L2_CID_PRIVATE_BASE+75) +enum v4l2_iso_mode { + ISO_AUTO = 0, + ISO_50, + ISO_100, + ISO_200, + ISO_400, + ISO_800, + ISO_1600, + ISO_SPORTS, + ISO_NIGHT, + ISO_MOVIE, + ISO_MAX, +}; + +#define V4L2_CID_CAMERA_METERING (V4L2_CID_PRIVATE_BASE+76) +enum v4l2_metering_mode { + METERING_BASE = 0, + METERING_MATRIX, + METERING_CENTER, + METERING_SPOT, + METERING_MAX, +}; + +#define V4L2_CID_CAMERA_CONTRAST (V4L2_CID_PRIVATE_BASE+77) +enum v4l2_contrast_mode { + CONTRAST_MINUS_2 = 0, + CONTRAST_MINUS_1, + CONTRAST_DEFAULT, + CONTRAST_PLUS_1, + CONTRAST_PLUS_2, + CONTRAST_MAX, +}; + +#define V4L2_CID_CAMERA_SATURATION (V4L2_CID_PRIVATE_BASE+78) +enum v4l2_saturation_mode { + SATURATION_MINUS_2 = 0, + SATURATION_MINUS_1, + SATURATION_DEFAULT, + SATURATION_PLUS_1, + SATURATION_PLUS_2, + SATURATION_MAX, +}; + +#define V4L2_CID_CAMERA_SHARPNESS (V4L2_CID_PRIVATE_BASE+79) +enum v4l2_sharpness_mode { + SHARPNESS_MINUS_2 = 0, + SHARPNESS_MINUS_1, + SHARPNESS_DEFAULT, + SHARPNESS_PLUS_1, + SHARPNESS_PLUS_2, + SHARPNESS_MAX, +}; + +#define V4L2_CID_CAMERA_WDR (V4L2_CID_PRIVATE_BASE+80) +enum v4l2_wdr_mode { + WDR_OFF, + WDR_ON, + WDR_MAX, +}; + +#define V4L2_CID_CAMERA_ANTI_SHAKE (V4L2_CID_PRIVATE_BASE+81) +enum v4l2_anti_shake_mode { + ANTI_SHAKE_OFF, + ANTI_SHAKE_STILL_ON, + ANTI_SHAKE_MOVIE_ON, + ANTI_SHAKE_MAX, +}; + +#define V4L2_CID_CAMERA_TOUCH_AF_START_STOP (V4L2_CID_PRIVATE_BASE+82) +enum v4l2_touch_af { + TOUCH_AF_STOP = 0, + TOUCH_AF_START, + TOUCH_AF_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO (V4L2_CID_PRIVATE_BASE+83) +enum v4l2_smart_auto { + SMART_AUTO_OFF = 0, + SMART_AUTO_ON, + SMART_AUTO_MAX, +}; + +#define V4L2_CID_CAMERA_VINTAGE_MODE (V4L2_CID_PRIVATE_BASE+84) +enum v4l2_vintage_mode { + VINTAGE_MODE_BASE, + VINTAGE_MODE_OFF, + VINTAGE_MODE_NORMAL, + VINTAGE_MODE_WARM, + VINTAGE_MODE_COOL, + VINTAGE_MODE_BNW, + VINTAGE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE+85) +#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE + 30)//(V4L2_CID_PRIVATE_BASE+86) +#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31)//(V4L2_CID_PRIVATE_BASE+87) +#define V4L2_CID_CAMERA_GPS_TIMESTAMP (V4L2_CID_CAMERA_CLASS_BASE + 32)//(V4L2_CID_PRIVATE_BASE+88) +#define V4L2_CID_CAMERA_GPS_ALTITUDE (V4L2_CID_CAMERA_CLASS_BASE + 33)//(V4L2_CID_PRIVATE_BASE+89) +#define V4L2_CID_CAMERA_EXIF_TIME_INFO (V4L2_CID_CAMERA_CLASS_BASE + 34) +#define V4L2_CID_CAMERA_GPS_PROCESSINGMETHOD (V4L2_CID_CAMERA_CLASS_BASE+35) +#define V4L2_CID_CAMERA_ZOOM (V4L2_CID_PRIVATE_BASE+90) +enum v4l2_zoom_level { + ZOOM_LEVEL_0 = 0, + ZOOM_LEVEL_1, + ZOOM_LEVEL_2, + ZOOM_LEVEL_3, + ZOOM_LEVEL_4, + ZOOM_LEVEL_5, + ZOOM_LEVEL_6, + ZOOM_LEVEL_7, + ZOOM_LEVEL_8, + ZOOM_LEVEL_9, + ZOOM_LEVEL_10, + ZOOM_LEVEL_11, + ZOOM_LEVEL_12, + ZOOM_LEVEL_MAX = 31, +}; + +#define V4L2_CID_CAMERA_FACE_DETECTION (V4L2_CID_PRIVATE_BASE+91) +enum v4l2_face_detection { + FACE_DETECTION_OFF = 0, + FACE_DETECTION_ON, + FACE_DETECTION_NOLINE, + FACE_DETECTION_ON_BEAUTY, + FACE_DETECTION_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO_STATUS (V4L2_CID_PRIVATE_BASE+92) +enum v4l2_smart_auto_status { + SMART_AUTO_STATUS_AUTO = 0, + SMART_AUTO_STATUS_LANDSCAPE, + SMART_AUTO_STATUS_PORTRAIT, + SMART_AUTO_STATUS_MACRO, + SMART_AUTO_STATUS_NIGHT, + SMART_AUTO_STATUS_PORTRAIT_NIGHT, + SMART_AUTO_STATUS_BACKLIT, + SMART_AUTO_STATUS_PORTRAIT_BACKLIT, + SMART_AUTO_STATUS_ANTISHAKE, + SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE, + SMART_AUTO_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_SET_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE+93) +enum v4l2_auto_focus { + AUTO_FOCUS_OFF = 0, + AUTO_FOCUS_ON, + AUTO_FOCUS_MAX, +}; + +#define V4L2_CID_CAMERA_BEAUTY_SHOT (V4L2_CID_PRIVATE_BASE+94) +enum v4l2_beauty_shot { + BEAUTY_SHOT_OFF = 0, + BEAUTY_SHOT_ON, + BEAUTY_SHOT_MAX, +}; + +#define V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE+95) +enum v4l2_ae_awb_lockunlock { + AE_UNLOCK_AWB_UNLOCK = 0, + AE_LOCK_AWB_UNLOCK, + AE_UNLOCK_AWB_LOCK, + AE_LOCK_AWB_LOCK, + AE_AWB_MAX +}; + +#define V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK (V4L2_CID_PRIVATE_BASE+96) +enum v4l2_face_lock { + FACE_LOCK_OFF = 0, + FACE_LOCK_ON, + FIRST_FACE_TRACKING, + FACE_LOCK_MAX, +}; + +#define V4L2_CID_CAMERA_OBJECT_POSITION_X (V4L2_CID_PRIVATE_BASE+97) +#define V4L2_CID_CAMERA_OBJECT_POSITION_Y (V4L2_CID_PRIVATE_BASE+98) +#define V4L2_CID_CAMERA_FOCUS_MODE (V4L2_CID_PRIVATE_BASE+99) +enum v4l2_focusmode { + FOCUS_MODE_AUTO = 0, + FOCUS_MODE_MACRO, + FOCUS_MODE_FACEDETECT, + FOCUS_MODE_INFINITY, + FOCUS_MODE_CONTINOUS, + FOCUS_MODE_TOUCH, + FOCUS_MODE_MAX, + FOCUS_MODE_DEFAULT = (1 << 8), +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE+100) +enum v4l2_obj_tracking_status { + OBJECT_TRACKING_STATUS_BASE, + OBJECT_TRACKING_STATUS_PROGRESSING, + OBJECT_TRACKING_STATUS_SUCCESS, + OBJECT_TRACKING_STATUS_FAIL, + OBJECT_TRACKING_STATUS_MISSING, + OBJECT_TRACKING_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP (V4L2_CID_PRIVATE_BASE+101) +enum v4l2_ot_start_stop { + OT_STOP = 0, + OT_START, + OT_MAX, +}; + +#define V4L2_CID_CAMERA_CAF_START_STOP (V4L2_CID_PRIVATE_BASE+102) +enum v4l2_caf_start_stop { + CAF_STOP = 0, + CAF_START, + CAF_MAX, +}; + +#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT (V4L2_CID_PRIVATE_BASE+103) +#define V4L2_CID_CAMERA_FRAME_RATE (V4L2_CID_PRIVATE_BASE+104) +enum v4l2_frame_rate { + FRAME_RATE_AUTO = 0, + FRAME_RATE_7 = 7, + FRAME_RATE_15 = 15, + FRAME_RATE_30 = 30, + FRAME_RATE_60 = 60, + FRAME_RATE_120 = 120, + FRAME_RATE_MAX +}; + +#define V4L2_CID_CAMERA_ANTI_BANDING (V4L2_CID_PRIVATE_BASE+105) +enum v4l2_anti_banding { + ANTI_BANDING_AUTO = 0, + ANTI_BANDING_50HZ = 1, + ANTI_BANDING_60HZ = 2, + ANTI_BANDING_OFF = 3, +}; + +#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE+106) +enum v4l2_gamma_mode { + GAMMA_OFF = 0, + GAMMA_ON = 1, + GAMMA_MAX, +}; + +#define V4L2_CID_CAMERA_SET_SLOW_AE (V4L2_CID_PRIVATE_BASE+107) +enum v4l2_slow_ae_mode { + SLOW_AE_OFF, + SLOW_AE_ON, + SLOW_AE_MAX, +}; + +#define V4L2_CID_CAMERA_BATCH_REFLECTION (V4L2_CID_PRIVATE_BASE+108) +#define V4L2_CID_CAMERA_EXIF_ORIENTATION (V4L2_CID_PRIVATE_BASE+109) + +#define V4L2_CID_CAMERA_RESET (V4L2_CID_PRIVATE_BASE+111) //s1_camera [ Defense process by ESD input ] +#define V4L2_CID_CAMERA_CHECK_DATALINE (V4L2_CID_PRIVATE_BASE+112) +#define V4L2_CID_CAMERA_CHECK_DATALINE_STOP (V4L2_CID_PRIVATE_BASE+113) + +#endif + +#if defined(CONFIG_ARIES_NTT) // Modify NTTS1 +#define V4L2_CID_CAMERA_AE_AWB_DISABLE_LOCK (V4L2_CID_PRIVATE_BASE+114) +#endif +#define V4L2_CID_CAMERA_THUMBNAIL_NULL (V4L2_CID_PRIVATE_BASE+115) +#define V4L2_CID_CAMERA_SENSOR_MODE (V4L2_CID_PRIVATE_BASE+116) +enum v4l2_sensor_mode { + SENSOR_CAMERA, + SENSOR_MOVIE, +}; + +typedef enum { + STREAM_MODE_CAM_OFF, + STREAM_MODE_CAM_ON, + STREAM_MODE_MOVIE_OFF, + STREAM_MODE_MOVIE_ON, +} stream_mode_t; + +#define V4L2_CID_CAMERA_EXIF_EXPTIME (V4L2_CID_PRIVATE_BASE+117) +#define V4L2_CID_CAMERA_EXIF_FLASH (V4L2_CID_PRIVATE_BASE+118) +#define V4L2_CID_CAMERA_EXIF_ISO (V4L2_CID_PRIVATE_BASE+119) +#define V4L2_CID_CAMERA_EXIF_TV (V4L2_CID_PRIVATE_BASE+120) +#define V4L2_CID_CAMERA_EXIF_BV (V4L2_CID_PRIVATE_BASE+121) +#define V4L2_CID_CAMERA_EXIF_EBV (V4L2_CID_PRIVATE_BASE+122) +#define V4L2_CID_CAMERA_CHECK_ESD (V4L2_CID_PRIVATE_BASE+123) +#define V4L2_CID_CAMERA_APP_CHECK (V4L2_CID_PRIVATE_BASE+124) + +/* Pixel format FOURCC depth Description */ +enum v4l2_pix_format_mode { + V4L2_PIX_FMT_MODE_PREVIEW, + V4L2_PIX_FMT_MODE_CAPTURE, + V4L2_PIX_FMT_MODE_HDR, + V4L2_PIX_FMT_MODE_VT_MIRROR, + V4L2_PIX_FMT_MODE_VT_NONMIRROR, +}; +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') +#define V4L2_PIX_FMT_NV21T v4l2_fourcc('T', 'V', '2', '1') + + +/* + * * V4L2 extention for digital camera + * */ +/* Strobe flash light */ +enum v4l2_strobe_control { + /* turn off the flash light */ + V4L2_STROBE_CONTROL_OFF = 0, + /* turn on the flash light */ + V4L2_STROBE_CONTROL_ON = 1, + /* act guide light before splash */ + V4L2_STROBE_CONTROL_AFGUIDE = 2, + /* charge the flash light */ + V4L2_STROBE_CONTROL_CHARGE = 3, +}; + +enum v4l2_strobe_conf { + V4L2_STROBE_OFF = 0, /* Always off */ + V4L2_STROBE_ON = 1, /* Always splashes */ + /* Auto control presets */ + V4L2_STROBE_AUTO = 2, + V4L2_STROBE_REDEYE_REDUCTION = 3, + V4L2_STROBE_SLOW_SYNC = 4, + V4L2_STROBE_FRONT_CURTAIN = 5, + V4L2_STROBE_REAR_CURTAIN = 6, + /* Extra manual control presets */ + /* keep turned on until turning off */ + V4L2_STROBE_PERMANENT = 7, + V4L2_STROBE_EXTERNAL = 8, +}; + +enum v4l2_strobe_status { + V4L2_STROBE_STATUS_OFF = 0, + /* while processing configurations */ + V4L2_STROBE_STATUS_BUSY = 1, + V4L2_STROBE_STATUS_ERR = 2, + V4L2_STROBE_STATUS_CHARGING = 3, + V4L2_STROBE_STATUS_CHARGED = 4, +}; + +/* capabilities field */ +/* No strobe supported */ +#define V4L2_STROBE_CAP_NONE 0x0000 +/* Always flash off mode */ +#define V4L2_STROBE_CAP_OFF 0x0001 +/* Always use flash light mode */ +#define V4L2_STROBE_CAP_ON 0x0002 +/* Flashlight works automatic */ +#define V4L2_STROBE_CAP_AUTO 0x0004 +/* Red-eye reduction */ +#define V4L2_STROBE_CAP_REDEYE 0x0008 +/* Slow sync */ +#define V4L2_STROBE_CAP_SLOWSYNC 0x0010 +/* Front curtain */ +#define V4L2_STROBE_CAP_FRONT_CURTAIN 0x0020 +/* Rear curtain */ +#define V4L2_STROBE_CAP_REAR_CURTAIN 0x0040 +/* keep turned on until turning off */ +#define V4L2_STROBE_CAP_PERMANENT 0x0080 +/* use external strobe */ +#define V4L2_STROBE_CAP_EXTERNAL 0x0100 + +/* Set mode and Get status */ +struct v4l2_strobe { + /* off/on/charge:0/1/2 */ + enum v4l2_strobe_control control; + /* supported strobe capabilities */ + __u32 capabilities; + enum v4l2_strobe_conf mode; + enum v4l2_strobe_status status; /* read only */ + /* default is 0 and range of value varies from each models */ + __u32 flash_ev; + __u32 reserved[4]; +}; + +#define VIDIOC_S_STROBE _IOWR('V', 83, struct v4l2_strobe) +#define VIDIOC_G_STROBE _IOR('V', 84, struct v4l2_strobe) + +/* Object recognition and collateral actions */ +enum v4l2_recog_mode { + V4L2_RECOGNITION_MODE_OFF = 0, + V4L2_RECOGNITION_MODE_ON = 1, + V4L2_RECOGNITION_MODE_LOCK = 2, +}; + +enum v4l2_recog_action { + V4L2_RECOGNITION_ACTION_NONE = 0, /* only recognition */ + V4L2_RECOGNITION_ACTION_BLINK = 1, /* Capture on blinking */ + V4L2_RECOGNITION_ACTION_SMILE = 2, /* Capture on smiling */ +}; + +enum v4l2_recog_pattern { + V4L2_RECOG_PATTERN_FACE = 0, /* Face */ + V4L2_RECOG_PATTERN_HUMAN = 1, /* Human */ + V4L2_RECOG_PATTERN_CHAR = 2, /* Character */ +}; + +struct v4l2_recog_rect { + enum v4l2_recog_pattern p; /* detected pattern */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recog_data { + __u8 detect_cnt; /* detected object counter */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recognition { + enum v4l2_recog_mode mode; + + /* Which pattern to detect */ + enum v4l2_recog_pattern pattern; + + /* How many object to detect */ + __u8 obj_num; + + /* select detected object */ + __u32 detect_idx; + + /* read only :Get object coordination */ + struct v4l2_recog_data data; + + enum v4l2_recog_action action; + __u32 reserved[4]; +}; + +#define VIDIOC_S_RECOGNITION _IOWR('V', 85, struct v4l2_recognition) +#define VIDIOC_G_RECOGNITION _IOR('V', 86, struct v4l2_recognition) + +#endif /* __LINUX_VIDEODEV2_SAMSUNG_H */ diff --git a/exynos5/hal/libcamera/Android.mk b/exynos5/hal/libcamera/Android.mk new file mode 100644 index 0000000..9ab5b2f --- /dev/null +++ b/exynos5/hal/libcamera/Android.mk @@ -0,0 +1,28 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# HAL module implemenation stored in +# hw/..so +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES:= \ + SecCamera.cpp \ + SecCameraHWInterface.cpp \ + mediactl.cpp \ + +LOCAL_SHARED_LIBRARIES:= libutils libcutils libbinder liblog libcamera_client libhardware + +LOCAL_CFLAGS += -DGAIA_FW_BETA + +ifeq ($(BOARD_USES_HWJPEG),true) +LOCAL_SHARED_LIBRARIES += libhwjpeg +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250 +endif + +LOCAL_MODULE := camera.$(TARGET_DEVICE) + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos5/hal/libcamera/NOTICE b/exynos5/hal/libcamera/NOTICE new file mode 100644 index 0000000..f921593 --- /dev/null +++ b/exynos5/hal/libcamera/NOTICE @@ -0,0 +1,190 @@ + + Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/exynos5/hal/libcamera/SecCamera.cpp b/exynos5/hal/libcamera/SecCamera.cpp new file mode 100644 index 0000000..2b434c5 --- /dev/null +++ b/exynos5/hal/libcamera/SecCamera.cpp @@ -0,0 +1,3693 @@ +/* + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +************************************ +* Filename: SecCamera.cpp +* Author: Sachin P. Kamat +* Purpose: This file interacts with the Camera and JPEG drivers. +************************************* +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SecCamera" + +#include +#include +#include +#include +#include "SecCamera.h" +#include "cutils/properties.h" +#include +#include "mediactl.h" +#include "v4l2subdev.h" + +using namespace android; + +#define CHECK(return_value) \ + if (return_value < 0) { \ + LOGE("%s::%d fail. errno: %s, m_camera_id = %d", \ + __func__, __LINE__, strerror(errno), m_camera_id); \ + return -1; \ + } + +#define CHECK_PTR(return_value) \ + if (return_value < 0) { \ + LOGE("%s::%d fail, errno: %s, m_camera_id = %d", \ + __func__,__LINE__, strerror(errno), m_camera_id); \ + return NULL; \ + } + +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +namespace android { + +static struct timeval time_start; +static struct timeval time_stop; +int cam_fd1, cam_fd2; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 +unsigned long measure_time_camera(struct timeval *start, struct timeval *stop) +{ + unsigned long sec, usec, time; + + sec = stop->tv_sec - start->tv_sec; + + if (stop->tv_usec >= start->tv_usec) { + usec = stop->tv_usec - start->tv_usec; + } else { + usec = stop->tv_usec + 1000000 - start->tv_usec; + sec--; + } + + time = (sec * 1000000) + usec; + + return time; +} +#endif + +static int gsc_cap_open(int id) +{ + char node[20]; + int fd; + + id += GSC_VD_NODE_OFFSET; + sprintf(node, "%s%d", PFX_NODE_GSC, id); + LOGE("(%s): %s%d", __func__, PFX_NODE_GSC, id); + + fd = open(node, O_RDWR, 0); + if(fd < 0) { + LOGE("ERR(%s): Open gscaler video device failed", __func__); + return -1; + } + LOGE("%s open", node); + + return fd; +} + +static int close_buffers(struct SecBuffer *buffers) +{ + int i, j; + int ret; + + for (i = 0; i < MAX_BUFFERS; i++) { + for(j = 0; j < MAX_PLANES; j++) { + if (buffers[i].virt.extP[j]) { + buffers[i].virt.extP[j] = NULL; + } + } + } + + return 0; +} + +static int get_pixel_depth(unsigned int fmt) +{ + int depth = 0; + + switch (fmt) { + case V4L2_PIX_FMT_JPEG: + depth = 8; + break; + + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YVU420M: + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12MT: + depth = 12; + break; + + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUV422P: + depth = 16; + break; + + case V4L2_PIX_FMT_RGB32: + depth = 32; + break; + + default: + LOGE("ERR(%s):Get depth failed.", __func__); + break; + } + + return depth; +} + +static int gsc_cap_poll(struct pollfd *events) +{ + int ret; + + /* 10 second delay is because sensor can take a long time + * to do auto focus and capture in dark settings + */ + ret = poll(events, 1, 10000); + if (ret < 0) { + LOGE("ERR(%s):poll error", __func__); + return ret; + } + + if (ret == 0) { + LOGE("ERR(%s):No data in 10 secs..", __func__); + return ret; + } + + return ret; +} + +static int v4l2_gsc_cap_querycap(int fp) +{ + struct v4l2_capability cap; + + if (ioctl(fp, VIDIOC_QUERYCAP, &cap) < 0) { + LOGE("ERR(%s):VIDIOC_QUERYCAP failed", __func__); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) { + LOGE("ERR(%s):no capture devices", __func__); + return -1; + } + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("ERR(%s):no streaming capture devices", __func__); + return -1; + } + + return 0; +} + +static const __u8* v4l2_gsc_cap_enuminput(int fp, int index) +{ + static struct v4l2_input input; + + input.index = index; + if (ioctl(fp, VIDIOC_ENUMINPUT, &input) != 0) { + LOGE("ERR(%s):No matching index found", __func__); + return NULL; + } + LOGI("Name of input channel[%d] is %s", input.index, input.name); + + return input.name; +} + +static int v4l2_gsc_cap_s_input(int fp, int index) +{ + struct v4l2_input input; + + input.index = index; + + if (ioctl(fp, VIDIOC_S_INPUT, &input) < 0) { + LOGE("ERR(%s):VIDIOC_S_INPUT failed", __func__); + return -1; + } + + return 0; +} + +static int v4l2_gsc_cap_g_fmt(int fp) +{ + struct v4l2_format v4l2_fmt; + + v4l2_fmt.type = V4L2_BUF_TYPE; + + if(ioctl(fp, VIDIOC_G_FMT, &v4l2_fmt) < 0){ + LOGE("ERR(%s):VIDIOC_G_FMT failed", __func__); + return -1; + } + + return 0; +} + +static int v4l2_gsc_cap_s_fmt(int fp, int width, int height, unsigned int fmt, enum v4l2_field field, unsigned int num_plane) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + unsigned int framesize; + + memset(&v4l2_fmt, 0, sizeof(struct v4l2_format)); + v4l2_fmt.type = V4L2_BUF_TYPE; + + framesize = (width * height * get_pixel_depth(fmt)) / 8; + + v4l2_fmt.fmt.pix_mp.width = width; + v4l2_fmt.fmt.pix_mp.height = height; + v4l2_fmt.fmt.pix_mp.pixelformat = fmt; + v4l2_fmt.fmt.pix_mp.field = field; + if (num_plane == 1) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = framesize; + } else if (num_plane == 2) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width * height, 2048); + v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 16) * ALIGN(height/2, 16) * 2; + } else if (num_plane == 3) { + v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 8) * ALIGN(height/2, 8); + v4l2_fmt.fmt.pix_mp.plane_fmt[2].sizeimage = ALIGN(width/2, 8) * ALIGN(height/2, 8); + } else { + LOGE("ERR(%s): Invalid plane number", __func__); + return -1; + } + v4l2_fmt.fmt.pix_mp.num_planes = num_plane; + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +static int v4l2_gsc_cap_s_fmt_cap(int fp, int width, int height, unsigned int fmt) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + v4l2_fmt.type = V4L2_BUF_TYPE; + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + if (fmt == V4L2_PIX_FMT_JPEG) + pixfmt.colorspace = V4L2_COLORSPACE_JPEG; + + v4l2_fmt.fmt.pix = pixfmt; + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +int v4l2_gsc_cap_s_fmt_is(int fp, int width, int height, unsigned int fmt, enum v4l2_field field) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + v4l2_fmt.type = V4L2_BUF_TYPE_PRIVATE; + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + pixfmt.field = field; + + v4l2_fmt.fmt.pix = pixfmt; + + /* Set up for capture */ + if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +static int v4l2_gsc_cap_enum_fmt(int fp, unsigned int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int found = 0; + + fmtdesc.type = V4L2_BUF_TYPE; + fmtdesc.index = 0; + + while (ioctl(fp, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { + if (fmtdesc.pixelformat == fmt) { + LOGV("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description); + found = 1; + break; + } + + fmtdesc.index++; + } + + if (!found) { + LOGE("unsupported pixel format"); + return -1; + } + + return 0; +} + +static int v4l2_gsc_cap_reqbufs(int fp, enum v4l2_buf_type type, int nr_bufs) +{ + struct v4l2_requestbuffers req; + + req.count = nr_bufs; + req.type = type; + req.memory = V4L2_MEMORY_TYPE; + + if (ioctl(fp, VIDIOC_REQBUFS, &req) < 0) { + LOGE("ERR(%s):VIDIOC_REQBUFS failed", __func__); + return -1; + } + + if (req.count > MAX_BUFFERS ) { + LOGE("ERR(%s):Insufficient buffer memory on", __func__); + return -1; + } + + return req.count; +} + +static int v4l2_gsc_cap_querybuf(int fp, struct SecBuffer *buffers, enum v4l2_buf_type type, int nr_frames, int num_plane) +{ + struct v4l2_buffer v4l2_buf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + int i, plane_index; + + for (i = 0; i < nr_frames; i++) { + v4l2_buf.type = type; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + v4l2_buf.index = i; + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; // this is for multi-planar + LOGV("QUERYBUF(index=%d)", i); + LOGV("Memory plane is %d", v4l2_buf.length); + + if (ioctl(fp, VIDIOC_QUERYBUF, &v4l2_buf) < 0) { + LOGE("ERR(%s):VIDIOC_QUERYBUF failed", __func__); + return -1; + } + + for (plane_index = 0; plane_index < num_plane; plane_index++) { + LOGV("Offset : 0x%x", v4l2_buf.m.planes[plane_index].m.mem_offset); + LOGV("Plane Length : 0x%x", v4l2_buf.m.planes[plane_index].length); + + buffers[i].phys.extP[plane_index] = (unsigned int)v4l2_buf.m.planes[plane_index].cookie; + + buffers[i].size.extS[plane_index] = v4l2_buf.m.planes[plane_index].length; + LOGV("Length[%d] : 0x%x", i, buffers[i].size.extS[plane_index]); + if ((buffers[i].virt.extP[plane_index] = (char *)mmap(0, v4l2_buf.m.planes[plane_index].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fp, v4l2_buf.m.planes[plane_index].m.mem_offset)) < 0) { + LOGE("mmap failed"); + return -1; + } + LOGV("vaddr[%d][%d] : 0x%x", i, plane_index, (__u32) buffers[i].virt.extP[plane_index]); + } + } + return 0; +} + +static int v4l2_gsc_cap_streamon(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE; + int ret; + + LOGV("%s : On streaming I/O", __func__); + ret = ioctl(fp, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMON failed", __func__); + return ret; + } + + return ret; +} + +static int v4l2_gsc_cap_streamoff(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE; + int ret; + + LOGV("%s :", __func__); + ret = ioctl(fp, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMOFF failed", __func__); + return ret; + } + + return 0; +} + +static int v4l2_gsc_cap_qbuf(int fp, int width, int height, struct SecBuffer *vaddr, int index, int num_plane) +{ + struct v4l2_buffer v4l2_buf; + int ret; + + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; + + v4l2_buf.type = V4L2_BUF_TYPE; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + v4l2_buf.index = index; + + if(fp == cam_fd1) { + if (num_plane == 1) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = width * height * 2; + } else if (num_plane == 2) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(width/2, 16) * ALIGN(height/2, 16); + } else if (num_plane == 3) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(width/2, 8) * ALIGN(height/2, 8); + v4l2_buf.m.planes[2].m.userptr = (long unsigned int)vaddr[index].virt.extP[2]; + v4l2_buf.m.planes[2].length = ALIGN(width/2, 8) * ALIGN(height/2, 8); + } else { + LOGE("ERR(%s): Invalid plane number", __func__); + return -1; + } + } + else if(fp == cam_fd2) { + v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0]; + v4l2_buf.m.planes[0].length = ALIGN(ALIGN(width, 16) * ALIGN(height, 16), 2048); + v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1]; + v4l2_buf.m.planes[1].length = ALIGN(ALIGN(width, 16) * ALIGN(height >> 1, 8), 2048); + } + else { + return -1; + } + + ret = ioctl(fp, VIDIOC_QBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_QBUF failed", __func__); + return ret; + } + + return 0; +} + +static int v4l2_gsc_cap_dqbuf(int fp, int num_plane) +{ + struct v4l2_buffer v4l2_buf; + int ret; + + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + + v4l2_buf.m.planes = planes; + v4l2_buf.length = num_plane; + + v4l2_buf.type = V4L2_BUF_TYPE; + v4l2_buf.memory = V4L2_MEMORY_TYPE; + + ret = ioctl(fp, VIDIOC_DQBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_DQBUF failed, dropped frame", __func__); + return ret; + } + + return v4l2_buf.index; +} + +static int v4l2_gsc_cap_g_ctrl(int fp, unsigned int id) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + + ret = ioctl(fp, VIDIOC_G_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s): VIDIOC_G_CTRL(id = 0x%x (%d)) failed, ret = %d", + __func__, id, id-V4L2_CID_PRIVATE_BASE, ret); + return ret; + } + + return ctrl.value; +} + +static int v4l2_gsc_cap_s_ctrl(int fp, unsigned int id, unsigned int value) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + ctrl.value = value; + + ret = ioctl(fp, VIDIOC_S_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_CTRL(id = %#x (%d), value = %d) failed ret = %d", + __func__, id, id-V4L2_CID_PRIVATE_BASE, value, ret); + + return ret; + } + + return ctrl.value; +} + +static int v4l2_gsc_cap_s_ext_ctrl(int fp, unsigned int id, void *value) +{ + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + int ret; + + ctrl.id = id; + + ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ctrls.count = 1; + ctrls.controls = &ctrl; + + ret = ioctl(fp, VIDIOC_S_EXT_CTRLS, &ctrls); + if (ret < 0) + LOGE("ERR(%s):VIDIOC_S_EXT_CTRLS failed", __func__); + + return ret; +} + +static int v4l2_gsc_cap_g_parm(int fp, struct v4l2_streamparm *streamparm) +{ + int ret; + + streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fp, VIDIOC_G_PARM, streamparm); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_G_PARM failed", __func__); + return ret; + } + + LOGV("%s : timeperframe: numerator %d, denominator %d", __func__, + streamparm->parm.capture.timeperframe.numerator, + streamparm->parm.capture.timeperframe.denominator); + + return ret; +} + +static int v4l2_gsc_cap_s_parm(int fp, struct v4l2_streamparm *streamparm) +{ + int ret; + + streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + ret = ioctl(fp, VIDIOC_S_PARM, streamparm); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_PARM failed", __func__); + return ret; + } + + return ret; +} + +static int v4l2_subdev_open(struct media_entity *entity) +{ + int fd; + + fd = open(entity->devname, O_RDWR, 0); + if(fd < 0){ + LOGE("ERR(%s): Open failed.", __func__); + return -1; + } + + return 0; +} + +static int v4l2_subdev_get_fmt(int fd, struct v4l2_subdev_format *fmt) +{ + if(ioctl(fd, VIDIOC_SUBDEV_G_FMT, fmt)) { + LOGE("ERR(%s): subdev get foramt failed.", __func__); + return -1; + } + + return 0; +} + +SecCamera::SecCamera() : + m_flagCreate(0), + m_camera_id(CAMERA_ID_BACK), + m_gsc_vd_fd(-1), + m_cam_fd2(-1), + m_jpeg_fd(-1), + m_flag_record_start(0), + m_preview_v4lformat(V4L2_PIX_FMT_YVU420M), + m_preview_width (0), + m_preview_height (0), + m_preview_max_width (MAX_BACK_CAMERA_PREVIEW_WIDTH), + m_preview_max_height (MAX_BACK_CAMERA_PREVIEW_HEIGHT), + m_snapshot_v4lformat(-1), + m_snapshot_width (0), + m_snapshot_height (0), + m_snapshot_max_width (MAX_BACK_CAMERA_SNAPSHOT_WIDTH), + m_snapshot_max_height (MAX_BACK_CAMERA_SNAPSHOT_HEIGHT), + m_picture_vaddr(NULL), + m_recording_en (0), + m_recording_width (0), + m_recording_height (0), + m_angle(-1), + m_anti_banding(-1), + m_wdr(-1), + m_anti_shake(-1), + m_zoom_level(-1), + m_object_tracking(-1), + m_smart_auto(-1), + m_beauty_shot(-1), + m_vintage_mode(-1), + m_face_detect(-1), + m_object_tracking_start_stop(-1), + m_gps_latitude(-1), + m_gps_longitude(-1), + m_gps_altitude(-1), + m_gps_timestamp(-1), + m_sensor_mode(-1), + m_shot_mode(-1), + m_exif_orientation(-1), + m_chk_dataline(-1), + m_video_gamma(-1), + m_slow_ae(-1), + m_camera_af_flag(-1), + m_flag_camera_start(0), + m_jpeg_thumbnail_width (0), + m_jpeg_thumbnail_height(0), + m_jpeg_thumbnail_quality(100), + m_jpeg_quality(100), + m_touch_af_start_stop(-1), + m_postview_offset(0) +#ifdef ENABLE_ESD_PREVIEW_CHECK + , + m_esd_check_count(0) +#endif // ENABLE_ESD_PREVIEW_CHECK +{ + memset(&m_streamparm, 0, sizeof(m_streamparm)); + m_params = (struct sec_cam_parm*)&m_streamparm.parm.raw_data; + struct v4l2_captureparm capture; + m_params->capture.timeperframe.numerator = 1; + m_params->capture.timeperframe.denominator = 0; + m_params->contrast = -1; + m_params->effects = -1; + m_params->brightness = -1; + m_params->exposure = -1; + m_params->flash_mode = -1; + m_params->focus_mode = -1; + m_params->iso = -1; + m_params->metering = -1; + m_params->saturation = -1; + m_params->scene_mode = -1; + m_params->sharpness = -1; + m_params->white_balance = -1; + + memset(&mExifInfo, 0, sizeof(mExifInfo)); + + memset(&m_events_c, 0, sizeof(m_events_c)); + memset(&m_events_c2, 0, sizeof(m_events_c2)); +} + +SecCamera::~SecCamera() +{ + LOGV("%s :", __func__); + DestroyCamera(); +} + +bool SecCamera::CreateCamera(int index) +{ + LOGV("%s:", __func__); + char node[30]; + int i; + int ret = 0; + + LOGV("%s: m_flagCreate : %d", __func__, m_flagCreate); + if (!m_flagCreate) { + /* Arun C + * Reset the lense position only during camera starts; don't do + * reset between shot to shot + */ + m_flagCreate = 1; + m_camera_af_flag = -1; + + /* media device open */ + LOGV("%s: m_flagCreate : %d", __func__, m_flagCreate); + + media = media_open(); + if (media == NULL) { + LOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno)); + return -1; + } + +#ifndef GAIA_FW_BETA + ////////////////// + /* GET ENTITIES */ + ////////////////// + /* camera subdev */ + strcpy(node, M5MOLS_ENTITY_NAME); + LOGV("%s : node : %s", __func__, node); + camera_sd_entity = media_get_entity_by_name(media, node, strlen(node)); + LOGV("%s : camera_sd_entity : 0x%p", __func__, camera_sd_entity); + + /* mipi-csis subdev */ + sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_MIPI_CSIS, MIPI_NUM); + LOGV("%s : node : %s", __func__, node); + mipi_sd_entity = media_get_entity_by_name(media, node, strlen(node)); + LOGV("%s : mipi_sd_entity : 0x%p", __func__, mipi_sd_entity); + + /* fimc-lite subdev */ + sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_FLITE, FLITE_NUM); + LOGV("%s : node : %s", __func__, node); + flite_sd_entity = media_get_entity_by_name(media, node, strlen(node)); + LOGV("%s : flite_sd_entity : 0x%p", __func__, flite_sd_entity); + + /* gscaler-capture subdev */ + sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_GSC_CAP, GSC_NUM); + LOGV("%s : node : %s", __func__, node); + gsc_cap_sd_entity = media_get_entity_by_name(media, node, strlen(node)); + LOGV("%s : gsc_cap_sd_entity : 0x%p", __func__, gsc_cap_sd_entity); + + /* gscaler-capture subdev */ + sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_GSC_CAP, GSC_NUM); + LOGV("%s : node : %s", __func__, node); + gsc_cap_vd_entity = media_get_entity_by_name(media, node, strlen(node)); + LOGV("%s : gsc_cap_vd_entity : 0x%p", __func__, gsc_cap_vd_entity); + + LOGV("camera_sd : numlink : %d", camera_sd_entity->num_links); + LOGV("mipi_sd : numlink : %d", mipi_sd_entity->num_links); + LOGV("flite_sd : numlink : %d", flite_sd_entity->num_links); + LOGV("gsc_cap_sd : numlink : %d", gsc_cap_sd_entity->num_links); + LOGV("gsc_cap_vd : numlink : %d", gsc_cap_vd_entity->num_links); + + ////////////////// + /* SETUP LINKS */ + ////////////////// + /*camera sensor to mipi-csis */ + links = camera_sd_entity->links; + if (links == NULL || + links->source->entity != camera_sd_entity || + links->sink->entity != mipi_sd_entity) { + LOGE("ERR(%s): Cannot make link camera sensor to mipi-csis", __func__); + return -1; + } + if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("ERR(%s): Cannot make setup camera sensor to mipi-csis", __func__); + return -1; + } + LOGV("[LINK SUCCESS] camera seneor to mipi-csis"); + + /*mipi-csis to fimc-lite*/ + for(i = 0; i < mipi_sd_entity->num_links; i++) { + links = &mipi_sd_entity->links[i]; + LOGV("(%s), i=%d: links->source->entity : %p, mipi_sd_entity : %p", __func__, i, + links->source->entity, mipi_sd_entity); + LOGV("(%s), i=%d: links->sink->entity : %p, flite_sd_entity : %p", __func__, i, + links->sink->entity, flite_sd_entity); + if (links == NULL || + links->source->entity != mipi_sd_entity || + links->sink->entity != flite_sd_entity) { + continue; + } else if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("ERR(%s): Cannot make setup mipi-csis to fimc-lite", __func__); + return -1; + } + } + LOGV("[LINK SUCCESS] mipi-csis to fimc-lite"); + + /*fimc-lite to gscaler capture device*/ + for(i = 0; i < gsc_cap_sd_entity->num_links; i++) { + links = &gsc_cap_sd_entity->links[i]; + LOGV("(%s), i=%d: links->source->entity : %p, flite_sd_entity : %p", __func__, i, + links->source->entity, flite_sd_entity); + LOGV("(%s), i=%d: links->sink->entity : %p, gsc_cap_sd_entity : %p", __func__, i, + links->sink->entity, gsc_cap_sd_entity); + if (links == NULL || + links->source->entity != flite_sd_entity || + links->sink->entity != gsc_cap_sd_entity) { + continue; + } else if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("ERR(%s): Cannot make setup fimc-lite to gscaler capture device", __func__); + return -1; + } + } + LOGV("[LINK SUCCESS] fimc-lite to gscaler capture device"); + + /*gscaler capture device to gscaler video device*/ + for(i = 0; i < gsc_cap_vd_entity->num_links; i++) { + links = &gsc_cap_vd_entity->links[i]; + LOGV("(%s), i=%d: links->source->entity : %p, gsc_cap_sd_entity : %p", __func__, i, + links->source->entity, gsc_cap_sd_entity); + LOGV("(%s), i=%d: links->sink->entity : %p, gsc_cap_vd_entity : %p", __func__, i, + links->sink->entity, gsc_cap_vd_entity); + if (links == NULL || + links->source->entity != gsc_cap_sd_entity || + links->sink->entity != gsc_cap_vd_entity) { + continue; + } else if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("ERR(%s): Cannot make setup gscaler capture device to gscaler video device", __func__); + return -1; + } + } + LOGV("[LINK SUCCESS] gscaler capture device to gscaler video device"); +#else +////////////////////////////// +// internal IS +////////////////////////////// + ////////////////// + /* GET ENTITIES */ + ////////////////// + /* ISP sensor subdev */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_SENSOR_ENTITY_NAME); + isp_sensor_entity = media_get_entity_by_name(media, node, strlen(node)); + + /* ISP front subdev */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_FRONT_ENTITY_NAME); + isp_front_entity = media_get_entity_by_name(media, node, strlen(node)); + + /* ISP back subdev */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_BACK_ENTITY_NAME); + isp_back_entity = media_get_entity_by_name(media, node, strlen(node)); + + + /* ISP ScalerC video node */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_VIDEO_SCALERC_NAME); + isp_scalerc_entity = media_get_entity_by_name(media, node, strlen(node)); + + /* ISP ScalerP video node */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_VIDEO_SCALERP_NAME); + isp_scalerp_entity = media_get_entity_by_name(media, node, strlen(node)); + + /* ISP 3DNR video node */ + memset(&node, 0x00, sizeof(node)); + strcpy(node, ISP_VIDEO_3DNR_NAME); + isp_3dnr_entity = media_get_entity_by_name(media, node, strlen(node)); + + LOGV("isp_sensor_entity : numlink : %d", isp_sensor_entity->num_links); + LOGV("isp_front_entity : numlink : %d", isp_front_entity->num_links); + LOGV("isp_back_entity : numlink : %d", isp_back_entity->num_links); + LOGV("isp_scalerc_entity : numlink : %d", isp_scalerc_entity->num_links); + LOGV("isp_scalerp_entity : numlink : %d", isp_scalerp_entity->num_links); + LOGV("isp_3dnr_entity : numlink : %d", isp_3dnr_entity->num_links); + + ////////////////// + /* SETUP LINKS */ + ////////////////// + /* SENSOR TO FRONT */ + links = isp_sensor_entity->links; + if (links == NULL || + links->source->entity != isp_sensor_entity || + links->sink->entity != isp_front_entity) { + LOGE("[ERR] Can not make link isp_sensor to isp_front\n"); + return -1; + } + if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("[ERR] Can not make setup isp_sensor to isp_front\n"); + return -1; + } + LOGV("[LINK SUCCESS] Sensor to front"); + + /* FRONT TO BACK */ + for (i = 0; i < isp_front_entity->num_links; i++){ + links = &isp_front_entity->links[i]; + if (links == NULL || + links->source->entity != isp_front_entity || + links->sink->entity != isp_back_entity) { + LOGV("(%s), i=%d: links->source->entity : %p, isp_front_entity : %p", __func__, i, + links->source->entity, isp_front_entity); + LOGV("(%s), i=%d: links->sink->entity : %p, isp_back_entity : %p", __func__, i, + links->sink->entity, isp_back_entity); + continue; + } else if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("[ERR] Can not make setup isp_front to isp_back\n"); + return -1; + } + } + LOGV("[LINK SUCCESS] front to back"); + + /* BACK TO ScalerP Video*/ + for (i = 0; i < isp_back_entity->num_links; i++){ + links = &isp_back_entity->links[i]; + if (links == NULL || + links->source->entity != isp_back_entity || + links->sink->entity != isp_scalerp_entity) { + LOGV("(%s), i=%d: links->source->entity : %p, isp_front_entity : %p", __func__, i, + links->source->entity, isp_front_entity); + LOGV("(%s), i=%d: links->sink->entity : %p, isp_back_entity : %p", __func__, i, + links->sink->entity, isp_back_entity); + continue; + } + if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { + LOGE("[ERR] Can not make setup isp_back to scalerP\n"); + return -1; + } + } + LOGV("[LINK SUCCESS] back to scalerP"); +#endif + + m_gsc_vd_fd = gsc_cap_open(0); + cam_fd1 = m_gsc_vd_fd; + if (m_gsc_vd_fd < 0) { + LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, PFX_NODE_GSC, strerror(errno)); + return -1; + } + +#ifndef GAIA_FW_BETA + if (!v4l2_gsc_cap_enuminput(m_gsc_vd_fd, index)) { + LOGE("m_gsc_vd_fd(%d) v4l2_gsc_cap_enuminput fail", m_gsc_vd_fd); + return -1; + } + + ret = v4l2_gsc_cap_s_input(m_gsc_vd_fd, index); + CHECK(ret); +#endif + + m_camera_id = index; + + switch (m_camera_id) { + case CAMERA_ID_FRONT: + m_preview_max_width = MAX_FRONT_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_FRONT_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT; + break; + + case CAMERA_ID_BACK: + m_preview_max_width = MAX_BACK_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_BACK_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_BACK_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT; + break; + } + + //setExifFixedAttribute(); + } + return 0; +} + +void SecCamera::resetCamera() +{ + LOGV("%s :", __func__); + DestroyCamera(); + CreateCamera(m_camera_id); +} + +bool SecCamera::DestroyCamera() +{ + LOGV("%s :", __func__); + + if (m_flagCreate) { + + stopRecord(); + + /* close m_gsc_vd_fd after stopRecord() because stopRecord() + * uses m_gsc_vd_fd to change frame rate + */ + LOGI("DestroyCamera: m_gsc_vd_fd(%d)", m_gsc_vd_fd); + if (m_gsc_vd_fd > -1) { + close(m_gsc_vd_fd); + m_gsc_vd_fd = -1; + } + + LOGI("DestroyCamera: m_cam_fd2(%d)", m_cam_fd2); + if (m_cam_fd2 > -1) { + close(m_cam_fd2); + m_cam_fd2 = -1; + } + + m_flagCreate = 0; + } else + LOGI("%s : already deinitialized", __func__); + + return 0; +} + +int SecCamera::getCameraFd(void) +{ + return m_gsc_vd_fd; +} + +unsigned char* SecCamera::getPictureVaddr(void) +{ + return m_picture_vaddr; +} + +int SecCamera::startPreview(void) +{ + v4l2_streamparm streamparm; + struct sec_cam_parm *parms; + int ret; + + parms = (struct sec_cam_parm*)&streamparm.parm.raw_data; + LOGV("%s :", __func__); + + // check preview is aleady started. + if (m_flag_camera_start > 0) { + LOGE("ERR(%s):Preview was already started", __func__); + return 0; + } + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_gsc_vd_fd; + m_events_c.events = POLLIN | POLLERR; + +#ifndef GAIA_FW_BETA + /* enum_fmt, s_fmt sample */ + ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd, m_preview_v4lformat); + CHECK(ret); + + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName()); + + if (Internal_is) { + if (!m_recording_en) + v4l2_gsc_cap_s_fmt_is(m_gsc_vd_fd, m_preview_width, m_preview_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + else + v4l2_gsc_cap_s_fmt_is(m_gsc_vd_fd, m_recording_width, m_recording_height, + m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL); + + } + + ret = v4l2_gsc_cap_s_fmt(m_gsc_vd_fd, m_preview_width, m_preview_height, m_preview_v4lformat, V4L2_FIELD_ANY, PREVIEW_NUM_PLANE); + CHECK(ret); + + if (Internal_is) { + if (!m_recording_en) + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL); + else + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL); + } + CHECK(ret); + + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CACHEABLE, 1); + CHECK(ret); +#endif + + ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, MAX_BUFFERS); + CHECK(ret); + + LOGV("%s : m_preview_width: %d m_preview_height: %d m_angle: %d", + __func__, m_preview_width, m_preview_height, m_angle); + + LOGV("m_camera_id : %d", m_camera_id); + + /* start with all buffers in queue */ + for (int i = 0; i < MAX_BUFFERS; i++) { + ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_preview_width, m_preview_height, m_buffers_preview, i, PREVIEW_NUM_PLANE); + CHECK(ret); + } + + ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd); + CHECK(ret); + + m_flag_camera_start = 1; +/* TO DO : Frame Rate set is will be availeable. + if (setFrameRate(m_params->capture.timeperframe.denominator) < 0) + LOGE("ERR(%s):Fail on setFrameRate(%d)", + __func__, m_params->capture.timeperframe.denominator); +*/ + LOGV("%s: got the first frame of the preview", __func__); + + return 0; +} + +int SecCamera::stopPreview(void) +{ + int ret; + + LOGV("%s :", __func__); + + if (m_flag_camera_start == 0) { + LOGW("%s: doing nothing because m_flag_camera_start is zero", __func__); + return 0; + } + + if (m_params->flash_mode == FLASH_MODE_TORCH) + setFlashMode(FLASH_MODE_OFF); + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + ret = v4l2_gsc_cap_streamoff(m_gsc_vd_fd); + CHECK(ret); + + close_buffers(m_buffers_preview); + + v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, 0); + + m_flag_camera_start = 0; + + return ret; +} + +//Recording +int SecCamera::startRecord(void) +{ + int ret, i; + + LOGV("%s :", __func__); + + // aleady started + if (m_flag_record_start > 0) { + LOGE("ERR(%s):Preview was already started", __func__); + return 0; + } + + if (m_cam_fd2 <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + /* enum_fmt, s_fmt sample */ + ret = v4l2_gsc_cap_enum_fmt(m_cam_fd2, RECORD_PIX_FMT); + CHECK(ret); + + LOGI("%s: m_recording_width = %d, m_recording_height = %d", + __func__, m_recording_width, m_recording_height); + + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName()); + +// if (Internal_is) +// v4l2_gsc_cap_s_fmt_is(m_cam_fd2, m_recording_width, m_recording_height, RECORD_PIX_FMT, (enum v4l2_field) IS_MODE_CAPTURE_VIDEO); + + ret = v4l2_gsc_cap_s_fmt(m_cam_fd2, m_recording_width, + m_recording_height, RECORD_PIX_FMT, V4L2_FIELD_ANY, RECORD_NUM_PLANE); + CHECK(ret); + + ret = v4l2_gsc_cap_reqbufs(m_cam_fd2, V4L2_BUF_TYPE, MAX_BUFFERS); + CHECK(ret); + + /* start with all buffers in queue */ + for (i = 0; i < MAX_BUFFERS; i++) { + ret = v4l2_gsc_cap_qbuf(m_cam_fd2, m_recording_width, m_recording_height, m_buffers_record, i, RECORD_NUM_PLANE); + CHECK(ret); + } + + // Get and throw away the first frame since it is often garbled. + memset(&m_events_c2, 0, sizeof(m_events_c2)); + m_events_c2.fd = m_cam_fd2; + m_events_c2.events = POLLIN | POLLERR; + + ret = v4l2_gsc_cap_streamon(m_cam_fd2); + CHECK(ret); + + m_flag_record_start = 1; + + return 0; +} + +int SecCamera::stopRecord(void) +{ + int ret; + + LOGV("%s :", __func__); + + if (m_flag_record_start == 0) { + LOGW("%s: doing nothing because m_flag_record_start is zero", __func__); + return 0; + } + + if (m_cam_fd2 <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + m_flag_record_start = 0; + + ret = v4l2_gsc_cap_streamoff(m_cam_fd2); + CHECK(ret); + + close_buffers(m_buffers_record); + + v4l2_gsc_cap_reqbufs(m_cam_fd2, V4L2_BUF_TYPE, 0); + + return 0; +} + +int SecCamera::getRecordAddr(int index, SecBuffer *buffer) +{ + buffer->phys.extP[0] = (unsigned int)m_buffers_record[index].phys.extP[0]; + buffer->phys.extP[1] = (unsigned int)(m_buffers_record[index].phys.extP[0] + (m_recording_width * m_recording_height)); + return 0; +} + +int SecCamera::getPreviewAddr(int index, SecBuffer *buffer) +{ + buffer->phys.extP[0] = (unsigned int)m_buffers_preview[index].phys.extP[0]; + buffer->phys.extP[1] = (unsigned int)m_buffers_preview[index].phys.extP[1]; + buffer->virt.extP[0] = m_buffers_preview[index].virt.extP[0]; + return 0; +} + +void SecCamera::setUserBufferAddr(void *ptr, int index, int mode) +{ + if (mode == PREVIEW_MODE) { + m_buffers_preview[index].virt.extP[0] = (char *)((unsigned int *)ptr)[0]; + m_buffers_preview[index].virt.extP[1] = (char *)((unsigned int *)ptr)[1]; + m_buffers_preview[index].virt.extP[2] = (char *)((unsigned int *)ptr)[2]; + } else if (mode == RECORD_MODE) { + m_buffers_record[index].virt.extP[0] = (char *)ptr; + m_buffers_record[index].virt.extP[1] = (char *)ptr + ((ALIGN(m_recording_width, 16) * ALIGN(m_recording_height, 16))); + } else + LOGE("%s: Invalid fd!!!", __func__); +} + +int SecCamera::getPreview() +{ + int index; + int ret; + + LOGV("%s: ", __func__); + if (m_flag_camera_start == 0 || gsc_cap_poll(&m_events_c) == 0) { + LOGE("ERR(%s):Start Camera Device Reset", __func__); + /* + * When there is no data for more than 1 second from the camera we inform + * the FIMC driver by calling v4l2_gsc_cap_s_input() with a special value = 1000 + * FIMC driver identify that there is something wrong with the camera + * and it restarts the sensor. + */ + stopPreview(); + /* Reset Only Camera Device */ + ret = v4l2_gsc_cap_querycap(m_gsc_vd_fd); + CHECK(ret); +#ifndef GAIA_FW_BETA + if (v4l2_gsc_cap_enuminput(m_gsc_vd_fd, m_camera_id)) + return -1; + ret = v4l2_gsc_cap_s_input(m_gsc_vd_fd, 1000); + CHECK(ret); +#endif + m_preview_state = 0; + return -1; + ret = startPreview(); + if (ret < 0) { + LOGE("ERR(%s): startPreview() return %d", __func__, ret); + return 0; + } + } + + index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, PREVIEW_NUM_PLANE); + if (!(0 <= index && index < MAX_BUFFERS)) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return -1; + } + + return index; +} + +int SecCamera::setPreviewFrame(int index) +{ + int ret; + ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_preview_width, m_preview_height, m_buffers_preview, index, PREVIEW_NUM_PLANE); + CHECK(ret); + + return ret; +} + +int SecCamera::getRecordFrame() +{ + if (m_flag_record_start == 0) { + LOGE("%s: m_flag_record_start is 0", __func__); + return -1; + } + + gsc_cap_poll(&m_events_c2); + int index = v4l2_gsc_cap_dqbuf(m_cam_fd2, RECORD_NUM_PLANE); + if (!(0 <= index && index < MAX_BUFFERS)) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return -1; + } + + return index; +} + +int SecCamera::releaseRecordFrame(int index) +{ + if (!m_flag_record_start) { + /* this can happen when recording frames are returned after + * the recording is stopped at the driver level. we don't + * need to return the buffers in this case and we've seen + * cases where fimc could crash if we called qbuf and it + * wasn't expecting it. + */ + LOGI("%s: recording not in progress, ignoring", __func__); + return 0; + } + + return v4l2_gsc_cap_qbuf(m_cam_fd2, m_recording_width, m_recording_height, m_buffers_record, index, RECORD_NUM_PLANE); +} + +int SecCamera::setPreviewSize(int width, int height, int pixel_format) +{ + LOGV("%s(width(%d), height(%d), format(%d))", __func__, width, height, pixel_format); + + int v4lpixelformat = pixel_format; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (v4lpixelformat == V4L2_PIX_FMT_YUV420) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUV420"); + else if (v4lpixelformat == V4L2_PIX_FMT_YVU420) + LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420"); + else if (v4lpixelformat == V4L2_PIX_FMT_YVU420M) + LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420M"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV12) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV12"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV12M) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV12M"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV12T) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV12T"); + else if (v4lpixelformat == V4L2_PIX_FMT_NV21) + LOGV("PreviewFormat:V4L2_PIX_FMT_NV21"); + else if (v4lpixelformat == V4L2_PIX_FMT_YUV422P) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUV422P"); + else if (v4lpixelformat == V4L2_PIX_FMT_YUYV) + LOGV("PreviewFormat:V4L2_PIX_FMT_YUYV"); + else if (v4lpixelformat == V4L2_PIX_FMT_RGB565) + LOGV("PreviewFormat:V4L2_PIX_FMT_RGB565"); + else + LOGV("PreviewFormat:UnknownFormat"); +#endif + m_preview_width = width; + m_preview_height = height; + m_preview_v4lformat = v4lpixelformat; + + return 0; +} + +int SecCamera::getPreviewSize(int *width, int *height, int *frame_size) +{ + *width = m_preview_width; + *height = m_preview_height; + *frame_size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_preview_v4lformat), *width, *height); + return 0; +} + +int SecCamera::getPreviewMaxSize(int *width, int *height) +{ + *width = m_preview_max_width; + *height = m_preview_max_height; + + return 0; +} + +int SecCamera::getPreviewPixelFormat(void) +{ + return m_preview_v4lformat; +} + +/* + * Devide getJpeg() as two funcs, setSnapshotCmd() & getJpeg() because of the shutter sound timing. + * Here, just send the capture cmd to camera ISP to start JPEG capture. + */ +int SecCamera::setSnapshotCmd(void) +{ + LOGV("%s :", __func__); + + int ret = 0; + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return 0; + } + + if (m_flag_camera_start > 0) { + LOGW("WARN(%s):Camera was in preview, should have been stopped", __func__); + stopPreview(); + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_gsc_vd_fd; + m_events_c.events = POLLIN | POLLERR; + + int nframe = 1; + + ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd,m_snapshot_v4lformat); + CHECK(ret); + + ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, nframe); + CHECK(ret); + +#ifdef GAIA_FW_BETA + ret = v4l2_gsc_cap_querybuf(m_gsc_vd_fd, &m_capture_buf, V4L2_BUF_TYPE, 1, 2); + CHECK(ret); +#endif + + ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, m_buffers_preview, 0, 1); + CHECK(ret); + + ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd); + CHECK(ret); + + return 0; +} + +int SecCamera::endSnapshot(void) +{ + int ret; + + LOGI("%s :", __func__); + if (m_capture_buf.virt.extP[0]) { + munmap(m_capture_buf.virt.extP[0], m_capture_buf.size.extS[0]); + LOGI("munmap():virt. addr %p size = %d", + m_capture_buf.virt.extP[0], m_capture_buf.size.extS[0]); + m_capture_buf.virt.extP[0] = NULL; + m_capture_buf.size.extS[0] = 0; + } + return 0; +} + +/* + * Set Jpeg quality & exif info and get JPEG data from camera ISP + */ +unsigned char* SecCamera::getJpeg(int *jpeg_size, unsigned int *phyaddr) +{ + int index, ret = 0; + unsigned char *addr; + SecBuffer jpegAddr; + + // capture + ret = gsc_cap_poll(&m_events_c); + CHECK_PTR(ret); + index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, 1); + + if (index != 0) { + LOGE("ERR(%s):wrong index = %d", __func__, index); + return NULL; + } + + *jpeg_size = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_MAIN_SIZE); + CHECK_PTR(*jpeg_size); + + int main_offset = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_MAIN_OFFSET); + CHECK_PTR(main_offset); + m_postview_offset = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET); + CHECK_PTR(m_postview_offset); + + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + LOGV("\nsnapshot dqueued buffer = %d snapshot_width = %d snapshot_height = %d, size = %d", + index, m_snapshot_width, m_snapshot_height, *jpeg_size); + + addr = (unsigned char*)(m_capture_buf.virt.extP[0]) + main_offset; + getPreviewAddr(index, &jpegAddr); + *phyaddr = jpegAddr.phys.extP[0] + m_postview_offset; + + ret = v4l2_gsc_cap_streamoff(m_gsc_vd_fd); + CHECK_PTR(ret); + + return addr; +} + +int SecCamera::getExif(unsigned char *pExifDst, unsigned char *pThumbSrc) +{ + /*TODO : to be added HW JPEG code. */ + return 0; +} + +void SecCamera::getPostViewConfig(int *width, int *height, int *size) +{ + *width = m_snapshot_width; + *height = m_snapshot_height; + *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); + LOGV("[5B] m_preview_width : %d, mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d", + m_preview_width, *width, *height, *size); +} + +void SecCamera::getThumbnailConfig(int *width, int *height, int *size) +{ + *width = m_jpeg_thumbnail_width; + *height = m_jpeg_thumbnail_height; + *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); +} + +int SecCamera::getPostViewOffset(void) +{ + return m_postview_offset; +} + +int SecCamera::getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf, + unsigned int *output_size) +{ + LOGV("%s :", __func__); + + int index; + unsigned char *addr; + int ret = 0; + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (m_flag_camera_start > 0) { + LOGW("WARN(%s):Camera was in preview, should have been stopped", __func__); + stopPreview(); + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_gsc_vd_fd; + m_events_c.events = POLLIN | POLLERR; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV420"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12T"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) + LOGV("SnapshotFormat:V4L2_PIX_FMT_NV21"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV422P"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) + LOGV("SnapshotFormat:V4L2_PIX_FMT_YUYV"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) + LOGV("SnapshotFormat:V4L2_PIX_FMT_UYVY"); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) + LOGV("SnapshotFormat:V4L2_PIX_FMT_RGB565"); + else + LOGV("SnapshotFormat:UnknownFormat"); +#endif + + int nframe = 1; + + ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd, m_snapshot_v4lformat); + CHECK(ret); + + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName()); + + ret = v4l2_gsc_cap_s_fmt_cap(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + CHECK(ret); + + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CACHEABLE, 1); + CHECK(ret); + ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, nframe); + CHECK(ret); + +#ifdef GAIA_FW_BETA + ret = v4l2_gsc_cap_querybuf(m_gsc_vd_fd, &m_capture_buf, V4L2_BUF_TYPE, 1, 2); + CHECK(ret); +#endif + + struct SecBuffer my_buf; + my_buf.virt.p = (char *)yuv_buf; + +#ifndef GAIA_FW_BETA + ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, &my_buf, 0, 1); + CHECK(ret); +#else + ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, &m_capture_buf, 0, 1); + CHECK(ret); +#endif + + ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd); + CHECK(ret); + + gsc_cap_poll(&m_events_c); + + index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, 1); + +#ifdef GAIA_FW_BETA + ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + LOGV("\nsnapshot dequeued buffer = %d snapshot_width = %d snapshot_height = %d", + index, m_snapshot_width, m_snapshot_height); + + yuv_buf = (unsigned char*)m_capture_buf.virt.extP[0]; +#endif + m_picture_vaddr = yuv_buf; + v4l2_gsc_cap_streamoff(m_gsc_vd_fd); + + /* TODO: JPEG encode for smdk5250 */ + + return 0; +} + +int SecCamera::setSnapshotSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_snapshot_width = width; + m_snapshot_height = height; + + return 0; +} + +int SecCamera::getSnapshotSize(int *width, int *height, int *frame_size) +{ + *width = m_snapshot_width; + *height = m_snapshot_height; + + int frame = 0; + + frame = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height); + + // set it big. + if (frame == 0) + frame = m_snapshot_width * m_snapshot_height * BPP; + + *frame_size = frame; + + return 0; +} + +int SecCamera::getSnapshotMaxSize(int *width, int *height) +{ + switch (m_camera_id) { + case CAMERA_ID_FRONT: + m_snapshot_max_width = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT; + break; + + default: + case CAMERA_ID_BACK: + m_snapshot_max_width = MAX_BACK_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT; + break; + } + + *width = m_snapshot_max_width; + *height = m_snapshot_max_height; + + return 0; +} + +int SecCamera::setSnapshotPixelFormat(int pixel_format) +{ + int v4lpixelformat = pixel_format; + + if (m_snapshot_v4lformat != v4lpixelformat) { + m_snapshot_v4lformat = v4lpixelformat; + } + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) + LOGE("%s : SnapshotFormat:V4L2_PIX_FMT_YUV420", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12T", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV21", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUV422P", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUYV", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_UYVY", __func__); + else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) + LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_RGB565", __func__); + else + LOGD("SnapshotFormat:UnknownFormat"); +#endif + return 0; +} + +int SecCamera::getSnapshotPixelFormat(void) +{ + return m_snapshot_v4lformat; +} + +int SecCamera::getCameraId(void) +{ + return m_camera_id; +} + +int SecCamera::setAutofocus(void) +{ + LOGV("%s :", __func__); + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__); + return -1; + } + + return 0; +} + +int SecCamera::getAutoFocusResult(void) +{ + int af_result; + + af_result = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT); + + LOGV("%s : returning %d", __func__, af_result); + + return af_result; +} + +int SecCamera::cancelAutofocus(void) +{ + LOGV("%s :", __func__); + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + return 0; +} + +int SecCamera::SetRotate(int angle) +{ + LOGE("%s(angle(%d))", __func__, angle); + + if (m_angle != angle) { + switch (angle) { + case -360: + case 0: + case 360: + m_angle = 0; + break; + + case -270: + case 90: + m_angle = 90; + break; + + case -180: + case 180: + m_angle = 180; + break; + + case -90: + case 270: + m_angle = 270; + break; + + default: + LOGE("ERR(%s):Invalid angle(%d)", __func__, angle); + return -1; + } + + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_ROTATION, angle) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_ROTATION", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getRotate(void) +{ + LOGV("%s : angle(%d)", __func__, m_angle); + return m_angle; +} + +int SecCamera::setFrameRate(int frame_rate) +{ + LOGV("%s(FrameRate(%d))", __func__, frame_rate); + + if (frame_rate < FRAME_RATE_AUTO || FRAME_RATE_MAX < frame_rate ) + LOGE("ERR(%s):Invalid frame_rate(%d)", __func__, frame_rate); + + m_params->capture.timeperframe.denominator = frame_rate; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FRAME_RATE, frame_rate) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FRAME_RATE", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setVerticalMirror(void) +{ + LOGV("%s :", __func__); + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_VFLIP, 0) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_VFLIP", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setHorizontalMirror(void) +{ + LOGV("%s :", __func__); + + if (m_gsc_vd_fd <= 0) { + LOGE("ERR(%s):Camera was closed", __func__); + return -1; + } + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_HFLIP, 0) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_HFLIP", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setWhiteBalance(int white_balance) +{ + LOGV("%s(white_balance(%d))", __func__, white_balance); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (white_balance < IS_AWB_AUTO || IS_AWB_MAX <= white_balance) { + LOGE("ERR(%s):Invalid white_balance(%d)", __func__, white_balance); + return -1; + } + } else { + if (white_balance <= WHITE_BALANCE_BASE || WHITE_BALANCE_MAX <= white_balance) { + LOGE("ERR(%s):Invalid white_balance(%d)", __func__, white_balance); + return -1; + } + } + + if (m_params->white_balance != white_balance) { + m_params->white_balance = white_balance; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_AWB_MODE, white_balance) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_AWB_MODE", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_WHITE_BALANCE, white_balance) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WHITE_BALANCE", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getWhiteBalance(void) +{ + LOGV("%s : white_balance(%d)", __func__, m_params->white_balance); + return m_params->white_balance; +} + +int SecCamera::setBrightness(int brightness) +{ + LOGV("%s(brightness(%d))", __func__, brightness); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + brightness += IS_BRIGHTNESS_DEFAULT; + if (brightness < IS_BRIGHTNESS_MINUS_2 || IS_BRIGHTNESS_PLUS2 < brightness) { + LOGE("ERR(%s):Invalid brightness(%d)", __func__, brightness); + return -1; + } + } else { + LOGW("WARN(%s):Not supported brightness setting", __func__); + return 0; + } + + if (m_params->brightness != brightness) { + m_params->brightness = brightness; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_BRIGHTNESS, brightness) < EV_MINUS_4) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_BRIGHTNESS", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getBrightness(void) +{ + LOGV("%s : brightness(%d)", __func__, m_params->brightness); + return m_params->brightness; +} + +int SecCamera::setExposure(int exposure) +{ + LOGV("%s(exposure(%d))", __func__, exposure); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + exposure += IS_EXPOSURE_DEFAULT; + if (exposure < IS_EXPOSURE_MINUS_2 || IS_EXPOSURE_PLUS2 < exposure) { + LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure); + return -1; + } + } else { + exposure += EV_DEFAULT; + if (exposure < EV_MINUS_4 || EV_PLUS_4 < exposure) { + LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure); + return -1; + } + } + + if (m_params->exposure != exposure) { + m_params->exposure = exposure; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_EXPOSURE, exposure) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_EXPOSURE", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BRIGHTNESS, exposure) < EV_MINUS_4) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BRIGHTNESS", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getExposure(void) +{ + LOGV("%s : exposure(%d)", __func__, m_params->exposure); + return m_params->exposure; +} + +int SecCamera::setImageEffect(int image_effect) +{ + LOGV("%s(image_effect(%d))", __func__, image_effect); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (image_effect < IS_IMAGE_EFFECT_DISABLE || IS_IMAGE_EFFECT_MAX <= image_effect) { + LOGE("ERR(%s):Invalid image_effect(%d)", __func__, image_effect); + return -1; + } + } else { + if (image_effect <= IMAGE_EFFECT_BASE || IMAGE_EFFECT_MAX <= image_effect) { + LOGE("ERR(%s):Invalid image_effect(%d)", __func__, image_effect); + return -1; + } + } + + if (m_params->effects != image_effect) { + m_params->effects = image_effect; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_IMAGE_EFFECT, image_effect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_IMAGE_EFFECT", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_EFFECT, image_effect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_EFFECT", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getImageEffect(void) +{ + LOGV("%s : image_effect(%d)", __func__, m_params->effects); + return m_params->effects; +} + +int SecCamera::setAntiBanding(int anti_banding) +{ + LOGV("%s(anti_banding(%d))", __func__, anti_banding); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (anti_banding < IS_AFC_DISABLE || IS_AFC_MAX <= anti_banding) { + LOGE("ERR(%s):Invalid anti_banding (%d)", __func__, anti_banding); + return -1; + } + } else { + if (anti_banding < ANTI_BANDING_AUTO || ANTI_BANDING_OFF < anti_banding) { + LOGE("ERR(%s):Invalid anti_banding (%d)", __func__, anti_banding); + return -1; + } + } + + if (m_anti_banding != anti_banding) { + m_anti_banding = anti_banding; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_AFC_MODE, anti_banding) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_AFC_MODE", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ANTI_BANDING, anti_banding) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_BANDING", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::setSceneMode(int scene_mode) +{ + LOGV("%s(scene_mode(%d))", __func__, scene_mode); + + if (scene_mode <= SCENE_MODE_BASE || SCENE_MODE_MAX <= scene_mode) { + LOGE("ERR(%s):Invalid scene_mode (%d)", __func__, scene_mode); + return -1; + } + + if (m_params->scene_mode != scene_mode) { + m_params->scene_mode = scene_mode; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SCENE_MODE, scene_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SCENE_MODE", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSceneMode(void) +{ + return m_params->scene_mode; +} + +int SecCamera::setFlashMode(int flash_mode) +{ + LOGV("%s(flash_mode(%d))", __func__, flash_mode); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (flash_mode <= IS_FLASH_MODE_OFF || IS_FLASH_MODE_MAX <= flash_mode) { + LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode); + return -1; + } + } else { + if (flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) { + LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode); + return -1; + } + } + + if (m_params->flash_mode != flash_mode) { + m_params->flash_mode = flash_mode; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FLASH_MODE, flash_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FLASH_MODE", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getFlashMode(void) +{ + return m_params->flash_mode; +} + +int SecCamera::setISO(int iso_value) +{ + LOGV("%s(iso_value(%d))", __func__, iso_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (iso_value < IS_ISO_AUTO || IS_ISO_MAX <= iso_value) { + LOGE("ERR(%s):Invalid iso_value (%d)", __func__, iso_value); + return -1; + } + } else { + if (iso_value < ISO_AUTO || ISO_MAX <= iso_value) { + LOGE("ERR(%s):Invalid iso_value (%d)", __func__, iso_value); + return -1; + } + } + + if (m_params->iso != iso_value) { + m_params->iso = iso_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_ISO, iso_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_ISO", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ISO, iso_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ISO", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getISO(void) +{ + return m_params->iso; +} + +int SecCamera::setContrast(int contrast_value) +{ + LOGV("%s(contrast_value(%d))", __func__, contrast_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (contrast_value < IS_CONTRAST_AUTO || IS_CONTRAST_MAX <= contrast_value) { + LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value); + return -1; + } + } else { + if (contrast_value < CONTRAST_MINUS_2 || CONTRAST_MAX <= contrast_value) { + LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value); + return -1; + } + } + + if (m_params->contrast != contrast_value) { + m_params->contrast = contrast_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_CONTRAST, contrast_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_CONTRAST", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_CONTRAST, contrast_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CONTRAST", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getContrast(void) +{ + return m_params->contrast; +} + +int SecCamera::setSaturation(int saturation_value) +{ + LOGV("%s(saturation_value(%d))", __func__, saturation_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + saturation_value += IS_SATURATION_DEFAULT; + if (saturation_value < IS_SATURATION_MINUS_2 || IS_SATURATION_MAX <= saturation_value) { + LOGE("ERR(%s):Invalid saturation_value (%d)", __func__, saturation_value); + return -1; + } + } else { + saturation_value += SATURATION_DEFAULT; + if (saturation_value < SATURATION_MINUS_2 || SATURATION_MAX <= saturation_value) { + LOGE("ERR(%s):Invalid saturation_value (%d)", __func__, saturation_value); + return -1; + } + } + + if (m_params->saturation != saturation_value) { + m_params->saturation = saturation_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_SATURATION, saturation_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SATURATION, saturation_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getSaturation(void) +{ + return m_params->saturation; +} + +int SecCamera::setSharpness(int sharpness_value) +{ + LOGV("%s(sharpness_value(%d))", __func__, sharpness_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + sharpness_value += IS_SHARPNESS_DEFAULT; + if (sharpness_value < IS_SHARPNESS_MINUS_2 || IS_SHARPNESS_MAX <= sharpness_value) { + LOGE("ERR(%s):Invalid sharpness_value (%d)", __func__, sharpness_value); + return -1; + } + } else { + sharpness_value += SHARPNESS_DEFAULT; + if (sharpness_value < SHARPNESS_MINUS_2 || SHARPNESS_MAX <= sharpness_value) { + LOGE("ERR(%s):Invalid sharpness_value (%d)", __func__, sharpness_value); + return -1; + } + } + + if (m_params->sharpness != sharpness_value) { + m_params->sharpness = sharpness_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_SHARPNESS, sharpness_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SHARPNESS, sharpness_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getSharpness(void) +{ + return m_params->sharpness; +} + +int SecCamera::setHue(int hue_value) +{ + LOGV("%s(hue_value(%d))", __func__, hue_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + hue_value += IS_HUE_DEFAULT; + if (hue_value < IS_HUE_MINUS_2 || IS_HUE_MAX <= hue_value) { + LOGE("ERR(%s):Invalid hue_value (%d)", __func__, hue_value); + return -1; + } + } else { + LOGW("WARN(%s):Not supported hue setting", __func__); + return 0; + } + + if (m_params->hue != hue_value) { + m_params->hue = hue_value; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_HUE, hue_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_HUE", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getHue(void) +{ + return m_params->hue; +} + +int SecCamera::setWDR(int wdr_value) +{ + LOGV("%s(wdr_value(%d))", __func__, wdr_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (wdr_value < IS_DRC_BYPASS_DISABLE || IS_DRC_BYPASS_MAX <= wdr_value) { + LOGE("ERR(%s):Invalid drc_value (%d)", __func__, wdr_value); + return -1; + } + } else { + if (wdr_value < WDR_OFF || WDR_MAX <= wdr_value) { + LOGE("ERR(%s):Invalid wdr_value (%d)", __func__, wdr_value); + return -1; + } + } + + if (m_wdr != wdr_value) { + m_wdr = wdr_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_SET_DRC, wdr_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_SET_DRC", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_WDR, wdr_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WDR", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getWDR(void) +{ + return m_wdr; +} + +int SecCamera::setAntiShake(int anti_shake) +{ + LOGV("%s(anti_shake(%d))", __func__, anti_shake); + + if (anti_shake < ANTI_SHAKE_OFF || ANTI_SHAKE_MAX <= anti_shake) { + LOGE("ERR(%s):Invalid anti_shake (%d)", __func__, anti_shake); + return -1; + } + + if (m_anti_shake != anti_shake) { + m_anti_shake = anti_shake; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ANTI_SHAKE, anti_shake) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_SHAKE", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getAntiShake(void) +{ + return m_anti_shake; +} + +int SecCamera::setMetering(int metering_value) +{ + LOGV("%s(metering (%d))", __func__, metering_value); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (metering_value < IS_METERING_AVERAGE || IS_METERING_MAX <= metering_value) { + LOGE("ERR(%s):Invalid metering_value (%d)", __func__, metering_value); + return -1; + } + } else { + if (metering_value <= METERING_BASE || METERING_MAX <= metering_value) { + LOGE("ERR(%s):Invalid metering_value (%d)", __func__, metering_value); + return -1; + } + } + + if (m_params->metering != metering_value) { + m_params->metering = metering_value; + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_METERING, metering_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_METERING", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_METERING, metering_value) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_METERING", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getMetering(void) +{ + return m_params->metering; +} + +int SecCamera::setJpegQuality(int jpeg_quality) +{ + LOGV("%s(jpeg_quality (%d))", __func__, jpeg_quality); + + if (jpeg_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_quality) { + LOGE("ERR(%s):Invalid jpeg_quality (%d)", __func__, jpeg_quality); + return -1; + } + + if (m_jpeg_quality != jpeg_quality) { + m_jpeg_quality = jpeg_quality; +#ifdef JPEG_FROM_SENSOR + if (m_flag_camera_start && (m_camera_id == CAMERA_ID_BACK)) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAM_JPEG_QUALITY", __func__); + return -1; + } + } +#endif + } + + return 0; +} + +int SecCamera::getJpegQuality(void) +{ + return m_jpeg_quality; +} + +int SecCamera::setZoom(int zoom_level) +{ + LOGV("%s(zoom_level (%d))", __func__, zoom_level); + + if (zoom_level < ZOOM_LEVEL_0 || ZOOM_LEVEL_MAX <= zoom_level) { + LOGE("ERR(%s):Invalid zoom_level (%d)", __func__, zoom_level); + return -1; + } + + if (m_zoom_level != zoom_level) { + m_zoom_level = zoom_level; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ZOOM, zoom_level) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ZOOM", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getZoom(void) +{ + return m_zoom_level; +} + +int SecCamera::setObjectTracking(int object_tracking) +{ + LOGV("%s(object_tracking (%d))", __func__, object_tracking); + + if (object_tracking < OBJECT_TRACKING_OFF || OBJECT_TRACKING_MAX <= object_tracking) { + LOGE("ERR(%s):Invalid object_tracking (%d)", __func__, object_tracking); + return -1; + } + + if (m_object_tracking != object_tracking) + m_object_tracking = object_tracking; + + return 0; +} + +int SecCamera::getObjectTracking(void) +{ + return m_object_tracking; +} + +int SecCamera::getObjectTrackingStatus(void) +{ + int obj_status = 0; + obj_status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJ_TRACKING_STATUS); + return obj_status; +} + +int SecCamera::setObjectTrackingStartStop(int start_stop) +{ + LOGV("%s(object_tracking_start_stop (%d))", __func__, start_stop); + + if (m_object_tracking_start_stop != start_stop) { + m_object_tracking_start_stop = start_stop; + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP, start_stop) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setTouchAFStartStop(int start_stop) +{ + LOGV("%s(touch_af_start_stop (%d))", __func__, start_stop); + + if (m_touch_af_start_stop != start_stop) { + m_touch_af_start_stop = start_stop; + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_TOUCH_AF_START_STOP, start_stop) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_TOUCH_AF_START_STOP", __func__); + return -1; + } + } + + return 0; +} + +int SecCamera::setSmartAuto(int smart_auto) +{ + LOGV("%s(smart_auto (%d))", __func__, smart_auto); + + if (smart_auto < SMART_AUTO_OFF || SMART_AUTO_MAX <= smart_auto) { + LOGE("ERR(%s):Invalid smart_auto (%d)", __func__, smart_auto); + return -1; + } + + if (m_smart_auto != smart_auto) { + m_smart_auto = smart_auto; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SMART_AUTO, smart_auto) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SMART_AUTO", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSmartAuto(void) +{ + return m_smart_auto; +} + +int SecCamera::getAutosceneStatus(void) +{ + int autoscene_status = -1; + + if (getSmartAuto() == SMART_AUTO_ON) { + autoscene_status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SMART_AUTO_STATUS); + + if ((autoscene_status < SMART_AUTO_STATUS_AUTO) || (autoscene_status > SMART_AUTO_STATUS_MAX)) { + LOGE("ERR(%s):Invalid getAutosceneStatus (%d)", __func__, autoscene_status); + return -1; + } + } + return autoscene_status; +} + +int SecCamera::setBeautyShot(int beauty_shot) +{ + LOGV("%s(beauty_shot (%d))", __func__, beauty_shot); + + if (beauty_shot < BEAUTY_SHOT_OFF || BEAUTY_SHOT_MAX <= beauty_shot) { + LOGE("ERR(%s):Invalid beauty_shot (%d)", __func__, beauty_shot); + return -1; + } + + if (m_beauty_shot != beauty_shot) { + m_beauty_shot = beauty_shot; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BEAUTY_SHOT, beauty_shot) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BEAUTY_SHOT", __func__); + return -1; + } + } + + setFaceDetect(FACE_DETECTION_ON_BEAUTY); + } + + return 0; +} + +int SecCamera::getBeautyShot(void) +{ + return m_beauty_shot; +} + +int SecCamera::setVintageMode(int vintage_mode) +{ + LOGV("%s(vintage_mode(%d))", __func__, vintage_mode); + + if (vintage_mode <= VINTAGE_MODE_BASE || VINTAGE_MODE_MAX <= vintage_mode) { + LOGE("ERR(%s):Invalid vintage_mode (%d)", __func__, vintage_mode); + return -1; + } + + if (m_vintage_mode != vintage_mode) { + m_vintage_mode = vintage_mode; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_VINTAGE_MODE, vintage_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_VINTAGE_MODE", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getVintageMode(void) +{ + return m_vintage_mode; +} + +int SecCamera::setFocusMode(int focus_mode) +{ + LOGV("%s(focus_mode(%d))", __func__, focus_mode); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (Internal_is) { + if (IS_FOCUS_MODE_MAX <= focus_mode) { + LOGE("ERR(%s):Invalid focus_mode (%d)", __func__, focus_mode); + return -1; + } + } else { + if (FOCUS_MODE_MAX <= focus_mode) { + LOGE("ERR(%s):Invalid focus_mode (%d)", __func__, focus_mode); + return -1; + } + } + + if (m_params->focus_mode != focus_mode) { + m_params->focus_mode = focus_mode; +#ifdef AF_SUPPORT + if (m_flag_camera_start) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FOCUS_MODE, focus_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FOCUS_MODE", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __func__); + return -1; + } + } + } +#endif + } + + return 0; +} + +int SecCamera::getFocusMode(void) +{ + return m_params->focus_mode; +} + +int SecCamera::setFaceDetect(int face_detect) +{ + LOGV("%s(face_detect(%d))", __func__, face_detect); + int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10); + + if (m_face_detect != face_detect) { + m_face_detect = face_detect; + if (m_flag_camera_start) { + if (m_face_detect != FACE_DETECTION_OFF) { + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FOCUS_MODE, IS_FOCUS_MODE_AUTO) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FOCUS_MODin face detecion", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_AUTO) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODin face detecion", __func__); + return -1; + } + } + } + if (Internal_is) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CMD_FD, face_detect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_IS_CMD_FD", __func__); + return -1; + } + } else { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FACE_DETECTION, face_detect) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACE_DETECTION", __func__); + return -1; + } + } + } + } + + return 0; +} + +int SecCamera::getFaceDetect(void) +{ + return m_face_detect; +} + +int SecCamera::setGPSLatitude(const char *gps_latitude) +{ + double conveted_latitude = 0; + LOGV("%s(gps_latitude(%s))", __func__, gps_latitude); + if (gps_latitude == NULL) + m_gps_latitude = 0; + else { + conveted_latitude = atof(gps_latitude); + m_gps_latitude = (long)(conveted_latitude * 10000 / 1); + } + + LOGV("%s(m_gps_latitude(%ld))", __func__, m_gps_latitude); + return 0; +} + +int SecCamera::setGPSLongitude(const char *gps_longitude) +{ + double conveted_longitude = 0; + LOGV("%s(gps_longitude(%s))", __func__, gps_longitude); + if (gps_longitude == NULL) + m_gps_longitude = 0; + else { + conveted_longitude = atof(gps_longitude); + m_gps_longitude = (long)(conveted_longitude * 10000 / 1); + } + + LOGV("%s(m_gps_longitude(%ld))", __func__, m_gps_longitude); + return 0; +} + +int SecCamera::setGPSAltitude(const char *gps_altitude) +{ + double conveted_altitude = 0; + LOGV("%s(gps_altitude(%s))", __func__, gps_altitude); + if (gps_altitude == NULL) + m_gps_altitude = 0; + else { + conveted_altitude = atof(gps_altitude); + m_gps_altitude = (long)(conveted_altitude * 100 / 1); + } + + LOGV("%s(m_gps_altitude(%ld))", __func__, m_gps_altitude); + return 0; +} + +int SecCamera::setGPSTimeStamp(const char *gps_timestamp) +{ + LOGV("%s(gps_timestamp(%s))", __func__, gps_timestamp); + if (gps_timestamp == NULL) + m_gps_timestamp = 0; + else + m_gps_timestamp = atol(gps_timestamp); + + LOGV("%s(m_gps_timestamp(%ld))", __func__, m_gps_timestamp); + return 0; +} + +int SecCamera::setGPSProcessingMethod(const char *gps_processing_method) +{ + LOGV("%s(gps_processing_method(%s))", __func__, gps_processing_method); + memset(mExifInfo.gps_processing_method, 0, sizeof(mExifInfo.gps_processing_method)); + if (gps_processing_method != NULL) { + size_t len = strlen(gps_processing_method); + if (len > sizeof(mExifInfo.gps_processing_method)) { + len = sizeof(mExifInfo.gps_processing_method); + } + memcpy(mExifInfo.gps_processing_method, gps_processing_method, len); + } + return 0; +} + +int SecCamera::setFaceDetectLockUnlock(int facedetect_lockunlock) +{ + LOGV("%s(facedetect_lockunlock(%d))", __func__, facedetect_lockunlock); + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, facedetect_lockunlock) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setObjectPosition(int x, int y) +{ + LOGV("%s(setObjectPosition(x=%d, y=%d))", __func__, x, y); + + if (m_preview_width ==640) + x = x - 80; + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, x) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_X", __func__); + return -1; + } + + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, y) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_Y", __func__); + return -1; + } + + return 0; +} + +int SecCamera::setGamma(int gamma) +{ + LOGV("%s(gamma(%d))", __func__, gamma); + + if (gamma < GAMMA_OFF || GAMMA_MAX <= gamma) { + LOGE("ERR(%s):Invalid gamma (%d)", __func__, gamma); + return -1; + } + + if (m_video_gamma != gamma) { + m_video_gamma = gamma; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_GAMMA, gamma) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_GAMMA", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::setSlowAE(int slow_ae) +{ + LOGV("%s(slow_ae(%d))", __func__, slow_ae); + + if (slow_ae < GAMMA_OFF || GAMMA_MAX <= slow_ae) { + LOGE("ERR(%s):Invalid slow_ae (%d)", __func__, slow_ae); + return -1; + } + + if (m_slow_ae!= slow_ae) { + m_slow_ae = slow_ae; + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_SLOW_AE, slow_ae) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_SLOW_AE", __func__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::setRecording(int recording_en) +{ + LOGV("%s(recoding_en(%d))", __func__, recording_en); + + m_recording_en = recording_en; + + return 0; +} + +int SecCamera::setRecordingSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_recording_width = width; + m_recording_height = height; + + return 0; +} + +int SecCamera::getRecordingSize(int *width, int *height) +{ + *width = m_recording_width; + *height = m_recording_height; + + return 0; +} + +int SecCamera::setExifOrientationInfo(int orientationInfo) +{ + LOGV("%s(orientationInfo(%d))", __func__, orientationInfo); + + if (orientationInfo < 0) { + LOGE("ERR(%s):Invalid orientationInfo (%d)", __func__, orientationInfo); + return -1; + } + m_exif_orientation = orientationInfo; + + return 0; +} + +int SecCamera::setBatchReflection() +{ + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BATCH_REFLECTION, 1) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BATCH_REFLECTION", __func__); + return -1; + } + } + + return 0; +} + +/* Camcorder fix fps */ +int SecCamera::setSensorMode(int sensor_mode) +{ + LOGV("%s(sensor_mode (%d))", __func__, sensor_mode); + + if (sensor_mode < SENSOR_MODE_CAMERA || SENSOR_MODE_MOVIE < sensor_mode) { + LOGE("ERR(%s):Invalid sensor mode (%d)", __func__, sensor_mode); + return -1; + } + + if (m_sensor_mode != sensor_mode) + m_sensor_mode = sensor_mode; + + return 0; +} + +/* Shot mode */ +/* SINGLE = 0 +* CONTINUOUS = 1 +* PANORAMA = 2 +* SMILE = 3 +* SELF = 6 +*/ +int SecCamera::setShotMode(int shot_mode) +{ + LOGV("%s(shot_mode (%d))", __func__, shot_mode); + if (shot_mode < SHOT_MODE_SINGLE || SHOT_MODE_SELF < shot_mode) { + LOGE("ERR(%s):Invalid shot_mode (%d)", __func__, shot_mode); + return -1; + } + m_shot_mode = shot_mode; + + return 0; +} + +int SecCamera::setDataLineCheck(int chk_dataline) +{ + LOGV("%s(chk_dataline (%d))", __func__, chk_dataline); + + if (chk_dataline < CHK_DATALINE_OFF || CHK_DATALINE_MAX <= chk_dataline) { + LOGE("ERR(%s):Invalid chk_dataline (%d)", __func__, chk_dataline); + return -1; + } + + m_chk_dataline = chk_dataline; + + return 0; +} + +int SecCamera::getDataLineCheck(void) +{ + return m_chk_dataline; +} + +int SecCamera::setDataLineCheckStop(void) +{ + LOGV("%s", __func__); + + if (m_flag_camera_start) { + if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_CHECK_DATALINE_STOP, 1) < 0) { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CHECK_DATALINE_STOP", __func__); + return -1; + } + } + return 0; +} + +const __u8* SecCamera::getCameraSensorName(void) +{ + LOGV("%s", __func__); + + return v4l2_gsc_cap_enuminput(m_gsc_vd_fd, getCameraId()); +} + +#ifdef ENABLE_ESD_PREVIEW_CHECK +int SecCamera::getCameraSensorESDStatus(void) +{ + LOGV("%s", __func__); + + // 0 : normal operation, 1 : abnormal operation + int status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_ESD_INT); + + return status; +} +#endif // ENABLE_ESD_PREVIEW_CHECK + +int SecCamera::setJpegThumbnailSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __func__, width, height); + + m_jpeg_thumbnail_width = width; + m_jpeg_thumbnail_height = height; + + return 0; +} + +int SecCamera::getJpegThumbnailSize(int *width, int *height) +{ + if (width) + *width = m_jpeg_thumbnail_width; + if (height) + *height = m_jpeg_thumbnail_height; + + return 0; +} + +int SecCamera::setJpegThumbnailQuality(int jpeg_thumbnail_quality) +{ + LOGV("%s(jpeg_thumbnail_quality (%d))", __func__, jpeg_thumbnail_quality); + + if (jpeg_thumbnail_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_thumbnail_quality) { + LOGE("ERR(%s):Invalid jpeg_thumbnail_quality (%d)", __func__, jpeg_thumbnail_quality); + return -1; + } + + if (m_jpeg_thumbnail_quality != jpeg_thumbnail_quality) { + m_jpeg_thumbnail_quality = jpeg_thumbnail_quality; + } + + return 0; +} + +int SecCamera::getJpegThumbnailQuality(void) +{ + return m_jpeg_thumbnail_quality; +} + +void SecCamera::setExifFixedAttribute() +{ + char property[PROPERTY_VALUE_MAX]; + + //2 0th IFD TIFF Tags + //3 Maker + property_get("ro.product.brand", property, EXIF_DEF_MAKER); + strncpy((char *)mExifInfo.maker, property, + sizeof(mExifInfo.maker) - 1); + mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0'; + //3 Model + property_get("ro.product.model", property, EXIF_DEF_MODEL); + strncpy((char *)mExifInfo.model, property, + sizeof(mExifInfo.model) - 1); + mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0'; + //3 Software + property_get("ro.build.id", property, EXIF_DEF_SOFTWARE); + strncpy((char *)mExifInfo.software, property, + sizeof(mExifInfo.software) - 1); + mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0'; + + //3 YCbCr Positioning + mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING; + + //2 0th IFD Exif Private Tags + //3 F Number + mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM; + mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN; + //3 Exposure Program + mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM; + //3 Exif Version + memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version)); + //3 Aperture + uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); + mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN; + mExifInfo.aperture.den = EXIF_DEF_APEX_DEN; + //3 Maximum lens aperture + mExifInfo.max_aperture.num = mExifInfo.aperture.num; + mExifInfo.max_aperture.den = mExifInfo.aperture.den; + //3 Lens Focal Length + if (m_camera_id == CAMERA_ID_BACK) + mExifInfo.focal_length.num = BACK_CAMERA_FOCAL_LENGTH; + else + mExifInfo.focal_length.num = FRONT_CAMERA_FOCAL_LENGTH; + + mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; + //3 User Comments + strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS); + //3 Color Space information + mExifInfo.color_space = EXIF_DEF_COLOR_SPACE; + //3 Exposure Mode + mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE; + + //2 0th IFD GPS Info Tags + unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 }; + memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version)); + + //2 1th IFD TIFF Tags + mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION; + mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT; +} + +void SecCamera::setExifChangedAttribute() +{ + //2 0th IFD TIFF Tags + //3 Width + mExifInfo.width = m_snapshot_width; + //3 Height + mExifInfo.height = m_snapshot_height; + //3 Orientation + switch (m_exif_orientation) { + case 90: + mExifInfo.orientation = EXIF_ORIENTATION_90; + break; + case 180: + mExifInfo.orientation = EXIF_ORIENTATION_180; + break; + case 270: + mExifInfo.orientation = EXIF_ORIENTATION_270; + break; + case 0: + default: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + } + //3 Date time + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo); + + //2 0th IFD Exif Private Tags + //3 Exposure Time + //int shutterSpeed = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_GET_SHT_TIME); + int shutterSpeed = 100; + + /* TBD - front camera needs to be fixed to support this g_ctrl, + it current returns a negative err value, so avoid putting + odd value into exif for now */ + if (shutterSpeed < 0) { + LOGE("%s: error %d getting shutterSpeed, camera_id = %d, using 100", + __func__, shutterSpeed, m_camera_id); + shutterSpeed = 100; + } + mExifInfo.exposure_time.num = 1; + // x us -> 1/x s */ + mExifInfo.exposure_time.den = (uint32_t)(1000000 / shutterSpeed); + + //3 ISO Speed Rating + int iso = m_params->iso; + //int iso = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_GET_ISO); + /* TBD - front camera needs to be fixed to support this g_ctrl, + it current returns a negative err value, so avoid putting + odd value into exif for now */ + if (iso < 0) { + LOGE("%s: error %d getting iso, camera_id = %d, using 100", + __func__, iso, m_camera_id); + iso = ISO_100; + } + switch(iso) { + case ISO_50: + mExifInfo.iso_speed_rating = 50; + break; + case ISO_100: + mExifInfo.iso_speed_rating = 100; + break; + case ISO_200: + mExifInfo.iso_speed_rating = 200; + break; + case ISO_400: + mExifInfo.iso_speed_rating = 400; + break; + case ISO_800: + mExifInfo.iso_speed_rating = 800; + break; + case ISO_1600: + mExifInfo.iso_speed_rating = 1600; + break; + default: + mExifInfo.iso_speed_rating = 100; + break; + } + + uint32_t av, tv, bv, sv, ev; + av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num / mExifInfo.fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double)mExifInfo.exposure_time.num / mExifInfo.exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(mExifInfo.iso_speed_rating); + bv = av + tv - sv; + ev = av + tv; + LOGD("Shutter speed=%d us, iso=%d", shutterSpeed, mExifInfo.iso_speed_rating); + LOGD("AV=%d, TV=%d, SV=%d", av, tv, sv); + + //3 Shutter Speed + mExifInfo.shutter_speed.num = tv*EXIF_DEF_APEX_DEN; + mExifInfo.shutter_speed.den = EXIF_DEF_APEX_DEN; + //3 Brightness + mExifInfo.brightness.num = bv*EXIF_DEF_APEX_DEN; + mExifInfo.brightness.den = EXIF_DEF_APEX_DEN; + //3 Exposure Bias + if (m_params->scene_mode == SCENE_MODE_BEACH_SNOW) { + mExifInfo.exposure_bias.num = EXIF_DEF_APEX_DEN; + mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN; + } else { + mExifInfo.exposure_bias.num = 0; + mExifInfo.exposure_bias.den = 0; + } + //3 Metering Mode + switch (m_params->metering) { + case METERING_SPOT: + mExifInfo.metering_mode = EXIF_METERING_SPOT; + break; + case METERING_MATRIX: + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + case METERING_CENTER: + mExifInfo.metering_mode = EXIF_METERING_CENTER; + break; + default : + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + } + + //3 Flash + int flash = m_params->flash_mode; + //int flash = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_GET_FLASH_ONOFF); + if (flash < 0) + mExifInfo.flash = EXIF_DEF_FLASH; + else + mExifInfo.flash = flash; + + //3 White Balance + if (m_params->white_balance == WHITE_BALANCE_AUTO) + mExifInfo.white_balance = EXIF_WB_AUTO; + else + mExifInfo.white_balance = EXIF_WB_MANUAL; + //3 Scene Capture Type + switch (m_params->scene_mode) { + case SCENE_MODE_PORTRAIT: + mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT; + break; + case SCENE_MODE_LANDSCAPE: + mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE; + break; + case SCENE_MODE_NIGHTSHOT: + mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT; + break; + default: + mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD; + break; + } + + //2 0th IFD GPS Info Tags + if (m_gps_latitude != 0 && m_gps_longitude != 0) { + if (m_gps_latitude > 0) + strcpy((char *)mExifInfo.gps_latitude_ref, "N"); + else + strcpy((char *)mExifInfo.gps_latitude_ref, "S"); + + if (m_gps_longitude > 0) + strcpy((char *)mExifInfo.gps_longitude_ref, "E"); + else + strcpy((char *)mExifInfo.gps_longitude_ref, "W"); + + if (m_gps_altitude > 0) + mExifInfo.gps_altitude_ref = 0; + else + mExifInfo.gps_altitude_ref = 1; + + double latitude = fabs(m_gps_latitude / 10000.0); + double longitude = fabs(m_gps_longitude / 10000.0); + double altitude = fabs(m_gps_altitude / 100.0); + + mExifInfo.gps_latitude[0].num = (uint32_t)latitude; + mExifInfo.gps_latitude[0].den = 1; + mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60); + mExifInfo.gps_latitude[1].den = 1; + mExifInfo.gps_latitude[2].num = (uint32_t)((((latitude - mExifInfo.gps_latitude[0].num) * 60) + - mExifInfo.gps_latitude[1].num) * 60); + mExifInfo.gps_latitude[2].den = 1; + + mExifInfo.gps_longitude[0].num = (uint32_t)longitude; + mExifInfo.gps_longitude[0].den = 1; + mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60); + mExifInfo.gps_longitude[1].den = 1; + mExifInfo.gps_longitude[2].num = (uint32_t)((((longitude - mExifInfo.gps_longitude[0].num) * 60) + - mExifInfo.gps_longitude[1].num) * 60); + mExifInfo.gps_longitude[2].den = 1; + + mExifInfo.gps_altitude.num = (uint32_t)altitude; + mExifInfo.gps_altitude.den = 1; + + struct tm tm_data; + gmtime_r(&m_gps_timestamp, &tm_data); + mExifInfo.gps_timestamp[0].num = tm_data.tm_hour; + mExifInfo.gps_timestamp[0].den = 1; + mExifInfo.gps_timestamp[1].num = tm_data.tm_min; + mExifInfo.gps_timestamp[1].den = 1; + mExifInfo.gps_timestamp[2].num = tm_data.tm_sec; + mExifInfo.gps_timestamp[2].den = 1; + snprintf((char*)mExifInfo.gps_datestamp, sizeof(mExifInfo.gps_datestamp), + "%04d:%02d:%02d", tm_data.tm_year + 1900, tm_data.tm_mon + 1, tm_data.tm_mday); + + mExifInfo.enableGps = true; + } else { + mExifInfo.enableGps = false; + } + + //2 1th IFD TIFF Tags + mExifInfo.widthThumb = m_jpeg_thumbnail_width; + mExifInfo.heightThumb = m_jpeg_thumbnail_height; +} + +int SecCamera::makeExif (unsigned char *exifOut, + unsigned char *thumb_buf, + unsigned int thumb_size, + exif_attribute_t *exifInfo, + unsigned int *size, + bool useMainbufForThumb) +{ + unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset; + unsigned int tmp, LongerTagOffest = 0; + pApp1Start = pCur = exifOut; + + //2 Exif Identifier Code & TIFF Header + pCur += 4; // Skip 4 Byte for APP1 marker and length + unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + memcpy(pCur, ExifIdentifierCode, 6); + pCur += 6; + + /* Byte Order - little endian, Offset of IFD - 0x00000008.H */ + unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 }; + memcpy(pCur, TiffHeader, 8); + pIfdStart = pCur; + pCur += 8; + + //2 0th IFD TIFF Tags + if (exifInfo->enableGps) + tmp = NUM_0TH_IFD_TIFF; + else + tmp = NUM_0TH_IFD_TIFF - 1; + + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT, + 1, exifInfo->ycbcr_positioning); + writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); + if (exifInfo->enableGps) { + pGpsIfdPtr = pCur; + pCur += IFD_SIZE; // Skip a ifd size for gps IFD pointer + } + + pNextIfdOffset = pCur; // Skip a offset size for next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD Exif Private Tags + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_0TH_IFD_EXIF; + memcpy(pCur, &tmp , NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL, + 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL, + 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT, + 1, exifInfo->exposure_program); + writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT, + 1, exifInfo->iso_speed_rating); + writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED, + 4, exifInfo->exif_version); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT, + 1, exifInfo->metering_mode); + writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT, + 1, exifInfo->flash); + writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL, + 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart); + char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 }; + int commentsLen = strlen((char *)exifInfo->user_comment) + 1; + memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen); + memcpy(exifInfo->user_comment, code, sizeof(code)); + writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED, + commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT, + 1, exifInfo->color_space); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG, + 1, exifInfo->exposure_mode); + writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG, + 1, exifInfo->white_balance); + writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG, + 1, exifInfo->scene_capture_type); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD GPS Info Tags + if (exifInfo->enableGps) { + writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + if (exifInfo->gps_processing_method[0] == 0) { + // don't create GPS_PROCESSING_METHOD tag if there isn't any + tmp = NUM_0TH_IFD_GPS - 1; + } else { + tmp = NUM_0TH_IFD_GPS; + } + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE, + 4, exifInfo->gps_version_id); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_latitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_longitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE, + 1, exifInfo->gps_altitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart); + tmp = strlen((char*)exifInfo->gps_processing_method); + if (tmp > 0) { + if (tmp > 100) { + tmp = 100; + } + static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; + unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)]; + memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix)); + memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp); + writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED, + tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart); + } + writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII, + 11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + } + + //2 1th IFD TIFF Tags + + unsigned char *thumbBuf = thumb_buf; + unsigned int thumbSize = thumb_size; + + if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize > 0)) { + tmp = LongerTagOffest; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_1TH_IFD_TIFF; + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->widthThumb); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->heightThumb); + writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT, + 1, exifInfo->compression_scheme); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT, + 1, exifInfo->resolution_unit); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG, + 1, LongerTagOffest); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG, + 1, thumbSize); + + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + memcpy(pIfdStart + LongerTagOffest, thumbBuf, thumbSize); + LongerTagOffest += thumbSize; + } else { + tmp = 0; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + } + + unsigned char App1Marker[2] = { 0xff, 0xe1 }; + memcpy(pApp1Start, App1Marker, 2); + pApp1Start += 2; + + *size = 10 + LongerTagOffest; + tmp = *size - 2; // APP1 Maker isn't counted + unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF}; + memcpy(pApp1Start, size_mm, 2); + + LOGD("makeExif X"); + + return 0; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + uint32_t value) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, &value, 4); + *pCur += 4; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue) +{ + char buf[4] = { 0,}; + + memcpy(buf, pValue, count); + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, buf, 4); + *pCur += 4; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, count); + *offset += count; +} + +inline void SecCamera::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, 8 * count); + *offset += 8 * count; +} + +status_t SecCamera::dump(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + snprintf(buffer, 255, "dump(%d)\n", fd); + result.append(buffer); + ::write(fd, result.string(), result.size()); + return NO_ERROR; +} + +double SecCamera::jpeg_ratio = 0.7; +int SecCamera::interleaveDataSize = 5242880; +int SecCamera::jpegLineLength = 636; + +}; // namespace android diff --git a/exynos5/hal/libcamera/SecCamera.h b/exynos5/hal/libcamera/SecCamera.h new file mode 100644 index 0000000..1af19ee --- /dev/null +++ b/exynos5/hal/libcamera/SecCamera.h @@ -0,0 +1,698 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_SEC_H +#define ANDROID_HARDWARE_CAMERA_SEC_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "SecBuffer.h" + +#include +#include + +#include + +#include "SecJpegEncoder.h" + +#include "Exif.h" +namespace android { + +//#define ENABLE_ESD_PREVIEW_CHECK + +#if defined(LOG_NDEBUG) && (LOG_NDEBUG == 0) +#define LOG_CAMERA LOGD +#define LOG_CAMERA_PREVIEW LOGD + +#define LOG_TIME_DEFINE(n) \ + struct timeval time_start_##n, time_stop_##n; unsigned long log_time_##n = 0; + +#define LOG_TIME_START(n) \ + gettimeofday(&time_start_##n, NULL); + +#define LOG_TIME_END(n) \ + gettimeofday(&time_stop_##n, NULL); log_time_##n = measure_time_camera(&time_start_##n, &time_stop_##n); + +#define LOG_TIME(n) \ + log_time_##n + +#else +#define LOG_CAMERA(...) +#define LOG_CAMERA_PREVIEW(...) +#define LOG_TIME_DEFINE(n) +#define LOG_TIME_START(n) +#define LOG_TIME_END(n) +#define LOG_TIME(n) +#endif + +#define JOIN(x, y) JOIN_AGAIN(x, y) +#define JOIN_AGAIN(x, y) x ## y + +#define FRONT_CAM M5MO +#define BACK_CAM S5K4E5 + +#if !defined (FRONT_CAM) || !defined(BACK_CAM) +#error "Please define the Camera module" +#endif + +#define M5MO_PREVIEW_WIDTH 1920 +#define M5MO_PREVIEW_HEIGHT 1080 +#define M5MO_SNAPSHOT_WIDTH 3264 +#define M5MO_SNAPSHOT_HEIGHT 2448 + +#define M5MO_THUMBNAIL_WIDTH 320 +#define M5MO_THUMBNAIL_HEIGHT 240 +#define M5MO_THUMBNAIL_BPP 16 + +#define M5MO_FPS 30 + +/* focal length of 3.43mm */ +#define M5MO_FOCAL_LENGTH 343 + +#define S5K4E5_PREVIEW_WIDTH 1920 +#define S5K4E5_PREVIEW_HEIGHT 1080 +#define S5K4E5_SNAPSHOT_WIDTH 1920 +#define S5K4E5_SNAPSHOT_HEIGHT 1080 + +#define S5K4E5_THUMBNAIL_WIDTH 320 +#define S5K4E5_THUMBNAIL_HEIGHT 240 +#define S5K4E5_THUMBNAIL_BPP 16 + +#define S5K4E5_FPS 30 + +/* focal length of 0.9mm */ +#define S5K4E5_FOCAL_LENGTH 90 + +#define MAX_BACK_CAMERA_PREVIEW_WIDTH JOIN(BACK_CAM,_PREVIEW_WIDTH) +#define MAX_BACK_CAMERA_PREVIEW_HEIGHT JOIN(BACK_CAM,_PREVIEW_HEIGHT) +#define MAX_BACK_CAMERA_SNAPSHOT_WIDTH JOIN(BACK_CAM,_SNAPSHOT_WIDTH) +#define MAX_BACK_CAMERA_SNAPSHOT_HEIGHT JOIN(BACK_CAM,_SNAPSHOT_HEIGHT) + +#define BACK_CAMERA_THUMBNAIL_WIDTH JOIN(BACK_CAM,_THUMBNAIL_WIDTH) +#define BACK_CAMERA_THUMBNAIL_HEIGHT JOIN(BACK_CAM,_THUMBNAIL_HEIGHT) +#define BACK_CAMERA_THUMBNAIL_BPP JOIN(BACK_CAM,_THUMBNAIL_BPP) + +#define BACK_CAMERA_FPS JOIN(BACK_CAM,_FPS) + +#define BACK_CAMERA_FOCAL_LENGTH JOIN(BACK_CAM,_FOCAL_LENGTH) + +#define MAX_FRONT_CAMERA_PREVIEW_WIDTH JOIN(FRONT_CAM,_PREVIEW_WIDTH) +#define MAX_FRONT_CAMERA_PREVIEW_HEIGHT JOIN(FRONT_CAM,_PREVIEW_HEIGHT) +#define MAX_FRONT_CAMERA_SNAPSHOT_WIDTH JOIN(FRONT_CAM,_SNAPSHOT_WIDTH) +#define MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT JOIN(FRONT_CAM,_SNAPSHOT_HEIGHT) + +#define FRONT_CAMERA_THUMBNAIL_WIDTH JOIN(FRONT_CAM,_THUMBNAIL_WIDTH) +#define FRONT_CAMERA_THUMBNAIL_HEIGHT JOIN(FRONT_CAM,_THUMBNAIL_HEIGHT) +#define FRONT_CAMERA_THUMBNAIL_BPP JOIN(FRONT_CAM,_THUMBNAIL_BPP) + +#define FRONT_CAMERA_FPS JOIN(FRONT_CAM,_FPS) + +#define FRONT_CAMERA_FOCAL_LENGTH JOIN(FRONT_CAM,_FOCAL_LENGTH) + +#define DEFAULT_JPEG_THUMBNAIL_WIDTH 256 +#define DEFAULT_JPEG_THUMBNAIL_HEIGHT 192 + +#define PFX_NODE_GSC "/dev/video" + +#define M5MOLS_ENTITY_NAME "M5MOLS 5-001f" +#define PFX_SUBDEV_ENTITY_MIPI_CSIS "s5p-mipi-csis" +#define PFX_SUBDEV_ENTITY_FLITE "exynos-fimc-lite" +#define PFX_SUBDEV_ENTITY_GSC_CAP "gsc-cap-subdev" +#define PFX_VIDEODEV_ENTITY_GSC_CAP "exynos-gsc" +#define FIMD1_ENTITY_NAME "s5p-fimd1" + +#define GAIA_FW_BETA 1 + +#ifndef GAIA_FW_BETA +#define GSC_VD_NODE_OFFSET 25 //GSCALER 0 (0:25, 1:28, 2:31, 3:34) +#else +#define GSC_VD_NODE_OFFSET 41 //INTERNAL_ISP 4E5 + +#define ISP_SENSOR_MAX_ENTITIES 1 +#define ISP_SENSOR_PAD_SOURCE_FRONT 0 +#define ISP_SENSOR_PADS_NUM 1 + +#define ISP_FRONT_MAX_ENTITIES 1 +#define ISP_FRONT_PAD_SINK 0 +#define ISP_FRONT_PAD_SOURCE_BACK 1 +#define ISP_FRONT_PAD_SOURCE_BAYER 2 +#define ISP_FRONT_PAD_SOURCE_SCALERC 3 +#define ISP_FRONT_PADS_NUM 4 + +#define ISP_BACK_MAX_ENTITIES 1 +#define ISP_BACK_PAD_SINK 0 +#define ISP_BACK_PAD_SOURCE_3DNR 1 +#define ISP_BACK_PAD_SOURCE_SCALERP 2 +#define ISP_BACK_PADS_NUM 3 + +#define ISP_MODULE_NAME "exynos5-fimc-is" +#define ISP_SENSOR_ENTITY_NAME "exynos5-fimc-is-sensor" +#define ISP_FRONT_ENTITY_NAME "exynos5-fimc-is-front" +#define ISP_BACK_ENTITY_NAME "exynos5-fimc-is-back" +#define ISP_VIDEO_BAYER_NAME "exynos5-fimc-is-bayer" +#define ISP_VIDEO_SCALERC_NAME "exynos5-fimc-is-scalerc" +#define ISP_VIDEO_3DNR_NAME "exynos5-fimc-is-3dnr" +#define ISP_VIDEO_SCALERP_NAME "exynos5-fimc-is-scalerp" + +#endif +#define MIPI_NUM 1 +#define FLITE_NUM 1 +#define GSC_NUM 0 + +#define PFX_SUBDEV_NODE "/dev/v4l-subdev" + +#define BPP 2 +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#ifndef GAIA_FW_BETA +#define MAX_BUFFERS 8 +#else +#define MAX_BUFFERS 4 //external : 8, internal : 4 +#endif + +#define MAX_PLANES (3) +#define V4L2_BUF_TYPE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE + +#define V4L2_MEMORY_TYPE V4L2_MEMORY_USERPTR +#define RECORD_PIX_FMT V4L2_PIX_FMT_NV12M +#define PREVIEW_NUM_PLANE (3) +#define RECORD_NUM_PLANE (2) + +/* + * V 4 L 2 F I M C E X T E N S I O N S + * + */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) + +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) + +#define TPATTERN_COLORBAR 1 +#define TPATTERN_HORIZONTAL 2 +#define TPATTERN_VERTICAL 3 + +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + +/* FOURCC for FIMC specific */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') +/* + * U S E R D E F I N E D T Y P E S + * + */ +#define PREVIEW_MODE 1 +#define RECORD_MODE 2 + +/* We use this struct as the v4l2_streamparm raw_data for + * VIDIOC_G_PARM and VIDIOC_S_PARM + */ +struct sec_cam_parm { + struct v4l2_captureparm capture; + int contrast; + int effects; + int brightness; + int exposure; + int flash_mode; + int focus_mode; + int iso; + int metering; + int saturation; + int scene_mode; + int sharpness; + int hue; + int white_balance; +}; + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int depth; + int planes; +}; + +struct camsensor_date_info { + unsigned int year; + unsigned int month; + unsigned int date; +}; + +class SecCamera : public virtual RefBase { +public: + + enum CAMERA_ID { + CAMERA_ID_BACK = 0, + CAMERA_ID_FRONT = 1, + }; + + enum JPEG_QUALITY { + JPEG_QUALITY_ECONOMY = 0, + JPEG_QUALITY_NORMAL = 50, + JPEG_QUALITY_SUPERFINE = 100, + JPEG_QUALITY_MAX, + }; + + enum OBJECT_TRACKING { + OBJECT_TRACKING_OFF, + OBJECT_TRACKING_ON, + OBJECT_TRACKING_MAX, + }; + + /*VT call*/ + enum VT_MODE { + VT_MODE_OFF, + VT_MODE_ON, + VT_MODE_MAX, + }; + + /*Camera sensor mode - Camcorder fix fps*/ + enum SENSOR_MODE { + SENSOR_MODE_CAMERA, + SENSOR_MODE_MOVIE, + }; + + /*Camera Shot mode*/ + enum SHOT_MODE { + SHOT_MODE_SINGLE = 0, + SHOT_MODE_CONTINUOUS = 1, + SHOT_MODE_PANORAMA = 2, + SHOT_MODE_SMILE = 3, + SHOT_MODE_SELF = 6, + }; + + enum CHK_DATALINE { + CHK_DATALINE_OFF, + CHK_DATALINE_ON, + CHK_DATALINE_MAX, + }; + + int m_touch_af_start_stop; + + SecCamera(); + virtual ~SecCamera(); + + static SecCamera* createInstance(void) + { + static SecCamera singleton; + return &singleton; + } + status_t dump(int fd); + + bool CreateCamera(int index); + bool DestroyCamera(void); + int getCameraId(void); + + int startPreview(void); + int stopPreview(void); + int getPreviewState(void) + { + return m_preview_state; + } + void clearPreviewState(void) + { + m_preview_state = 0; + } + + int startRecord(void); + int stopRecord(void); + int setPreviewFrame(int index); + int getRecordFrame(void); + int releaseRecordFrame(int index); + int getRecordAddr(int index, SecBuffer *buffer); + + int getPreview(void); + int setPreviewSize(int width, int height, int pixel_format); + int getPreviewSize(int *width, int *height, int *frame_size); + int getPreviewMaxSize(int *width, int *height); + int getPreviewPixelFormat(void); + int setPreviewImage(int index, unsigned char *buffer, int size); + + int setSnapshotSize(int width, int height); + int getSnapshotSize(int *width, int *height, int *frame_size); + int getSnapshotMaxSize(int *width, int *height); + int setSnapshotPixelFormat(int pixel_format); + int getSnapshotPixelFormat(void); + + unsigned char* getJpeg(unsigned char *snapshot_data, int snapshot_size, int *size); + unsigned char* yuv2Jpeg(unsigned char *raw_data, int raw_size, + int *jpeg_size, + int width, int height, int pixel_format); + + int setJpegThumbnailSize(int width, int height); + int getJpegThumbnailSize(int *width, int *height); + + int setJpegThumbnailQuality(int jpeg_thumbnail_quality); + int getJpegThumbnailQuality(void); + + int setAutofocus(void); + + int SetRotate(int angle); + int getRotate(void); + + int setVerticalMirror(void); + int setHorizontalMirror(void); + + int setWhiteBalance(int white_balance); + int getWhiteBalance(void); + + int setBrightness(int brightness); + int getBrightness(void); + + int setExposure(int exposure); + int getExposure(void); + + int setImageEffect(int image_effect); + int getImageEffect(void); + + int setSceneMode(int scene_mode); + int getSceneMode(void); + + int setFlashMode(int flash_mode); + int getFlashMode(void); + + int setMetering(int metering_value); + int getMetering(void); + + int setISO(int iso_value); + int getISO(void); + + int setContrast(int contrast_value); + int getContrast(void); + + int setSaturation(int saturation_value); + int getSaturation(void); + + int setSharpness(int sharpness_value); + int getSharpness(void); + + int setHue(int hue_value); + int getHue(void); + + int setWDR(int wdr_value); + int getWDR(void); + + int setAntiShake(int anti_shake); + int getAntiShake(void); + + int setJpegQuality(int jpeg_qality); + int getJpegQuality(void); + + int setZoom(int zoom_level); + int getZoom(void); + + int setObjectTracking(int object_tracking); + int getObjectTracking(void); + int getObjectTrackingStatus(void); + + int setSmartAuto(int smart_auto); + int getSmartAuto(void); + int getAutosceneStatus(void); + + int setBeautyShot(int beauty_shot); + int getBeautyShot(void); + + int setVintageMode(int vintage_mode); + int getVintageMode(void); + + int setFocusMode(int focus_mode); + int getFocusMode(void); + + int setFaceDetect(int face_detect); + int getFaceDetect(void); + + int setGPSLatitude(const char *gps_latitude); + int setGPSLongitude(const char *gps_longitude); + int setGPSAltitude(const char *gps_altitude); + int setGPSTimeStamp(const char *gps_timestamp); + int setGPSProcessingMethod(const char *gps_timestamp); + int cancelAutofocus(void); + int setFaceDetectLockUnlock(int facedetect_lockunlock); + int setObjectPosition(int x, int y); + int setObjectTrackingStartStop(int start_stop); + int setTouchAFStartStop(int start_stop); + int setCAFStatus(int on_off); + int getAutoFocusResult(void); + int setAntiBanding(int anti_banding); + int getPostview(void); + int setRecording(int recording_en); + int setRecordingSize(int width, int height); + int getRecordingSize(int *width, int *height); + int setGamma(int gamma); + int setSlowAE(int slow_ae); + int setExifOrientationInfo(int orientationInfo); + int setBatchReflection(void); + int setSnapshotCmd(void); + int endSnapshot(void); + int setCameraSensorReset(void); + int setSensorMode(int sensor_mode); /* Camcorder fix fps */ + int setShotMode(int shot_mode); /* Shot mode */ + int setDataLineCheck(int chk_dataline); + int getDataLineCheck(void); + int setDataLineCheckStop(void); + int setDefultIMEI(int imei); + int getDefultIMEI(void); + const __u8* getCameraSensorName(void); +#ifdef ENABLE_ESD_PREVIEW_CHECK + int getCameraSensorESDStatus(void); +#endif // ENABLE_ESD_PREVIEW_CHECK + + int setFrameRate(int frame_rate); + unsigned char* getJpeg(int*, unsigned int*); + int getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf, + unsigned int *output_size); + int getExif(unsigned char *pExifDst, unsigned char *pThumbSrc); + + void getPostViewConfig(int*, int*, int*); + void getThumbnailConfig(int *width, int *height, int *size); + + int getPostViewOffset(void); + int getCameraFd(void); + unsigned char* getPictureVaddr(void); + int getJpegFd(void); + void SetJpgAddr(unsigned char *addr); + int getPreviewAddr(int index, SecBuffer *buffer); + void setUserBufferAddr(void *ptr, int index, int mode); + static void setJpegRatio(double ratio) + { + if((ratio < 0) || (ratio > 1)) + return; + + jpeg_ratio = ratio; + } + + static double getJpegRatio() + { + return jpeg_ratio; + } + + static void setInterleaveDataSize(int x) + { + interleaveDataSize = x; + } + + static int getInterleaveDataSize() + { + return interleaveDataSize; + } + + static void setJpegLineLength(int x) + { + jpegLineLength = x; + } + + static int getJpegLineLength() + { + return jpegLineLength; + } + +private: + v4l2_streamparm m_streamparm; + struct sec_cam_parm *m_params; + int m_flagCreate; + int m_preview_state; + int m_camera_id; + + /* v4l2 sub-dev file description */ + int m_cam_sd_fd; + int m_mipi_sd_fd; + int m_flite_sd_fd; + int m_gsc_sd_fd; + int m_gsc_vd_fd; + + /* media controller variable */ + struct media_device *media; + struct media_link *links; + struct media_pad *pads; + + struct media_entity *camera_sd_entity; + struct media_entity *mipi_sd_entity; + struct media_entity *flite_sd_entity; + struct media_entity *gsc_cap_sd_entity; + struct media_entity *gsc_cap_vd_entity; + struct media_entity *isp_sensor_entity; + struct media_entity *isp_front_entity; + struct media_entity *isp_back_entity; + struct media_entity *isp_scalerc_entity; + struct media_entity *isp_scalerp_entity; + struct media_entity *isp_3dnr_entity; + + int m_cam_fd; + + int m_cam_fd2; + struct pollfd m_events_c2; + int m_flag_record_start; + + int m_preview_v4lformat; + int m_preview_width; + int m_preview_height; + int m_preview_max_width; + int m_preview_max_height; + + int m_snapshot_v4lformat; + int m_snapshot_width; + int m_snapshot_height; + int m_snapshot_max_width; + int m_snapshot_max_height; + unsigned char* m_picture_vaddr; + + int m_angle; + int m_anti_banding; + int m_wdr; + int m_anti_shake; + int m_zoom_level; + int m_object_tracking; + int m_smart_auto; + int m_beauty_shot; + int m_vintage_mode; + int m_face_detect; + int m_object_tracking_start_stop; + int m_recording_en; + int m_recording_width; + int m_recording_height; + long m_gps_latitude; + long m_gps_longitude; + long m_gps_altitude; + long m_gps_timestamp; + int m_sensor_mode; /*Camcorder fix fps */ + int m_shot_mode; /* Shot mode */ + int m_exif_orientation; + int m_chk_dataline; + int m_video_gamma; + int m_slow_ae; + int m_camera_af_flag; + + int m_flag_camera_start; + + int m_jpeg_fd; + int m_jpeg_thumbnail_width; + int m_jpeg_thumbnail_height; + int m_jpeg_thumbnail_quality; + int m_jpeg_quality; + + int m_postview_offset; + +#ifdef ENABLE_ESD_PREVIEW_CHECK + int m_esd_check_count; +#endif // ENABLE_ESD_PREVIEW_CHECK + + exif_attribute_t mExifInfo; + + struct SecBuffer m_capture_buf; + struct SecBuffer m_buffers_preview[MAX_BUFFERS]; + struct SecBuffer m_buffers_record[MAX_BUFFERS]; + struct pollfd m_events_c; + + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + uint32_t value); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start); + inline void writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start); + + void setExifChangedAttribute(); + void setExifFixedAttribute(); + int makeExif (unsigned char *exifOut, + unsigned char *thumb_buf, + unsigned int thumb_size, + exif_attribute_t *exifInfo, + unsigned int *size, + bool useMainbufForThumb); + void resetCamera(); + + static double jpeg_ratio; + static int interleaveDataSize; + static int jpegLineLength; +}; + +extern unsigned long measure_time_camera(struct timeval *start, struct timeval *stop); + +}; // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_SEC_H diff --git a/exynos5/hal/libcamera/SecCameraHWInterface.cpp b/exynos5/hal/libcamera/SecCameraHWInterface.cpp new file mode 100644 index 0000000..8cfbccc --- /dev/null +++ b/exynos5/hal/libcamera/SecCameraHWInterface.cpp @@ -0,0 +1,3043 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +//#define LOG_NDEBUG 0 +#define LOG_TAG "CameraHardwareSec" +#include + +#include "SecCameraHWInterface.h" +#include +#include +#include +#include +#include + +#define VIDEO_COMMENT_MARKER_H 0xFFBE +#define VIDEO_COMMENT_MARKER_L 0xFFBF +#define VIDEO_COMMENT_MARKER_LENGTH 4 +#define JPEG_EOI_MARKER 0xFFD9 +#define HIBYTE(x) (((x) >> 8) & 0xFF) +#define LOBYTE(x) ((x) & 0xFF) +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +#define BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR "0.10,1.20,Infinity" +#define BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR "0.10,0.20,Infinity" +#define BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR "0.10,1.20,Infinity" +#define FRONT_CAMERA_FOCUS_DISTANCES_STR "0.20,0.25,Infinity" +//#define USE_EGL + +// This hack does two things: +// -- it sets preview to NV21 (YUV420SP) +// -- it sets gralloc to YV12 +// +// The reason being: the samsung encoder understands only yuv420sp, and gralloc +// does yv12 and rgb565. So what we do is we break up the interleaved UV in +// separate V and U planes, which makes preview look good, and enabled the +// encoder as well. +// +// FIXME: Samsung needs to enable support for proper yv12 coming out of the +// camera, and to fix their video encoder to work with yv12. +// FIXME: It also seems like either Samsung's YUV420SP (NV21) or img's YV12 has +// the color planes switched. We need to figure which side is doing it +// wrong and have the respective party fix it. + +namespace android { + +struct addrs { + uint32_t type; // make sure that this is 4 byte. + unsigned int addr_y; + unsigned int addr_cbcr; + unsigned int buf_index; + unsigned int reserved; +}; + +struct addrs_cap { + unsigned int addr_y; + unsigned int width; + unsigned int height; +}; + +static const int INITIAL_SKIP_FRAME = 3; +static const int EFFECT_SKIP_FRAME = 1; + +gralloc_module_t const* CameraHardwareSec::mGrallocHal; + +CameraHardwareSec::CameraHardwareSec(int cameraId, camera_device_t *dev) + : + mCaptureInProgress(false), + mParameters(), + mFrameSizeDelta(0), + mCameraSensorName(NULL), + mSkipFrame(0), + mNotifyCb(0), + mDataCb(0), + mDataCbTimestamp(0), + mCallbackCookie(0), + mMsgEnabled(CAMERA_MSG_RAW_IMAGE), + mRecordRunning(false), + mPostViewWidth(0), + mPostViewHeight(0), + mPostViewSize(0), + mHalDevice(dev) +{ + LOGV("%s :", __func__); + int ret = 0; + + mPreviewWindow = NULL; + mSecCamera = SecCamera::createInstance(); + + mRawHeap = NULL; + mPreviewHeap = NULL; + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) + mRecordHeap[i] = NULL; + + if (!mGrallocHal) { + ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal); + if (ret) + LOGE("ERR(%s):Fail on loading gralloc HAL", __func__); + } + + ret = mSecCamera->CreateCamera(cameraId); + if (ret < 0) { + LOGE("ERR(%s):Fail on mSecCamera init", __func__); + mSecCamera->DestroyCamera(); + } + + initDefaultParameters(cameraId); + + mExitAutoFocusThread = false; + mExitPreviewThread = false; + /* whether the PreviewThread is active in preview or stopped. we + * create the thread but it is initially in stopped state. + */ + mPreviewRunning = false; + mPreviewStartDeferred = false; + mPreviewThread = new PreviewThread(this); + mAutoFocusThread = new AutoFocusThread(this); + mPictureThread = new PictureThread(this); +} + +int CameraHardwareSec::getCameraId() const +{ + return mSecCamera->getCameraId(); +} + +void CameraHardwareSec::initDefaultParameters(int cameraId) +{ + if (mSecCamera == NULL) { + LOGE("ERR(%s):mSecCamera object is NULL", __func__); + return; + } + + CameraParameters p; + CameraParameters ip; + +#ifndef GAIA_FW_BETA + mCameraSensorName = mSecCamera->getCameraSensorName(); + if (mCameraSensorName == NULL) { + LOGE("ERR(%s):mCameraSensorName is NULL", __func__); + return; + } + LOGV("CameraSensorName: %s", mCameraSensorName); + int Internal_is = !strncmp((const char*)mCameraSensorName, "ISP Camera", 10); +#else + int Internal_is = 0; + //sprintf((char *)mCameraSensorName, "%s", "temp name"); +#endif + int preview_max_width = 0; + int preview_max_height = 0; + int snapshot_max_width = 0; + int snapshot_max_height = 0; + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + "3264x2448,2576x1948,1920x1080,1280x720,800x480,720x480,640x480,320x240,528x432,176x144"); + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + "3264x2448,1920x1080,1280x720,800x480,720x480,640x480"); + if (Internal_is) + p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, + "1920x1080,1280x720,640x480,176x144"); + } else { + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + "1392x1392,1280x720,640x480,352x288,320x240,176x144"); + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + "1392x1392,1280x960,640x480"); + if (Internal_is) + p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, + "1280x720,640x480,176x144"); + } + + p.getSupportedPreviewSizes(mSupportedPreviewSizes); + + // If these fail, then we are using an invalid cameraId and we'll leave the + // sizes at zero to catch the error. + if (mSecCamera->getPreviewMaxSize(&preview_max_width, + &preview_max_height) < 0) + LOGE("getPreviewMaxSize fail (%d / %d)", + preview_max_width, preview_max_height); + if (mSecCamera->getSnapshotMaxSize(&snapshot_max_width, + &snapshot_max_height) < 0) + LOGE("getSnapshotMaxSize fail (%d / %d)", + snapshot_max_width, snapshot_max_height); + + p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420P); mFrameSizeDelta = 16; + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, CameraParameters::PIXEL_FORMAT_YUV420P); + p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420SP); + p.setPreviewSize(preview_max_width, preview_max_height); + + p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG); + p.setPictureSize(snapshot_max_width, snapshot_max_height); + p.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // maximum quality + p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, + CameraParameters::PIXEL_FORMAT_JPEG); + + p.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1280x720"); + + String8 parameterString; + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + parameterString = CameraParameters::FOCUS_MODE_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::FOCUS_MODE_INFINITY); + parameterString.append(","); + parameterString.append(CameraParameters::FOCUS_MODE_MACRO); + p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_FOCUS_MODE, + CameraParameters::FOCUS_MODE_AUTO); + p.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR); + p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, + "320x240,0x0"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240"); + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30"); + p.setPreviewFrameRate(30); + } else { + parameterString = CameraParameters::FOCUS_MODE_FIXED; + p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_FOCUS_MODE, + CameraParameters::FOCUS_MODE_FIXED); + p.set(CameraParameters::KEY_FOCUS_DISTANCES, + FRONT_CAMERA_FOCUS_DISTANCES_STR); + p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, + "160x120,0x0"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "160"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "120"); + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30"); + p.setPreviewFrameRate(30); + } + + parameterString = CameraParameters::EFFECT_NONE; + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_MONO); + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_NEGATIVE); + parameterString.append(","); + parameterString.append(CameraParameters::EFFECT_SEPIA); + p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, parameterString.string()); + + if (cameraId == SecCamera::CAMERA_ID_BACK) { + parameterString = CameraParameters::FLASH_MODE_ON; + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_OFF); + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_AUTO); + parameterString.append(","); + parameterString.append(CameraParameters::FLASH_MODE_TORCH); + p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_FLASH_MODE, + CameraParameters::FLASH_MODE_OFF); + + parameterString = CameraParameters::SCENE_MODE_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_PORTRAIT); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_LANDSCAPE); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_BEACH); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_SNOW); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_FIREWORKS); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_SPORTS); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_PARTY); + parameterString.append(","); + parameterString.append(CameraParameters::SCENE_MODE_CANDLELIGHT); + p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, + parameterString.string()); + p.set(CameraParameters::KEY_SCENE_MODE, + CameraParameters::SCENE_MODE_AUTO); + + /* we have two ranges, 4-30fps for night mode and + * 15-30fps for all others + */ + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)"); + p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000"); + + p.set(CameraParameters::KEY_FOCAL_LENGTH, "3.43"); + } else { + p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(7500,30000)"); + p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "7500,30000"); + + p.set(CameraParameters::KEY_FOCAL_LENGTH, "0.9"); + } + + parameterString = CameraParameters::WHITE_BALANCE_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_INCANDESCENT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_FLUORESCENT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_DAYLIGHT); + parameterString.append(","); + parameterString.append(CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT); + p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, + parameterString.string()); + + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "100"); + + p.set(CameraParameters::KEY_ROTATION, 0); + p.set(CameraParameters::KEY_WHITE_BALANCE, CameraParameters::WHITE_BALANCE_AUTO); + + p.set(CameraParameters::KEY_EFFECT, CameraParameters::EFFECT_NONE); + + p.set("contrast", "auto"); + p.set("iso", "auto"); + p.set("metering", "center"); + p.set("wdr", 0); + + ip.set("chk_dataline", 0); + if (cameraId == SecCamera::CAMERA_ID_FRONT) { + ip.set("vtmode", 0); + ip.set("blur", 0); + } + + p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "51.2"); + p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "39.4"); + + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); + p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "2"); + p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-2"); + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "1"); + + p.set("brightness", 0); + p.set("brightness-max", 2); + p.set("brightness-min", -2); + + p.set("saturation", 0); + p.set("saturation-max", 2); + p.set("saturation-min", -2); + + p.set("sharpness", 0); + p.set("sharpness-max", 2); + p.set("sharpness-min", -2); + + p.set("hue", 0); + p.set("hue-max", 2); + p.set("hue-min", -2); + + parameterString = CameraParameters::ANTIBANDING_AUTO; + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_50HZ); + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_60HZ); + parameterString.append(","); + parameterString.append(CameraParameters::ANTIBANDING_OFF); + p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, + parameterString.string()); + + p.set(CameraParameters::KEY_ANTIBANDING, CameraParameters::ANTIBANDING_OFF); + + mParameters = p; + mInternalParameters = ip; + + /* make sure mSecCamera has all the settings we do. applications + * aren't required to call setParameters themselves (only if they + * want to change something. + */ + setParameters(p); + if (cameraId == SecCamera::CAMERA_ID_BACK) + mSecCamera->setFrameRate(BACK_CAMERA_FPS); + else + mSecCamera->setFrameRate(FRONT_CAMERA_FPS); +} + +CameraHardwareSec::~CameraHardwareSec() +{ + LOGV("%s", __func__); + mSecCamera->DestroyCamera(); +} + +status_t CameraHardwareSec::setPreviewWindow(preview_stream_ops *w) +{ + int min_bufs; + + mPreviewWindow = w; + LOGV("%s: mPreviewWindow %p", __func__, mPreviewWindow); + + if (!w) { + LOGE("preview window is NULL!"); + return OK; + } + + mPreviewLock.lock(); + + if (mPreviewRunning && !mPreviewStartDeferred) { + LOGI("stop preview (window change)"); + stopPreviewInternal(); + } + + if (w->get_min_undequeued_buffer_count(w, &min_bufs)) { + LOGE("%s: could not retrieve min undequeued buffer count", __func__); + return INVALID_OPERATION; + } + + if (min_bufs >= BUFFER_COUNT_FOR_GRALLOC) { + LOGE("%s: min undequeued buffer count %d is too high (expecting at most %d)", __func__, + min_bufs, BUFFER_COUNT_FOR_GRALLOC - 1); + } + + LOGV("%s: setting buffer count to %d", __func__, BUFFER_COUNT_FOR_GRALLOC); + if (w->set_buffer_count(w, BUFFER_COUNT_FOR_GRALLOC)) { + LOGE("%s: could not set buffer count", __func__); + return INVALID_OPERATION; + } + + int preview_width; + int preview_height; + mParameters.getPreviewSize(&preview_width, &preview_height); + + int hal_pixel_format; + + const char *str_preview_format = mParameters.getPreviewFormat(); + LOGV("%s: str preview format %s width : %d height : %d ", __func__, str_preview_format, preview_width, preview_height); + mFrameSizeDelta = 16; + + hal_pixel_format = HAL_PIXEL_FORMAT_YV12; + + if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_RGB565)) { + hal_pixel_format = HAL_PIXEL_FORMAT_RGB_565; + mFrameSizeDelta = 0; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_RGBA8888)) { + hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888; + mFrameSizeDelta = 0; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420SP)) { + hal_pixel_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + } else if (!strcmp(str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420P)) + hal_pixel_format = HAL_PIXEL_FORMAT_YV12; + +#ifdef USE_EGL + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_ION)) { + LOGE("%s: could not set usage on gralloc buffer", __func__); + return INVALID_OPERATION; + } +#else + if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN + | GRALLOC_USAGE_HWC_HWOVERLAY | GRALLOC_USAGE_HW_ION)) { + LOGE("%s: could not set usage on gralloc buffer", __func__); + return INVALID_OPERATION; + } +#endif + + if (w->set_buffers_geometry(w, + preview_width, preview_height, + hal_pixel_format)) { + LOGE("%s: could not set buffers geometry to %s", + __func__, str_preview_format); + return INVALID_OPERATION; + } + + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) + if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) { + LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i); + return INVALID_OPERATION; + } + + if (mPreviewRunning && mPreviewStartDeferred) { + LOGV("start/resume preview"); + status_t ret = startPreviewInternal(); + if (ret == OK) { + mPreviewStartDeferred = false; + mPreviewCondition.signal(); + } + } + mPreviewLock.unlock(); + + return OK; +} + +void CameraHardwareSec::setCallbacks(camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user) +{ + mNotifyCb = notify_cb; + mDataCb = data_cb; + mDataCbTimestamp = data_cb_timestamp; + mGetMemoryCb = get_memory; + mCallbackCookie = user; +} + +void CameraHardwareSec::enableMsgType(int32_t msgType) +{ + LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x", + __func__, msgType, mMsgEnabled); + mMsgEnabled |= msgType; + + mPreviewLock.lock(); + if ((msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_VIDEO_FRAME)) && + mPreviewRunning && mPreviewStartDeferred) { + LOGV("%s: starting deferred preview", __func__); + if (startPreviewInternal() == OK) { + mPreviewStartDeferred = false; + mPreviewCondition.signal(); + } + } + mPreviewLock.unlock(); + + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); +} + +void CameraHardwareSec::disableMsgType(int32_t msgType) +{ + LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x", + __func__, msgType, mMsgEnabled); + mMsgEnabled &= ~msgType; + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); +} + +bool CameraHardwareSec::msgTypeEnabled(int32_t msgType) +{ + return (mMsgEnabled & msgType); +} + +void CameraHardwareSec::setSkipFrame(int frame) +{ + Mutex::Autolock lock(mSkipFrameLock); + if (frame < mSkipFrame) + return; + + mSkipFrame = frame; +} + +int CameraHardwareSec::previewThreadWrapper() +{ + LOGI("%s: starting", __func__); + while (1) { + mPreviewLock.lock(); + while (!mPreviewRunning) { + LOGI("%s: calling mSecCamera->stopPreview() and waiting", __func__); + mSecCamera->stopPreview(); + /* signal that we're stopping */ + mPreviewStoppedCondition.signal(); + mPreviewCondition.wait(mPreviewLock); + LOGI("%s: return from wait", __func__); + } + mPreviewLock.unlock(); + + if (mExitPreviewThread) { + LOGI("%s: exiting", __func__); + mSecCamera->stopPreview(); + return 0; + } + previewThread(); + } +} + +int CameraHardwareSec::previewThread() +{ + int index; + nsecs_t timestamp; + SecBuffer previewAddr, recordAddr; + static int numArray = 0; + void *virAddr[3]; + private_handle_t *hnd = NULL; + + index = mSecCamera->getPreview(); + + if (index < 0) { + LOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__); + if (mSecCamera->getPreviewState()) { + stopPreview(); + startPreview(); + mSecCamera->clearPreviewState(); + } + return UNKNOWN_ERROR; + } + + mSkipFrameLock.lock(); + if (mSkipFrame > 0) { + mSkipFrame--; + mSkipFrameLock.unlock(); + LOGV("%s: index %d skipping frame", __func__, index); + if (mSecCamera->setPreviewFrame(index) < 0) { + LOGE("%s: Could not qbuff[%d]!!", __func__, index); + return UNKNOWN_ERROR; + } + return NO_ERROR; + } + mSkipFrameLock.unlock(); + + timestamp = systemTime(SYSTEM_TIME_MONOTONIC); + + int width, height, frame_size, offset; + + mSecCamera->getPreviewSize(&width, &height, &frame_size); + + offset = frame_size * index; + + if (mPreviewWindow && mGrallocHal && mPreviewRunning) { + hnd = (private_handle_t*)*mBufferHandle[index]; + + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + + mPreviewHeap = mGetMemoryCb(hnd->fd, frame_size, 1, 0); + + hnd = NULL; + + mGrallocHal->unlock(mGrallocHal, *mBufferHandle[index]); + if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[index])) { + LOGE("%s: Could not enqueue gralloc buffer[%d]!!", __func__, index); + goto callbacks; + } + + numArray = index; + + if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[numArray], &mStride[numArray])) { + LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, numArray); + goto callbacks; + } + + if (!mGrallocHal->lock(mGrallocHal, + *mBufferHandle[numArray], + GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR, + 0, 0, width, height, virAddr)) { + mSecCamera->getPreviewAddr(index, &previewAddr); + char *frame = (char *)previewAddr.virt.extP[0]; + +#ifdef USE_EGL + int m_Ywidth = ALIGN(width, 16); + int m_Yheight = ALIGN(height, 16); + int m_UVwidth = ALIGN(width/2, 8); + int m_UVheight = ALIGN(height/2, 8); + virAddr[1] = virAddr[0] + (m_Ywidth * m_Yheight); + virAddr[2] = virAddr[1] + (m_UVwidth * m_UVheight); +#endif + + mSecCamera->setUserBufferAddr(virAddr, index, PREVIEW_MODE); + } + else + LOGE("%s: could not obtain gralloc buffer", __func__); + + if (mSecCamera->setPreviewFrame(index) < 0) { + LOGE("%s: Fail qbuf, index(%d)", __func__, index); + goto callbacks; + } + index = 0; + } + +callbacks: + // Notify the client of a new frame. + if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) + mDataCb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap, index, NULL, mCallbackCookie); + + Mutex::Autolock lock(mRecordLock); + if (mRecordRunning == true) { + int recordingIndex = 0; + + index = mSecCamera->getRecordFrame(); + if (index < 0) { + LOGE("ERR(%s):Fail on SecCamera->getRecordFrame()", __func__); + return UNKNOWN_ERROR; + } + + numArray = index; + + // Notify the client of a new frame. + if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) + mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, + mRecordHeap[numArray], recordingIndex, mCallbackCookie); + else + mSecCamera->releaseRecordFrame(index); + } + + return NO_ERROR; +} + +status_t CameraHardwareSec::startPreview() +{ + int ret = 0; + + LOGV("%s :", __func__); + + Mutex::Autolock lock(mStateLock); + if (mCaptureInProgress) { + LOGE("%s : capture in progress, not allowed", __func__); + return INVALID_OPERATION; + } + + mPreviewLock.lock(); + if (mPreviewRunning) { + // already running + LOGE("%s : preview thread already running", __func__); + mPreviewLock.unlock(); + return INVALID_OPERATION; + } + + mPreviewRunning = true; + mPreviewStartDeferred = false; + + if (!mPreviewWindow && + !(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) && + !(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) { + LOGI("%s : deferring", __func__); + mPreviewStartDeferred = true; + mPreviewLock.unlock(); + return NO_ERROR; + } + + ret = startPreviewInternal(); + if (ret == OK) + mPreviewCondition.signal(); + + mPreviewLock.unlock(); + return ret; +} + +status_t CameraHardwareSec::startPreviewInternal() +{ + LOGV("%s", __func__); + int width, height, frame_size; + + mSecCamera->getPreviewSize(&width, &height, &frame_size); + LOGD("mPreviewHeap(fd(%d), size(%d), width(%d), height(%d))", + mSecCamera->getCameraFd(), frame_size + mFrameSizeDelta, width, height); + + void *vaddr[3]; + + for (int i = 0; i < MAX_BUFFERS; i++) { + !mGrallocHal->lock(mGrallocHal, + *mBufferHandle[i], + GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR, + 0, 0, width, height, vaddr); + memset(vaddr[0], 0, width*height*2); + int m_Ywidth = ALIGN(width, 16); + int m_Yheight = ALIGN(height, 16); + int m_UVwidth = ALIGN(width/2, 8); + int m_UVheight = ALIGN(height/2, 8); + vaddr[1] = vaddr[0] + (m_Ywidth * m_Yheight); + vaddr[2] = vaddr[1] + (m_UVwidth * m_UVheight); + mSecCamera->setUserBufferAddr(vaddr, i, PREVIEW_MODE); + } + + int ret = mSecCamera->startPreview(); + LOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret); + + if (ret < 0) { + LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__); + return UNKNOWN_ERROR; + } + + setSkipFrame(INITIAL_SKIP_FRAME); + + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + LOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d", + mPostViewWidth,mPostViewHeight,mPostViewSize); + + return NO_ERROR; +} + +void CameraHardwareSec::stopPreviewInternal() +{ + LOGV("%s :", __func__); + + /* request that the preview thread stop. */ + if (mPreviewRunning) { + mPreviewRunning = false; + if (!mPreviewStartDeferred) { + mPreviewCondition.signal(); + /* wait until preview thread is stopped */ + mPreviewStoppedCondition.wait(mPreviewLock); + + for (int i = 0; i < MAX_BUFFERS; i++) { + if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[i])) + LOGE("%s: Fail to enqueue buffer[%d]", __func__, i); + } + } + else + LOGV("%s : preview running but deferred, doing nothing", __func__); + } else + LOGI("%s : preview not running, doing nothing", __func__); +} + +void CameraHardwareSec::stopPreview() +{ + LOGV("%s :", __func__); + + /* request that the preview thread stop. */ + mPreviewLock.lock(); + stopPreviewInternal(); + mPreviewLock.unlock(); +} + +bool CameraHardwareSec::previewEnabled() +{ + Mutex::Autolock lock(mPreviewLock); + LOGV("%s : %d", __func__, mPreviewRunning); + return mPreviewRunning; +} + +status_t CameraHardwareSec::startRecording() +{ + LOGV("%s :", __func__); + + Mutex::Autolock lock(mRecordLock); + + for(int i = 0; irelease(mRecordHeap[i]); + mRecordHeap[i] = 0; + } + + int width, height; + + mSecCamera->getRecordingSize(&width, &height); + mRecordHeap[i] = mGetMemoryCb(-1, (ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048) + + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048)), 1, NULL); + mSecCamera->setUserBufferAddr((void *)(mRecordHeap[i]->data), i, RECORD_MODE); + if (!mRecordHeap[i]) { + LOGE("ERR(%s): Record heap[%d] creation fail", __func__, i); + return UNKNOWN_ERROR; + } + } + + LOGV("mRecordHeaps alloc done"); + + if (mRecordRunning == false) { + if (mSecCamera->startRecord() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__); + return UNKNOWN_ERROR; + } + mRecordRunning = true; + } + return NO_ERROR; +} + +void CameraHardwareSec::stopRecording() +{ + LOGV("%s :", __func__); + + Mutex::Autolock lock(mRecordLock); + + if (mRecordRunning == true) { + if (mSecCamera->stopRecord() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __func__); + return; + } + mRecordRunning = false; + } +} + +bool CameraHardwareSec::recordingEnabled() +{ + LOGV("%s :", __func__); + LOGV("%s : %d", __func__, mPreviewRunning); + + return mRecordRunning; +} + +void CameraHardwareSec::releaseRecordingFrame(const void *opaque) +{ + int i; + for (i = 0; i < MAX_BUFFERS; i++) + if ((char *)mRecordHeap[i]->data == (char *)opaque) + break; + + mSecCamera->releaseRecordFrame(i); +} + +int CameraHardwareSec::autoFocusThread() +{ + int count =0; + int af_status =0 ; + + LOGV("%s : starting", __func__); + + + /* block until we're told to start. we don't want to use + * a restartable thread and requestExitAndWait() in cancelAutoFocus() + * because it would cause deadlock between our callbacks and the + * caller of cancelAutoFocus() which both want to grab the same lock + * in CameraServices layer. + */ + mFocusLock.lock(); + /* check early exit request */ + if (mExitAutoFocusThread) { + mFocusLock.unlock(); + LOGV("%s : exiting on request0", __func__); + return NO_ERROR; + } + mFocusCondition.wait(mFocusLock); + /* check early exit request */ + if (mExitAutoFocusThread) { + mFocusLock.unlock(); + LOGV("%s : exiting on request1", __func__); + return NO_ERROR; + } + mFocusLock.unlock(); + +#ifdef GAIA_FW_BETA + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); + + //LOGV("%s : exiting with no error", __func__); + return NO_ERROR; +#else + +#ifdef AF_SUPPORT + LOGV("%s : calling setAutoFocus", __func__); + if (mSecCamera->setAutofocus() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__); + return UNKNOWN_ERROR; + } + + af_status = mSecCamera->getAutoFocusResult(); +#else + sleep(1); + af_status = 0x02; +#endif + + if (af_status == 0x01) { + LOGV("%s : AF Success!!", __func__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + } else if (af_status == 0x02) { + LOGV("%s : AF Cancelled !!", __func__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) { + /* CAMERA_MSG_FOCUS only takes a bool. true for + * finished and false for failure. cancel is still + * considered a true result. + */ + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + } + } else { + LOGV("%s : AF Fail !!", __func__); + LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); + } + + LOGV("%s : exiting with no error", __func__); + return NO_ERROR; +#endif +} + +status_t CameraHardwareSec::autoFocus() +{ + LOGV("%s :", __func__); + /* signal autoFocusThread to run once */ + mFocusCondition.signal(); + return NO_ERROR; +} + +status_t CameraHardwareSec::cancelAutoFocus() +{ + LOGV("%s :", __func__); +#ifndef GAIA_FW_BETA + + if (mSecCamera->cancelAutofocus() < 0) { + LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __func__); + return UNKNOWN_ERROR; + } +#endif + return NO_ERROR; +} + +int CameraHardwareSec::save_jpeg( unsigned char *real_jpeg, int jpeg_size) +{ + FILE *yuv_fp = NULL; + char filename[100], *buffer = NULL; + + /* file create/open, note to "wb" */ + yuv_fp = fopen("/data/camera_dump.jpeg", "wb"); + if (yuv_fp == NULL) { + LOGE("Save jpeg file open error"); + return -1; + } + + LOGV("[BestIQ] real_jpeg size ========> %d", jpeg_size); + buffer = (char *) malloc(jpeg_size); + if (buffer == NULL) { + LOGE("Save YUV] buffer alloc failed"); + if (yuv_fp) + fclose(yuv_fp); + + return -1; + } + + memcpy(buffer, real_jpeg, jpeg_size); + + fflush(stdout); + + fwrite(buffer, 1, jpeg_size, yuv_fp); + + fflush(yuv_fp); + + if (yuv_fp) + fclose(yuv_fp); + if (buffer) + free(buffer); + + return 0; +} + +void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t size) +{ + int nw; + int cnt = 0; + uint32_t written = 0; + + LOGD("opening file [%s]", fname); + int fd = open(fname, O_RDWR | O_CREAT); + if (fd < 0) { + LOGE("failed to create file [%s]: %s", fname, strerror(errno)); + return; + } + + LOGD("writing %d bytes to file [%s]", size, fname); + while (written < size) { + nw = ::write(fd, buf + written, size - written); + if (nw < 0) { + LOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno)); + break; + } + written += nw; + cnt++; + } + LOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt); + ::close(fd); +} + +bool CameraHardwareSec::scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHeight, + char *dstBuf, uint32_t dstWidth, uint32_t dstHeight) +{ + int32_t step_x, step_y; + int32_t iXsrc, iXdst; + int32_t x, y, src_y_start_pos, dst_pos, src_pos; + + if (dstWidth % 2 != 0 || dstHeight % 2 != 0) { + LOGE("scale_down_yuv422: invalid width, height for scaling"); + return false; + } + + step_x = srcWidth / dstWidth; + step_y = srcHeight / dstHeight; + + dst_pos = 0; + for (uint32_t y = 0; y < dstHeight; y++) { + src_y_start_pos = (y * step_y * (srcWidth * 2)); + + for (uint32_t x = 0; x < dstWidth; x += 2) { + src_pos = src_y_start_pos + (x * (step_x * 2)); + + dstBuf[dst_pos++] = srcBuf[src_pos ]; + dstBuf[dst_pos++] = srcBuf[src_pos + 1]; + dstBuf[dst_pos++] = srcBuf[src_pos + 2]; + dstBuf[dst_pos++] = srcBuf[src_pos + 3]; + } + } + + return true; +} + +bool CameraHardwareSec::YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight) +{ + int32_t x, y, src_y_start_pos, dst_cbcr_pos, dst_pos, src_pos; + unsigned char *srcBufPointer = (unsigned char *)srcBuf; + unsigned char *dstBufPointer = (unsigned char *)dstBuf; + + dst_pos = 0; + dst_cbcr_pos = srcWidth*srcHeight; + for (uint32_t y = 0; y < srcHeight; y++) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 2) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_pos++] = srcBufPointer[src_pos]; + } + } + for (uint32_t y = 0; y < srcHeight; y += 2) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 4) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 3]; + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 1]; + } + } + + return true; +} + +int CameraHardwareSec::pictureThread() +{ + LOGV("%s :", __func__); + + int jpeg_size = 0; + int ret = NO_ERROR; + unsigned char *jpeg_data = NULL; + int postview_offset = 0; + unsigned char *postview_data = NULL; + + unsigned char *addr = NULL; + int mPostViewWidth, mPostViewHeight, mPostViewSize; + int mThumbWidth, mThumbHeight, mThumbSize; + int cap_width, cap_height, cap_frame_size; + + unsigned int output_size = 0; + + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + mSecCamera->getThumbnailConfig(&mThumbWidth, &mThumbHeight, &mThumbSize); + int postviewHeapSize = mPostViewSize; + mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); + int mJpegHeapSize; +#ifdef JPEG_FROM_SENSOR + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) + mJpegHeapSize = cap_frame_size * SecCamera::getJpegRatio(); + else +#endif + mJpegHeapSize = cap_frame_size; + + //sp buffer = new MemoryBase(mRawHeap, 0, mPostViewSize + 8); + + LOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight); + + camera_memory_t *JpegHeap = mGetMemoryCb(-1, mJpegHeapSize, 1, 0); +#ifndef GAIA_FW_BETA + sp PostviewHeap = new MemoryHeapBaseIon(mPostViewSize); + sp ThumbnailHeap = new MemoryHeapBaseIon(mThumbSize); +#else + sp PostviewHeap = new MemoryHeapBase(mPostViewSize); + sp ThumbnailHeap = new MemoryHeapBase(mThumbSize); +#endif + + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { + int picture_size, picture_width, picture_height; + mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size); + int picture_format = mSecCamera->getSnapshotPixelFormat(); + + unsigned int phyAddr; + + // Modified the shutter sound timing for Jpeg capture +#ifdef JPEG_FROM_SENSOR + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) + mSecCamera->setSnapshotCmd(); + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){ + jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr); + if (jpeg_data == NULL) { + LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __func__); + ret = UNKNOWN_ERROR; + } + } else { +#endif + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(), + (unsigned char*)JpegHeap->data, &output_size) < 0) { + mStateLock.lock(); + mCaptureInProgress = false; + mStateLock.unlock(); + JpegHeap->release(JpegHeap); + return UNKNOWN_ERROR; + } + LOGI("snapshotandjpeg done"); +#ifdef JPEG_FROM_SENSOR + } +#endif + } + + int JpegImageSize, JpegExifSize; + bool isLSISensor = false; + +#ifdef JPEG_FROM_SENSOR + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) { + LOGV("%s, %s", __func__, (const char*)mCameraSensorName); //to check sensor name + isLSISensor = !strncmp((const char*)mCameraSensorName, "S5K4ECGX", 8); + if (isLSISensor) { + LOGI("== Camera Sensor Detect %s - Samsung LSI SOC 5M ==", mCameraSensorName); + // LSI 5M SOC + if (!SplitFrame(jpeg_data, SecCamera::getInterleaveDataSize(), + SecCamera::getJpegLineLength(), + mPostViewWidth * 2, mPostViewWidth, + JpegHeap->data, &JpegImageSize, + PostviewHeap->base(), &mPostViewSize)) { + JpegHeap->release(JpegHeap); + return UNKNOWN_ERROR; + } + } else { + LOGI("== Camera Sensor Detect %s Sony SOC 5M ==", mCameraSensorName); + decodeInterleaveData(jpeg_data, + SecCamera::getInterleaveDataSize(), + mPostViewWidth, mPostViewHeight, + &JpegImageSize, JpegHeap->data, PostviewHeap->base()); + } + } else +#endif + JpegImageSize = static_cast(output_size); + + scaleDownYuv422((char *)mSecCamera->getPictureVaddr(), mPostViewWidth, mPostViewHeight, + (char *)ThumbnailHeap->base(), mThumbWidth, mThumbHeight); + +#ifdef GAIA_FW_BETA + int rawHeapSize = mPostViewSize; + LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize); + mRawHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(), rawHeapSize, 1, 0); + if (!mRawHeap) + LOGE("ERR(%s): Raw heap creation fail", __func__); + + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) + mDataCb(CAMERA_MSG_RAW_IMAGE, mRawHeap, 0, NULL, mCallbackCookie); +#endif + + mStateLock.lock(); + mCaptureInProgress = false; + mStateLock.unlock(); + + if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { + camera_memory_t *ExifHeap = + mGetMemoryCb(-1, EXIF_FILE_SIZE + mThumbSize, 1, 0); + + JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data, + (unsigned char *)ThumbnailHeap->base()); + LOGV("JpegExifSize=%d", JpegExifSize); + + if (JpegExifSize < 0) { + ret = UNKNOWN_ERROR; + goto out; + } + + int mJpegHeapSize_out = JpegImageSize + JpegExifSize; + camera_memory_t *JpegHeap_out = mGetMemoryCb(-1, mJpegHeapSize_out, 1, 0); + + unsigned char *ExifStart = (unsigned char *)JpegHeap_out->data + 2; + unsigned char *ImageStart = ExifStart + JpegExifSize; + + memcpy(JpegHeap_out->data, JpegHeap->data, 2); + memcpy(ExifStart, ExifHeap->data, JpegExifSize); + memcpy(ImageStart, JpegHeap->data + 2, JpegImageSize - 2); + + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, JpegHeap_out, 0, NULL, mCallbackCookie); + + if (ExifHeap) { + ExifHeap->release(ExifHeap); + ExifHeap = 0; + } + + if (JpegHeap_out) { + JpegHeap_out->release(JpegHeap_out); + JpegHeap_out = 0; + } + } + + LOGV("%s : pictureThread end", __func__); + +out: + if (JpegHeap) { + JpegHeap->release(JpegHeap); + JpegHeap = 0; + } + + if (mRawHeap) { + mRawHeap->release(mRawHeap); + mRawHeap = 0; + } + + return ret; +} + +status_t CameraHardwareSec::takePicture() +{ + LOGV("%s :", __func__); + + stopPreview(); + + Mutex::Autolock lock(mStateLock); + if (mCaptureInProgress) { + LOGE("%s : capture already in progress", __func__); + return INVALID_OPERATION; + } + + if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) { + LOGE("%s : couldn't run picture thread", __func__); + return INVALID_OPERATION; + } + mCaptureInProgress = true; + + return NO_ERROR; +} + +status_t CameraHardwareSec::cancelPicture() +{ + LOGV("%s", __func__); + + if (mPictureThread.get()) { + LOGV("%s: waiting for picture thread to exit", __func__); + mPictureThread->requestExitAndWait(); + LOGV("%s: picture thread has exited", __func__); + } + + return NO_ERROR; +} + +bool CameraHardwareSec::CheckVideoStartMarker(unsigned char *pBuf) +{ + if (!pBuf) { + LOGE("CheckVideoStartMarker() => pBuf is NULL"); + return false; + } + + if (HIBYTE(VIDEO_COMMENT_MARKER_H) == * pBuf && LOBYTE(VIDEO_COMMENT_MARKER_H) == *(pBuf + 1) && + HIBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 2) && LOBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 3)) + return true; + + return false; +} + +bool CameraHardwareSec::CheckEOIMarker(unsigned char *pBuf) +{ + if (!pBuf) { + LOGE("CheckEOIMarker() => pBuf is NULL"); + return false; + } + + // EOI marker [FF D9] + if (HIBYTE(JPEG_EOI_MARKER) == *pBuf && LOBYTE(JPEG_EOI_MARKER) == *(pBuf + 1)) + return true; + + return false; +} + +bool CameraHardwareSec::FindEOIMarkerInJPEG(unsigned char *pBuf, int dwBufSize, int *pnJPEGsize) +{ + if (NULL == pBuf || 0 >= dwBufSize) { + LOGE("FindEOIMarkerInJPEG() => There is no contents."); + return false; + } + + unsigned char *pBufEnd = pBuf + dwBufSize; + + while (pBuf < pBufEnd) { + if (CheckEOIMarker(pBuf++)) + return true; + + (*pnJPEGsize)++; + } + + return false; +} + +bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize, + int dwJPEGLineLength, int dwVideoLineLength, int dwVideoHeight, + void *pJPEG, int *pdwJPEGSize, + void *pVideo, int *pdwVideoSize) +{ + LOGV("===========SplitFrame Start=============="); + + if (NULL == pFrame || 0 >= dwSize) { + LOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize); + return false; + } + + if (0 == dwJPEGLineLength || 0 == dwVideoLineLength) { + LOGE("There in no input information for decoding interleaved jpeg"); + return false; + } + + unsigned char *pSrc = pFrame; + unsigned char *pSrcEnd = pFrame + dwSize; + + unsigned char *pJ = (unsigned char *)pJPEG; + int dwJSize = 0; + unsigned char *pV = (unsigned char *)pVideo; + int dwVSize = 0; + + bool bRet = false; + bool isFinishJpeg = false; + + while (pSrc < pSrcEnd) { + // Check video start marker + if (CheckVideoStartMarker(pSrc)) { + int copyLength; + + if (pSrc + dwVideoLineLength <= pSrcEnd) + copyLength = dwVideoLineLength; + else + copyLength = pSrcEnd - pSrc - VIDEO_COMMENT_MARKER_LENGTH; + + // Copy video data + if (pV) { + memcpy(pV, pSrc + VIDEO_COMMENT_MARKER_LENGTH, copyLength); + pV += copyLength; + dwVSize += copyLength; + } + + pSrc += copyLength + VIDEO_COMMENT_MARKER_LENGTH; + } else { + // Copy pure JPEG data + int size = 0; + int dwCopyBufLen = dwJPEGLineLength <= pSrcEnd-pSrc ? dwJPEGLineLength : pSrcEnd - pSrc; + + if (FindEOIMarkerInJPEG((unsigned char *)pSrc, dwCopyBufLen, &size)) { + isFinishJpeg = true; + size += 2; // to count EOF marker size + } else { + if ((dwCopyBufLen == 1) && (pJPEG < pJ)) { + unsigned char checkBuf[2] = { *(pJ - 1), *pSrc }; + + if (CheckEOIMarker(checkBuf)) + isFinishJpeg = true; + } + size = dwCopyBufLen; + } + + memcpy(pJ, pSrc, size); + + dwJSize += size; + + pJ += dwCopyBufLen; + pSrc += dwCopyBufLen; + } + if (isFinishJpeg) + break; + } + + if (isFinishJpeg) { + bRet = true; + if (pdwJPEGSize) + *pdwJPEGSize = dwJSize; + if (pdwVideoSize) + *pdwVideoSize = dwVSize; + } else { + LOGE("DecodeInterleaveJPEG_WithOutDT() => Can not find EOI"); + bRet = false; + if (pdwJPEGSize) + *pdwJPEGSize = 0; + if (pdwVideoSize) + *pdwVideoSize = 0; + } + LOGV("===========SplitFrame end=============="); + + return bRet; +} + +int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData) +{ + if (pInterleaveData == NULL) + return false; + + bool ret = true; + unsigned int *interleave_ptr = (unsigned int *)pInterleaveData; + unsigned char *jpeg_ptr = (unsigned char *)pJpegData; + unsigned char *yuv_ptr = (unsigned char *)pYuvData; + unsigned char *p; + int jpeg_size = 0; + int yuv_size = 0; + + int i = 0; + + LOGV("decodeInterleaveData Start~~~"); + while (i < interleaveDataSize) { + if ((*interleave_ptr == 0xFFFFFFFF) || (*interleave_ptr == 0x02FFFFFF) || + (*interleave_ptr == 0xFF02FFFF)) { + // Padding Data + interleave_ptr++; + i += 4; + } else if ((*interleave_ptr & 0xFFFF) == 0x05FF) { + // Start-code of YUV Data + p = (unsigned char *)interleave_ptr; + p += 2; + i += 2; + + // Extract YUV Data + if (pYuvData != NULL) { + memcpy(yuv_ptr, p, yuvWidth * 2); + yuv_ptr += yuvWidth * 2; + yuv_size += yuvWidth * 2; + } + p += yuvWidth * 2; + i += yuvWidth * 2; + + // Check End-code of YUV Data + if ((*p == 0xFF) && (*(p + 1) == 0x06)) { + interleave_ptr = (unsigned int *)(p + 2); + i += 2; + } else { + ret = false; + break; + } + } else { + // Extract JPEG Data + if (pJpegData != NULL) { + memcpy(jpeg_ptr, interleave_ptr, 4); + jpeg_ptr += 4; + jpeg_size += 4; + } + interleave_ptr++; + i += 4; + } + } + if (ret) { + if (pJpegData != NULL) { + // Remove Padding after EOI + for (i = 0; i < 3; i++) { + if (*(--jpeg_ptr) != 0xFF) { + break; + } + jpeg_size--; + } + *pJpegSize = jpeg_size; + + } + // Check YUV Data Size + if (pYuvData != NULL) { + if (yuv_size != (yuvWidth * yuvHeight * 2)) { + ret = false; + } + } + } + LOGV("decodeInterleaveData End~~~"); + return ret; +} + +status_t CameraHardwareSec::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + const Vector args; + + if (mSecCamera != 0) { + mSecCamera->dump(fd); + mParameters.dump(fd, args); + mInternalParameters.dump(fd, args); + snprintf(buffer, 255, " preview running(%s)\n", mPreviewRunning?"true": "false"); + result.append(buffer); + } else + result.append("No camera client yet.\n"); + write(fd, result.string(), result.size()); + return NO_ERROR; +} + +bool CameraHardwareSec::isSupportedPreviewSize(const int width, + const int height) const +{ + unsigned int i; + + for (i = 0; i < mSupportedPreviewSizes.size(); i++) { + if (mSupportedPreviewSizes[i].width == width && + mSupportedPreviewSizes[i].height == height) + return true; + } + + return false; +} + +status_t CameraHardwareSec::setParameters(const CameraParameters& params) +{ + LOGV("%s :", __func__); +#ifndef GAIA_FW_BETA + int Internal_is = !strncmp((const char*)mSecCamera->getCameraSensorName(), "ISP Camera", 10); +#else + int Internal_is = 0; +#endif + status_t ret = NO_ERROR; + + /* if someone calls us while picture thread is running, it could screw + * up the sensor quite a bit so return error. we can't wait because + * that would cause deadlock with the callbacks + */ + mStateLock.lock(); + if (mCaptureInProgress) { + mStateLock.unlock(); + LOGE("%s : capture in progress, not allowed", __func__); + return UNKNOWN_ERROR; + } + mStateLock.unlock(); + + // preview size +#ifdef GAIA_FW_BETA + int new_preview_width = 1920; + int new_preview_height = 1080; +#else + int new_preview_width = 0; + int new_preview_height = 0; + params.getPreviewSize(&new_preview_width, &new_preview_height); +#endif + const char *new_str_preview_format = params.getPreviewFormat(); + LOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s", + __func__, new_preview_width, new_preview_height, new_str_preview_format); + + if (0 < new_preview_width && 0 < new_preview_height && + new_str_preview_format != NULL && + isSupportedPreviewSize(new_preview_width, new_preview_height)) { + int new_preview_format = 0; + + mFrameSizeDelta = 16; + if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_RGB565)) { + new_preview_format = V4L2_PIX_FMT_RGB565; + mFrameSizeDelta = 0; + } + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_RGBA8888)) { + new_preview_format = V4L2_PIX_FMT_RGB32; + mFrameSizeDelta = 0; + } + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420SP)) + new_preview_format = V4L2_PIX_FMT_NV21; + else if (!strcmp(new_str_preview_format, + CameraParameters::PIXEL_FORMAT_YUV420P)) + new_preview_format = V4L2_PIX_FMT_YVU420M; + + else if (!strcmp(new_str_preview_format, "yuv420sp_custom")) + new_preview_format = V4L2_PIX_FMT_NV12T; + else if (!strcmp(new_str_preview_format, "yuv422i")) + new_preview_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_preview_format, "yuv422p")) + new_preview_format = V4L2_PIX_FMT_YUV422P; + else + new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party + + int current_preview_width, current_preview_height, current_frame_size; + mSecCamera->getPreviewSize(¤t_preview_width, + ¤t_preview_height, + ¤t_frame_size); + int current_pixel_format = mSecCamera->getPreviewPixelFormat(); + + if (current_preview_width != new_preview_width || + current_preview_height != new_preview_height || + current_pixel_format != new_preview_format) { + if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height, + new_preview_format) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))", + __func__, new_preview_width, new_preview_height, new_preview_format); + ret = UNKNOWN_ERROR; + } else { + if (mPreviewWindow) { + if (mPreviewRunning && !mPreviewStartDeferred) { + LOGE("ERR(%s): preview is running, cannot change size and format!", + __func__); + ret = INVALID_OPERATION; + } + + LOGV("%s: mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow); + LOGV("%s: mPreviewWindow->set_buffers_geometry (%p)", __func__, + mPreviewWindow->set_buffers_geometry); + mPreviewWindow->set_buffers_geometry(mPreviewWindow, + new_preview_width, new_preview_height, + new_preview_format); + LOGV("%s: DONE mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow); + } + mParameters.setPreviewSize(new_preview_width, new_preview_height); + mParameters.setPreviewFormat(new_str_preview_format); + } + } + else LOGV("%s: preview size and format has not changed", __func__); + } else { + LOGE("%s: Invalid preview size(%dx%d)", + __func__, new_preview_width, new_preview_height); + + ret = INVALID_OPERATION; + } + +#ifndef GAIA_FW_BETA + int new_picture_width = 0; + int new_picture_height = 0; + + params.getPictureSize(&new_picture_width, &new_picture_height); + LOGV("%s : new_picture_width x new_picture_height = %dx%d", __func__, new_picture_width, new_picture_height); + if (0 < new_picture_width && 0 < new_picture_height) { + LOGV("%s: setSnapshotSize", __func__); + if (mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))", + __func__, new_picture_width, new_picture_height); + ret = UNKNOWN_ERROR; + } else + mParameters.setPictureSize(new_picture_width, new_picture_height); + } + + // picture format + const char *new_str_picture_format = params.getPictureFormat(); + LOGV("%s : new_str_picture_format %s", __func__, new_str_picture_format); + if (new_str_picture_format != NULL) { + int new_picture_format = 0; + + if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGB565)) + new_picture_format = V4L2_PIX_FMT_RGB565; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGBA8888)) + new_picture_format = V4L2_PIX_FMT_RGB32; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_YUV420SP)) + new_picture_format = V4L2_PIX_FMT_NV21; + else if (!strcmp(new_str_picture_format, "yuv420sp_custom")) + new_picture_format = V4L2_PIX_FMT_NV12T; + else if (!strcmp(new_str_picture_format, "yuv420p")) + new_picture_format = V4L2_PIX_FMT_YUV420; + else if (!strcmp(new_str_picture_format, "yuv422i")) + new_picture_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_picture_format, "uyv422i_custom")) //Zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (!strcmp(new_str_picture_format, "uyv422i")) //Non-zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_JPEG)) + new_picture_format = V4L2_PIX_FMT_YUYV; + else if (!strcmp(new_str_picture_format, "yuv422p")) + new_picture_format = V4L2_PIX_FMT_YUV422P; + else + new_picture_format = V4L2_PIX_FMT_NV21; //for 3rd party + + if (mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __func__, new_picture_format); + ret = UNKNOWN_ERROR; + } else + mParameters.setPictureFormat(new_str_picture_format); + } + + // JPEG image quality + int new_jpeg_quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY); + LOGV("%s : new_jpeg_quality %d", __func__, new_jpeg_quality); + /* we ignore bad values */ + if (new_jpeg_quality >=1 && new_jpeg_quality <= 100) { + if (mSecCamera->setJpegQuality(new_jpeg_quality) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegQuality(quality(%d))", __func__, new_jpeg_quality); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_JPEG_QUALITY, new_jpeg_quality); + } + + // JPEG thumbnail size + int new_jpeg_thumbnail_width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); + int new_jpeg_thumbnail_height= params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); + if (0 <= new_jpeg_thumbnail_width && 0 <= new_jpeg_thumbnail_height) { + if (mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __func__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, new_jpeg_thumbnail_width); + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, new_jpeg_thumbnail_height); + } + } + + // JPEG thumbnail quality + int new_jpeg_thumbnail_quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); + LOGV("%s : new_jpeg_thumbnail_quality %d", __func__, new_jpeg_thumbnail_quality); + /* we ignore bad values */ + if (new_jpeg_thumbnail_quality >=1 && new_jpeg_thumbnail_quality <= 100) { + if (mSecCamera->setJpegThumbnailQuality(new_jpeg_thumbnail_quality) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailQuality(quality(%d))", + __func__, new_jpeg_thumbnail_quality); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, new_jpeg_thumbnail_quality); + } + + // frame rate + int new_frame_rate = params.getPreviewFrameRate(); + /* ignore any fps request, we're determine fps automatically based + * on scene mode. don't return an error because it causes CTS failure. + */ + if (new_frame_rate != mParameters.getPreviewFrameRate()) { + if (mSecCamera->setFrameRate(new_frame_rate) < 0){ + LOGE("ERR(%s):Fail on mSecCamera->setFrameRate(%d)", __func__, new_frame_rate); + ret = UNKNOWN_ERROR; + } else { + mParameters.setPreviewFrameRate(new_frame_rate); + } + } + + // rotation + int new_rotation = params.getInt(CameraParameters::KEY_ROTATION); + LOGV("%s : new_rotation %d", __func__, new_rotation); + if (0 <= new_rotation) { + LOGV("%s : set orientation:%d", __func__, new_rotation); + if (mSecCamera->setExifOrientationInfo(new_rotation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_rotation); + ret = UNKNOWN_ERROR; + } else + mParameters.set(CameraParameters::KEY_ROTATION, new_rotation); + } + + // brightness + int new_brightness = params.getInt("brightness"); + int max_brightness = params.getInt("brightness-max"); + int min_brightness = params.getInt("brightness-min"); + LOGV("%s : new_brightness %d", __func__, new_brightness); + if ((min_brightness <= new_brightness) && + (max_brightness >= new_brightness)) { + if (mSecCamera->setBrightness(new_brightness) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_brightness); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("brightness", new_brightness); + } + } + + // saturation + int new_saturation = params.getInt("saturation"); + int max_saturation = params.getInt("saturation-max"); + int min_saturation = params.getInt("saturation-min"); + LOGV("%s : new_saturation %d", __func__, new_saturation); + if ((min_saturation <= new_saturation) && + (max_saturation >= new_saturation)) { + if (mSecCamera->setSaturation(new_saturation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSaturation(saturation(%d))", __func__, new_saturation); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("saturation", new_saturation); + } + } + + // sharpness + int new_sharpness = params.getInt("sharpness"); + int max_sharpness = params.getInt("sharpness-max"); + int min_sharpness = params.getInt("sharpness-min"); + LOGV("%s : new_sharpness %d", __func__, new_sharpness); + if ((min_sharpness <= new_sharpness) && + (max_sharpness >= new_sharpness)) { + if (mSecCamera->setSharpness(new_sharpness) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSharpness(sharpness(%d))", __func__, new_sharpness); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("sharpness", new_sharpness); + } + } + + // hue + int new_hue = params.getInt("hue"); + int max_hue = params.getInt("hue-max"); + int min_hue = params.getInt("hue-min"); + LOGV("%s : new_hue %d", __func__, new_hue); + if ((min_hue <= new_hue) && + (max_hue >= new_hue)) { + if (mSecCamera->setHue(new_hue) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setHue(hue(%d))", __func__, new_hue); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("hue", new_hue); + } + } + + // exposure + int new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); + int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); + int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); + LOGV("%s : new_exposure_compensation %d", __func__, new_exposure_compensation); + if ((min_exposure_compensation <= new_exposure_compensation) && + (max_exposure_compensation >= new_exposure_compensation)) { + if (mSecCamera->setExposure(new_exposure_compensation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExposure(exposure(%d))", __func__, new_exposure_compensation); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, new_exposure_compensation); + } + } + + // ISO + const char *new_iso_str = params.get("iso"); + LOGV("%s : new_iso_str %s", __func__, new_iso_str); + if (new_iso_str != NULL) { + int new_iso = -1; + + if (!strcmp(new_iso_str, "auto")) { + if (Internal_is) + new_iso = IS_ISO_AUTO; + else + new_iso = ISO_AUTO; + } else if (!strcmp(new_iso_str, "50")) { + if (Internal_is) + new_iso = IS_ISO_50; + else + new_iso = ISO_50; + } else if (!strcmp(new_iso_str, "100")) { + if (Internal_is) + new_iso = IS_ISO_100; + else + new_iso = ISO_100; + } else if (!strcmp(new_iso_str, "200")) { + if (Internal_is) + new_iso = IS_ISO_200; + else + new_iso = ISO_200; + } else if (!strcmp(new_iso_str, "400")) { + if (Internal_is) + new_iso = IS_ISO_400; + else + new_iso = ISO_400; + } else if (!strcmp(new_iso_str, "800")) { + if (Internal_is) + new_iso = IS_ISO_800; + else + new_iso = ISO_800; + } else if (!strcmp(new_iso_str, "1600")) { + if (Internal_is) + new_iso = IS_ISO_1600; + else + new_iso = ISO_1600; + } else { + LOGE("ERR(%s):Invalid iso value(%s)", __func__, new_iso_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_iso) { + if (mSecCamera->setISO(new_iso) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setISO(iso(%d))", __func__, new_iso); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("iso", new_iso_str); + } + } + } + + // whitebalance + const char *new_white_str = params.get(CameraParameters::KEY_WHITE_BALANCE); + LOGV("%s : new_white_str %s", __func__, new_white_str); + if (new_white_str != NULL) { + int new_white = -1; + + if (!strcmp(new_white_str, CameraParameters::WHITE_BALANCE_AUTO)) { + if (Internal_is) + new_white = IS_AWB_AUTO; + else + new_white = WHITE_BALANCE_AUTO; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_DAYLIGHT)) { + if (Internal_is) + new_white = IS_AWB_DAYLIGHT; + else + new_white = WHITE_BALANCE_SUNNY; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT)) { + if (Internal_is) + new_white = IS_AWB_CLOUDY; + else + new_white = WHITE_BALANCE_CLOUDY; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_FLUORESCENT)) { + if (Internal_is) + new_white = IS_AWB_FLUORESCENT; + else + new_white = WHITE_BALANCE_FLUORESCENT; + } else if (!strcmp(new_white_str, + CameraParameters::WHITE_BALANCE_INCANDESCENT)) { + if (Internal_is) + new_white = IS_AWB_TUNGSTEN; + else + new_white = WHITE_BALANCE_TUNGSTEN; + } else { + LOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); //twilight, shade, warm_flourescent + ret = UNKNOWN_ERROR; + } + + if (0 <= new_white) { + if (mSecCamera->setWhiteBalance(new_white) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str); + } + } + } + + // Metering + const char *new_metering_str = params.get("metering"); + LOGV("%s : new_metering_str %s", __func__, new_metering_str); + if (new_metering_str != NULL) { + int new_metering = -1; + + if (!strcmp(new_metering_str, "center")) { + if (Internal_is) + new_metering = IS_METERING_AVERAGE; + else + new_metering = METERING_CENTER; + } else if (!strcmp(new_metering_str, "spot")) { + if (Internal_is) + new_metering = IS_METERING_SPOT; + else + new_metering = METERING_SPOT; + } else if (!strcmp(new_metering_str, "matrix")) { + if (Internal_is) + new_metering = IS_METERING_MATRIX; + else + new_metering = METERING_MATRIX; + } else { + LOGE("ERR(%s):Invalid metering value(%s)", __func__, new_metering_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_metering) { + if (mSecCamera->setMetering(new_metering) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setMetering(metering(%d))", __func__, new_metering); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("metering", new_metering_str); + } + } + } + + // AFC + const char *new_antibanding_str = params.get(CameraParameters::KEY_ANTIBANDING); + LOGV("%s : new_antibanding_str %s", __func__, new_antibanding_str); + if (new_antibanding_str != NULL) { + int new_antibanding = -1; + + if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_AUTO)) { + if (Internal_is) + new_antibanding = IS_AFC_AUTO; + else + new_antibanding = ANTI_BANDING_AUTO; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_50HZ)) { + if (Internal_is) + new_antibanding = IS_AFC_MANUAL_50HZ; + else + new_antibanding = ANTI_BANDING_50HZ; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_60HZ)) { + if (Internal_is) + new_antibanding = IS_AFC_MANUAL_60HZ; + else + new_antibanding = ANTI_BANDING_60HZ; + } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_OFF)) { + if (Internal_is) + new_antibanding = IS_AFC_DISABLE; + else + new_antibanding = ANTI_BANDING_OFF; + } else { + LOGE("ERR(%s):Invalid antibanding value(%s)", __func__, new_antibanding_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_antibanding) { + if (mSecCamera->setAntiBanding(new_antibanding) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setAntiBanding(antibanding(%d))", __func__, new_antibanding); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_ANTIBANDING, new_antibanding_str); + } + } + } + + // scene mode + const char *new_scene_mode_str = params.get(CameraParameters::KEY_SCENE_MODE); + const char *current_scene_mode_str = mParameters.get(CameraParameters::KEY_SCENE_MODE); + + // fps range + int new_min_fps = 0; + int new_max_fps = 0; + int current_min_fps, current_max_fps; + params.getPreviewFpsRange(&new_min_fps, &new_max_fps); + mParameters.getPreviewFpsRange(¤t_min_fps, ¤t_max_fps); + /* our fps range is determined by the sensor, reject any request + * that isn't exactly what we're already at. + * but the check is performed when requesting only changing fps range + */ + if (new_scene_mode_str && current_scene_mode_str) { + if (!strcmp(new_scene_mode_str, current_scene_mode_str)) { + if ((new_min_fps != current_min_fps) || (new_max_fps != current_max_fps)) { + LOGW("%s : requested new_min_fps = %d, new_max_fps = %d not allowed", + __func__, new_min_fps, new_max_fps); + LOGE("%s : current_min_fps = %d, current_max_fps = %d", + __func__, current_min_fps, current_max_fps); + ret = UNKNOWN_ERROR; + } + } + } else { + /* Check basic validation if scene mode is different */ + if ((new_min_fps > new_max_fps) || + (new_min_fps < 0) || (new_max_fps < 0)) + ret = UNKNOWN_ERROR; + } + + if (new_scene_mode_str != NULL) { + int new_scene_mode = -1; + + const char *new_flash_mode_str = params.get(CameraParameters::KEY_FLASH_MODE); + const char *new_focus_mode_str; + + new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE); + // fps range is (15000,30000) by default. + mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)"); + mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, + "15000,30000"); + + if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) { + new_scene_mode = SCENE_MODE_NONE; + } else { + // defaults for non-auto scene modes + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) { + new_focus_mode_str = CameraParameters::FOCUS_MODE_AUTO; + } + new_flash_mode_str = CameraParameters::FLASH_MODE_OFF; + + if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_PORTRAIT)) { + new_scene_mode = SCENE_MODE_PORTRAIT; + new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_LANDSCAPE)) { + new_scene_mode = SCENE_MODE_LANDSCAPE; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_SPORTS)) { + new_scene_mode = SCENE_MODE_SPORTS; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_PARTY)) { + new_scene_mode = SCENE_MODE_PARTY_INDOOR; + new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO; + } else if ((!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_BEACH)) || + (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_SNOW))) { + new_scene_mode = SCENE_MODE_BEACH_SNOW; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_SUNSET)) { + new_scene_mode = SCENE_MODE_SUNSET; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_NIGHT)) { + new_scene_mode = SCENE_MODE_NIGHTSHOT; + mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(4000,30000)"); + mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, + "4000,30000"); + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_FIREWORKS)) { + new_scene_mode = SCENE_MODE_FIREWORKS; + } else if (!strcmp(new_scene_mode_str, + CameraParameters::SCENE_MODE_CANDLELIGHT)) { + new_scene_mode = SCENE_MODE_CANDLE_LIGHT; + } else { + LOGE("%s::unmatched scene_mode(%s)", + __func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto + ret = UNKNOWN_ERROR; + } + } + + // focus mode + if (new_focus_mode_str != NULL) { + int new_focus_mode = -1; + + if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_AUTO)) { + new_focus_mode = FOCUS_MODE_AUTO; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR); + } else if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_MACRO)) { + new_focus_mode = FOCUS_MODE_MACRO; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR); + } else if (!strcmp(new_focus_mode_str, + CameraParameters::FOCUS_MODE_INFINITY)) { + new_focus_mode = FOCUS_MODE_INFINITY; + mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, + BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR); + } else { + LOGE("%s::unmatched focus_mode(%s)", __func__, new_focus_mode_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_focus_mode) { + if (mSecCamera->setFocusMode(new_focus_mode) < 0) { + LOGE("%s::mSecCamera->setFocusMode(%d) fail", __func__, new_focus_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_FOCUS_MODE, new_focus_mode_str); + } + } + } + + // flash.. + if (new_flash_mode_str != NULL) { + int new_flash_mode = -1; + + if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_OFF)) + new_flash_mode = FLASH_MODE_OFF; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_AUTO)) + new_flash_mode = FLASH_MODE_AUTO; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_ON)) + new_flash_mode = FLASH_MODE_ON; + else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_TORCH)) + new_flash_mode = FLASH_MODE_TORCH; + else { + LOGE("%s::unmatched flash_mode(%s)", __func__, new_flash_mode_str); //red-eye + ret = UNKNOWN_ERROR; + } + if (0 <= new_flash_mode) { + if (mSecCamera->setFlashMode(new_flash_mode) < 0) { + LOGE("%s::mSecCamera->setFlashMode(%d) fail", __func__, new_flash_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_FLASH_MODE, new_flash_mode_str); + } + } + } + + // scene.. + if (0 <= new_scene_mode) { + if (mSecCamera->setSceneMode(new_scene_mode) < 0) { + LOGE("%s::mSecCamera->setSceneMode(%d) fail", __func__, new_scene_mode); + ret = UNKNOWN_ERROR; + } else { + mParameters.set(CameraParameters::KEY_SCENE_MODE, new_scene_mode_str); + } + } + } + + // image effect + const char *new_image_effect_str = params.get(CameraParameters::KEY_EFFECT); + if (new_image_effect_str != NULL) { + + int new_image_effect = -1; + + if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NONE)) { + if (Internal_is) + new_image_effect = IS_IMAGE_EFFECT_DISABLE; + else + new_image_effect = IMAGE_EFFECT_NONE; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_MONO)) { + if (Internal_is) + new_image_effect = IS_IMAGE_EFFECT_MONOCHROME; + else + new_image_effect = IMAGE_EFFECT_BNW; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_SEPIA)) { + if (Internal_is) + new_image_effect = IS_IMAGE_EFFECT_SEPIA; + else + new_image_effect = IMAGE_EFFECT_SEPIA; + } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_AQUA)) + new_image_effect = IMAGE_EFFECT_AQUA; + else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NEGATIVE)) { + if (Internal_is) + new_image_effect = IS_IMAGE_EFFECT_NEGATIVE_MONO; + else + LOGW("WARN(%s):Invalid effect value (%s)", __func__, new_image_effect_str); + } else { + //posterize, whiteboard, blackboard, solarize + LOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str); + ret = UNKNOWN_ERROR; + } + + if (new_image_effect >= 0) { + if (mSecCamera->setImageEffect(new_image_effect) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect); + ret = UNKNOWN_ERROR; + } else { + const char *old_image_effect_str = mParameters.get(CameraParameters::KEY_EFFECT); + + if (old_image_effect_str) { + if (strcmp(old_image_effect_str, new_image_effect_str)) { + setSkipFrame(EFFECT_SKIP_FRAME); + } + } + + mParameters.set(CameraParameters::KEY_EFFECT, new_image_effect_str); + } + } + } + + //contrast + const char *new_contrast_str = params.get("contrast"); + LOGV("%s : new_contrast_str %s", __func__, new_contrast_str); + if (new_contrast_str != NULL) { + int new_contrast = -1; + + if (!strcmp(new_contrast_str, "auto")) { + if (Internal_is) + new_contrast = IS_CONTRAST_AUTO; + else + LOGW("WARN(%s):Invalid contrast value (%s)", __func__, new_contrast_str); + } else if (!strcmp(new_contrast_str, "-2")) { + if (Internal_is) + new_contrast = IS_CONTRAST_MINUS_2; + else + new_contrast = CONTRAST_MINUS_2; + } else if (!strcmp(new_contrast_str, "-1")) { + if (Internal_is) + new_contrast = IS_CONTRAST_MINUS_1; + else + new_contrast = CONTRAST_MINUS_1; + } else if (!strcmp(new_contrast_str, "0")) { + if (Internal_is) + new_contrast = IS_CONTRAST_DEFAULT; + else + new_contrast = CONTRAST_DEFAULT; + } else if (!strcmp(new_contrast_str, "1")) { + if (Internal_is) + new_contrast = IS_CONTRAST_PLUS_1; + else + new_contrast = CONTRAST_PLUS_1; + } else if (!strcmp(new_contrast_str, "2")) { + if (Internal_is) + new_contrast = IS_CONTRAST_PLUS_2; + else + new_contrast = CONTRAST_PLUS_2; + } else { + LOGE("ERR(%s):Invalid contrast value(%s)", __func__, new_contrast_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_contrast) { + if (mSecCamera->setContrast(new_contrast) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setContrast(contrast(%d))", __func__, new_contrast); + ret = UNKNOWN_ERROR; + } else { + mParameters.set("contrast", new_contrast_str); + } + } + } + + //WDR + int new_wdr = params.getInt("wdr"); + LOGV("%s : new_wdr %d", __func__, new_wdr); + + if (0 <= new_wdr) { + if (mSecCamera->setWDR(new_wdr) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_wdr); + ret = UNKNOWN_ERROR; + } + } + + //anti shake + int new_anti_shake = mInternalParameters.getInt("anti-shake"); + + if (0 <= new_anti_shake) { + if (mSecCamera->setAntiShake(new_anti_shake) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_anti_shake); + ret = UNKNOWN_ERROR; + } + } + + // gps latitude + const char *new_gps_latitude_str = params.get(CameraParameters::KEY_GPS_LATITUDE); + if (mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __func__, new_gps_latitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_latitude_str) { + mParameters.set(CameraParameters::KEY_GPS_LATITUDE, new_gps_latitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_LATITUDE); + } + } + + // gps longitude + const char *new_gps_longitude_str = params.get(CameraParameters::KEY_GPS_LONGITUDE); + + if (mSecCamera->setGPSLongitude(new_gps_longitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __func__, new_gps_longitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_longitude_str) { + mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, new_gps_longitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE); + } + } + + // gps altitude + const char *new_gps_altitude_str = params.get(CameraParameters::KEY_GPS_ALTITUDE); + + if (mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) { + LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __func__, new_gps_altitude_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_altitude_str) { + mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, new_gps_altitude_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE); + } + } + + // gps timestamp + const char *new_gps_timestamp_str = params.get(CameraParameters::KEY_GPS_TIMESTAMP); + + if (mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) { + LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __func__, new_gps_timestamp_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_timestamp_str) { + mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, new_gps_timestamp_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP); + } + } + + // gps processing method + const char *new_gps_processing_method_str = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD); + + if (mSecCamera->setGPSProcessingMethod(new_gps_processing_method_str) < 0) { + LOGE("%s::mSecCamera->setGPSProcessingMethod(%s) fail", __func__, new_gps_processing_method_str); + ret = UNKNOWN_ERROR; + } else { + if (new_gps_processing_method_str) { + mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, new_gps_processing_method_str); + } else { + mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD); + } + } + + // Recording size + int new_recording_width = 0; + int new_recording_height = 0; + params.getVideoSize(&new_recording_width, &new_recording_height); + LOGV("new_recording_width (%d) new_recording_height (%d)", + new_recording_width, new_recording_height); + + int current_recording_width, current_recording_height; + mSecCamera->getRecordingSize(¤t_recording_width, ¤t_recording_height); + LOGV("current_recording_width (%d) current_recording_height (%d)", + current_recording_width, current_recording_height); + + if (0 < new_recording_width && 0 < new_recording_height) { + if (current_recording_width != new_recording_width || + current_recording_height != new_recording_height) { + if (mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", + __func__, new_recording_width, new_recording_height); + ret = UNKNOWN_ERROR; + } else { + if (Internal_is && mPreviewWindow && mPreviewRunning) { + mSecCamera->setRecording(1); + stopPreview(); + startPreview(); + mSecCamera->setRecording(0); + } + } + } + mParameters.setVideoSize(new_recording_width, new_recording_height); + } else { + if (mSecCamera->setRecordingSize(new_preview_width, new_preview_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", + __func__, new_preview_width, new_preview_height); + ret = UNKNOWN_ERROR; + } + } + + //gamma + const char *new_gamma_str = mInternalParameters.get("video_recording_gamma"); + + if (new_gamma_str != NULL) { + int new_gamma = -1; + if (!strcmp(new_gamma_str, "off")) + new_gamma = GAMMA_OFF; + else if (!strcmp(new_gamma_str, "on")) + new_gamma = GAMMA_ON; + else { + LOGE("%s::unmatched gamma(%s)", __func__, new_gamma_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_gamma) { + if (mSecCamera->setGamma(new_gamma) < 0) { + LOGE("%s::mSecCamera->setGamma(%d) fail", __func__, new_gamma); + ret = UNKNOWN_ERROR; + } + } + } + + //slow ae + const char *new_slow_ae_str = mInternalParameters.get("slow_ae"); + + if (new_slow_ae_str != NULL) { + int new_slow_ae = -1; + + if (!strcmp(new_slow_ae_str, "off")) + new_slow_ae = SLOW_AE_OFF; + else if (!strcmp(new_slow_ae_str, "on")) + new_slow_ae = SLOW_AE_ON; + else { + LOGE("%s::unmatched slow_ae(%s)", __func__, new_slow_ae_str); + ret = UNKNOWN_ERROR; + } + + if (0 <= new_slow_ae) { + if (mSecCamera->setSlowAE(new_slow_ae) < 0) { + LOGE("%s::mSecCamera->setSlowAE(%d) fail", __func__, new_slow_ae); + ret = UNKNOWN_ERROR; + } + } + } + + /*Camcorder fix fps*/ + int new_sensor_mode = mInternalParameters.getInt("cam_mode"); + + if (0 <= new_sensor_mode) { + if (mSecCamera->setSensorMode(new_sensor_mode) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __func__, new_sensor_mode); + ret = UNKNOWN_ERROR; + } + } else { + new_sensor_mode=0; + } + + /*Shot mode*/ + int new_shot_mode = mInternalParameters.getInt("shot_mode"); + + if (0 <= new_shot_mode) { + if (mSecCamera->setShotMode(new_shot_mode) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __func__, new_shot_mode); + ret = UNKNOWN_ERROR; + } + } else { + new_shot_mode=0; + } + + // chk_dataline + int new_dataline = mInternalParameters.getInt("chk_dataline"); + + if (0 <= new_dataline) { + if (mSecCamera->setDataLineCheck(new_dataline) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __func__, new_dataline); + ret = UNKNOWN_ERROR; + } + } + LOGV("%s return ret = %d", __func__, ret); +#endif + + return ret; +} + +CameraParameters CameraHardwareSec::getParameters() const +{ + LOGV("%s :", __func__); + return mParameters; +} + +status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2) +{ + return BAD_VALUE; +} + +void CameraHardwareSec::release() +{ + LOGV("%s", __func__); + + /* shut down any threads we have that might be running. do it here + * instead of the destructor. we're guaranteed to be on another thread + * than the ones below. if we used the destructor, since the threads + * have a reference to this object, we could wind up trying to wait + * for ourself to exit, which is a deadlock. + */ + if (mPreviewThread != NULL) { + /* this thread is normally already in it's threadLoop but blocked + * on the condition variable or running. signal it so it wakes + * up and can exit. + */ + mPreviewThread->requestExit(); + mExitPreviewThread = true; + mPreviewRunning = true; /* let it run so it can exit */ + mPreviewCondition.signal(); + mPreviewThread->requestExitAndWait(); + mPreviewThread.clear(); + } + if (mAutoFocusThread != NULL) { + /* this thread is normally already in it's threadLoop but blocked + * on the condition variable. signal it so it wakes up and can exit. + */ + mFocusLock.lock(); + mAutoFocusThread->requestExit(); + mExitAutoFocusThread = true; + mFocusCondition.signal(); + mFocusLock.unlock(); + mAutoFocusThread->requestExitAndWait(); + mAutoFocusThread.clear(); + } + if (mPictureThread != NULL) { + mPictureThread->requestExitAndWait(); + mPictureThread.clear(); + } + + if (mRawHeap) { + mRawHeap->release(mRawHeap); + mRawHeap = 0; + } + if (mPreviewHeap) { + mPreviewHeap->release(mPreviewHeap); + mPreviewHeap = 0; + } + for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) { + if (mRecordHeap[i]) { + mRecordHeap[i]->release(mRecordHeap[i]); + mRecordHeap[i] = 0; + } + } + + /* close after all the heaps are cleared since those + * could have dup'd our file descriptor. + */ + mSecCamera->DestroyCamera(); +} + +static CameraInfo sCameraInfo[] = { + { + CAMERA_FACING_BACK, + 0, /* orientation */ + }, + { + CAMERA_FACING_FRONT, + 0, /* orientation */ + } +}; + +status_t CameraHardwareSec::storeMetaDataInBuffers(bool enable) +{ + if (!enable) { + LOGE("Non-metadata buffer mode is not supported!"); + return INVALID_OPERATION; + } + return OK; +} + +/** Close this device */ + +static camera_device_t *g_cam_device; + +static int HAL_camera_device_close(struct hw_device_t* device) +{ + LOGI("%s", __func__); + if (device) { + camera_device_t *cam_device = (camera_device_t *)device; + delete static_cast(cam_device->priv); + free(cam_device); + g_cam_device = 0; + } + return 0; +} + +static inline CameraHardwareSec *obj(struct camera_device *dev) +{ + return reinterpret_cast(dev->priv); +} + +/** Set the preview_stream_ops to which preview frames are sent */ +static int HAL_camera_device_set_preview_window(struct camera_device *dev, + struct preview_stream_ops *buf) +{ + LOGV("%s", __func__); + return obj(dev)->setPreviewWindow(buf); +} + +/** Set the notification and data callbacks */ +static void HAL_camera_device_set_callbacks(struct camera_device *dev, + camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void* user) +{ + LOGV("%s", __func__); + obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp, + get_memory, + user); +} + +/** + * The following three functions all take a msg_type, which is a bitmask of + * the messages defined in include/ui/Camera.h + */ + +/** + * Enable a message, or set of messages. + */ +static void HAL_camera_device_enable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + obj(dev)->enableMsgType(msg_type); +} + +/** + * Disable a message, or a set of messages. + * + * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera + * HAL should not rely on its client to call releaseRecordingFrame() to + * release video recording frames sent out by the cameral HAL before and + * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL + * clients must not modify/access any video recording frame after calling + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). + */ +static void HAL_camera_device_disable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + obj(dev)->disableMsgType(msg_type); +} + +/** + * Query whether a message, or a set of messages, is enabled. Note that + * this is operates as an AND, if any of the messages queried are off, this + * will return false. + */ +static int HAL_camera_device_msg_type_enabled(struct camera_device *dev, int32_t msg_type) +{ + LOGV("%s", __func__); + return obj(dev)->msgTypeEnabled(msg_type); +} + +/** + * Start preview mode. + */ +static int HAL_camera_device_start_preview(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->startPreview(); +} + +/** + * Stop a previously started preview. + */ +static void HAL_camera_device_stop_preview(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->stopPreview(); +} + +/** + * Returns true if preview is enabled. + */ +static int HAL_camera_device_preview_enabled(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->previewEnabled(); +} + +/** + * Request the camera HAL to store meta data or real YUV data in the video + * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If + * it is not called, the default camera HAL behavior is to store real YUV + * data in the video buffers. + * + * This method should be called before startRecording() in order to be + * effective. + * + * If meta data is stored in the video buffers, it is up to the receiver of + * the video buffers to interpret the contents and to find the actual frame + * data with the help of the meta data in the buffer. How this is done is + * outside of the scope of this method. + * + * Some camera HALs may not support storing meta data in the video buffers, + * but all camera HALs should support storing real YUV data in the video + * buffers. If the camera HAL does not support storing the meta data in the + * video buffers when it is requested to do do, INVALID_OPERATION must be + * returned. It is very useful for the camera HAL to pass meta data rather + * than the actual frame data directly to the video encoder, since the + * amount of the uncompressed frame data can be very large if video size is + * large. + * + * @param enable if true to instruct the camera HAL to store + * meta data in the video buffers; false to instruct + * the camera HAL to store real YUV data in the video + * buffers. + * + * @return OK on success. + */ +static int HAL_camera_device_store_meta_data_in_buffers(struct camera_device *dev, int enable) +{ + LOGV("%s", __func__); + return obj(dev)->storeMetaDataInBuffers(enable); +} + +/** + * Start record mode. When a record image is available, a + * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding + * frame. Every record frame must be released by a camera HAL client via + * releaseRecordingFrame() before the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames, + * and the client must not modify/access any video recording frames. + */ +static int HAL_camera_device_start_recording(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->startRecording(); +} + +/** + * Stop a previously started recording. + */ +static void HAL_camera_device_stop_recording(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->stopRecording(); +} + +/** + * Returns true if recording is enabled. + */ +static int HAL_camera_device_recording_enabled(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->recordingEnabled(); +} + +/** + * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. + * + * It is camera HAL client's responsibility to release video recording + * frames sent out by the camera HAL before the camera HAL receives a call + * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames. + */ +static void HAL_camera_device_release_recording_frame(struct camera_device *dev, + const void *opaque) +{ + LOGV("%s", __func__); + obj(dev)->releaseRecordingFrame(opaque); +} + +/** + * Start auto focus, the notification callback routine is called with + * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be + * called again if another auto focus is needed. + */ +static int HAL_camera_device_auto_focus(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->autoFocus(); +} + +/** + * Cancels auto-focus function. If the auto-focus is still in progress, + * this function will cancel it. Whether the auto-focus is in progress or + * not, this function will return the focus position to the default. If + * the camera does not support auto-focus, this is a no-op. + */ +static int HAL_camera_device_cancel_auto_focus(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->cancelAutoFocus(); +} + +/** + * Take a picture. + */ +static int HAL_camera_device_take_picture(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->takePicture(); +} + +/** + * Cancel a picture that was started with takePicture. Calling this method + * when no picture is being taken is a no-op. + */ +static int HAL_camera_device_cancel_picture(struct camera_device *dev) +{ + LOGV("%s", __func__); + return obj(dev)->cancelPicture(); +} + +/** + * Set the camera parameters. This returns BAD_VALUE if any parameter is + * invalid or not supported. + */ +static int HAL_camera_device_set_parameters(struct camera_device *dev, + const char *parms) +{ + LOGV("%s", __func__); + String8 str(parms); + CameraParameters p(str); + return obj(dev)->setParameters(p); +} + +/** Return the camera parameters. */ +char *HAL_camera_device_get_parameters(struct camera_device *dev) +{ + LOGV("%s", __func__); + String8 str; + CameraParameters parms = obj(dev)->getParameters(); + str = parms.flatten(); + return strdup(str.string()); +} + +static void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms) +{ + LOGV("%s", __func__); + free(parms); +} + +/** + * Send command to camera driver. + */ +static int HAL_camera_device_send_command(struct camera_device *dev, + int32_t cmd, int32_t arg1, int32_t arg2) +{ + LOGV("%s", __func__); + return obj(dev)->sendCommand(cmd, arg1, arg2); +} + +/** + * Release the hardware resources owned by this object. Note that this is + * *not* done in the destructor. + */ +static void HAL_camera_device_release(struct camera_device *dev) +{ + LOGV("%s", __func__); + obj(dev)->release(); +} + +/** + * Dump state of the camera hardware + */ +static int HAL_camera_device_dump(struct camera_device *dev, int fd) +{ + LOGV("%s", __func__); + return obj(dev)->dump(fd); +} + +static int HAL_getNumberOfCameras() +{ + LOGV("%s", __func__); + return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]); +} + +static int HAL_getCameraInfo(int cameraId, struct camera_info *cameraInfo) +{ + LOGV("%s", __func__); + memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo)); + return 0; +} + +#define SET_METHOD(m) m : HAL_camera_device_##m + +static camera_device_ops_t camera_device_ops = { + SET_METHOD(set_preview_window), + SET_METHOD(set_callbacks), + SET_METHOD(enable_msg_type), + SET_METHOD(disable_msg_type), + SET_METHOD(msg_type_enabled), + SET_METHOD(start_preview), + SET_METHOD(stop_preview), + SET_METHOD(preview_enabled), + SET_METHOD(store_meta_data_in_buffers), + SET_METHOD(start_recording), + SET_METHOD(stop_recording), + SET_METHOD(recording_enabled), + SET_METHOD(release_recording_frame), + SET_METHOD(auto_focus), + SET_METHOD(cancel_auto_focus), + SET_METHOD(take_picture), + SET_METHOD(cancel_picture), + SET_METHOD(set_parameters), + SET_METHOD(get_parameters), + SET_METHOD(put_parameters), + SET_METHOD(send_command), + SET_METHOD(release), + SET_METHOD(dump), +}; + +#undef SET_METHOD + +static int HAL_camera_device_open(const struct hw_module_t* module, + const char *id, + struct hw_device_t** device) +{ + LOGV("%s", __func__); + + int cameraId = atoi(id); + if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) { + LOGE("Invalid camera ID %s", id); + return -EINVAL; + } + + if (g_cam_device) { + if (obj(g_cam_device)->getCameraId() == cameraId) { + LOGV("returning existing camera ID %s", id); + goto done; + } else { + LOGE("Cannot open camera %d. camera %d is already running!", + cameraId, obj(g_cam_device)->getCameraId()); + return -ENOSYS; + } + } + + g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t)); + if (!g_cam_device) + return -ENOMEM; + + g_cam_device->common.tag = HARDWARE_DEVICE_TAG; + g_cam_device->common.version = 1; + g_cam_device->common.module = const_cast(module); + g_cam_device->common.close = HAL_camera_device_close; + + g_cam_device->ops = &camera_device_ops; + + LOGI("%s: open camera %s", __func__, id); + + g_cam_device->priv = new CameraHardwareSec(cameraId, g_cam_device); + +done: + *device = (hw_device_t *)g_cam_device; + LOGI("%s: opened camera %s (%p)", __func__, id, *device); + return 0; +} + +static hw_module_methods_t camera_module_methods = { + open : HAL_camera_device_open +}; + +extern "C" { + struct camera_module HAL_MODULE_INFO_SYM = { + common : { + tag : HARDWARE_MODULE_TAG, + version_major : 1, + version_minor : 0, + id : CAMERA_HARDWARE_MODULE_ID, + name : "orion camera HAL", + author : "Samsung Corporation", + methods : &camera_module_methods, + }, + get_number_of_cameras : HAL_getNumberOfCameras, + get_camera_info : HAL_getCameraInfo + }; +} + +}; // namespace android diff --git a/exynos5/hal/libcamera/SecCameraHWInterface.h b/exynos5/hal/libcamera/SecCameraHWInterface.h new file mode 100644 index 0000000..6be8ae2 --- /dev/null +++ b/exynos5/hal/libcamera/SecCameraHWInterface.h @@ -0,0 +1,219 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H + +#include "SecCamera.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gralloc_priv.h" + +#define BUFFER_COUNT_FOR_GRALLOC (MAX_BUFFERS + 4) +#define BUFFER_COUNT_FOR_ARRAY (MAX_BUFFERS) + +namespace android { + class CameraHardwareSec : public virtual RefBase { +public: + virtual void setCallbacks(camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user); + + virtual void enableMsgType(int32_t msgType); + virtual void disableMsgType(int32_t msgType); + virtual bool msgTypeEnabled(int32_t msgType); + + virtual status_t startPreview(); + virtual void stopPreview(); + virtual bool previewEnabled(); + + virtual status_t startRecording(); + virtual void stopRecording(); + virtual bool recordingEnabled(); + virtual void releaseRecordingFrame(const void *opaque); + + virtual status_t autoFocus(); + virtual status_t cancelAutoFocus(); + virtual status_t takePicture(); + virtual status_t cancelPicture(); + virtual status_t dump(int fd) const; + virtual status_t setParameters(const CameraParameters& params); + virtual CameraParameters getParameters() const; + virtual status_t sendCommand(int32_t command, int32_t arg1, int32_t arg2); + virtual status_t setPreviewWindow(preview_stream_ops *w); + virtual status_t storeMetaDataInBuffers(bool enable); + virtual void release(); + + inline int getCameraId() const; + + CameraHardwareSec(int cameraId, camera_device_t *dev); + virtual ~CameraHardwareSec(); +private: + status_t startPreviewInternal(); + void stopPreviewInternal(); + + class PreviewThread : public Thread { + CameraHardwareSec *mHardware; + public: + PreviewThread(CameraHardwareSec *hw): + Thread(false), + mHardware(hw) { } + virtual void onFirstRef() { + run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + mHardware->previewThreadWrapper(); + return false; + } + }; + + class PictureThread : public Thread { + CameraHardwareSec *mHardware; + public: + PictureThread(CameraHardwareSec *hw): + Thread(false), + mHardware(hw) { } + virtual bool threadLoop() { + mHardware->pictureThread(); + mHardware->mSecCamera->endSnapshot(); + return false; + } + }; + + class AutoFocusThread : public Thread { + CameraHardwareSec *mHardware; + public: + AutoFocusThread(CameraHardwareSec *hw): Thread(false), mHardware(hw) { } + virtual void onFirstRef() { + run("CameraAutoFocusThread", PRIORITY_DEFAULT); + } + virtual bool threadLoop() { + mHardware->autoFocusThread(); + return true; + } + }; + + void initDefaultParameters(int cameraId); + void initHeapLocked(); + + sp mPreviewThread; + int previewThread(); + int previewThreadWrapper(); + + sp mAutoFocusThread; + int autoFocusThread(); + + sp mPictureThread; + int pictureThread(); + bool mCaptureInProgress; + + int save_jpeg(unsigned char *real_jpeg, int jpeg_size); + void save_postview(const char *fname, uint8_t *buf, + uint32_t size); + int decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData); + bool YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight); + bool scaleDownYuv422(char *srcBuf, uint32_t srcWidth, + uint32_t srcHight, char *dstBuf, + uint32_t dstWidth, uint32_t dstHight); + + bool CheckVideoStartMarker(unsigned char *pBuf); + bool CheckEOIMarker(unsigned char *pBuf); + bool FindEOIMarkerInJPEG(unsigned char *pBuf, + int dwBufSize, int *pnJPEGsize); + bool SplitFrame(unsigned char *pFrame, int dwSize, + int dwJPEGLineLength, int dwVideoLineLength, + int dwVideoHeight, void *pJPEG, + int *pdwJPEGSize, void *pVideo, + int *pdwVideoSize); + void setSkipFrame(int frame); + bool isSupportedPreviewSize(const int width, + const int height) const; + /* used by auto focus thread to block until it's told to run */ + mutable Mutex mFocusLock; + mutable Condition mFocusCondition; + bool mExitAutoFocusThread; + + /* used by preview thread to block until it's told to run */ + mutable Mutex mPreviewLock; + mutable Condition mPreviewCondition; + mutable Condition mPreviewStoppedCondition; + bool mPreviewRunning; + bool mPreviewStartDeferred; + bool mExitPreviewThread; + + preview_stream_ops *mPreviewWindow; + + /* used to guard threading state */ + mutable Mutex mStateLock; + + CameraParameters mParameters; + CameraParameters mInternalParameters; + + int mFrameSizeDelta; + camera_memory_t *mPreviewHeap; + camera_memory_t *mRawHeap; + camera_memory_t *mRecordHeap[BUFFER_COUNT_FOR_ARRAY]; + + buffer_handle_t *mBufferHandle[BUFFER_COUNT_FOR_ARRAY]; + int mStride[BUFFER_COUNT_FOR_ARRAY]; + + + SecCamera *mSecCamera; + const __u8 *mCameraSensorName; + + mutable Mutex mSkipFrameLock; + int mSkipFrame; + + camera_notify_callback mNotifyCb; + camera_data_callback mDataCb; + camera_data_timestamp_callback mDataCbTimestamp; + camera_request_memory mGetMemoryCb; + void *mCallbackCookie; + + int32_t mMsgEnabled; + + bool mRecordRunning; + mutable Mutex mRecordLock; + int mPostViewWidth; + int mPostViewHeight; + int mPostViewSize; + + Vector mSupportedPreviewSizes; + + camera_device_t *mHalDevice; + static gralloc_module_t const* mGrallocHal; +}; + +}; // namespace android + +#endif diff --git a/exynos5/hal/libcamera/mediactl.cpp b/exynos5/hal/libcamera/mediactl.cpp new file mode 100644 index 0000000..468acc4 --- /dev/null +++ b/exynos5/hal/libcamera/mediactl.cpp @@ -0,0 +1,668 @@ +/* + * Media controller interface library + * + * Copyright (C) 2010-2011 Ideas on board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +//#include "config.h" +#define LOG_NDEBUG 0 +#define LOG_TAG "Mediactl" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mediactl.h" + +#define KF_MSG 0x1 +#define KF_ANY 0x2 + +#define perror_exit(cond, func) \ + if (cond) { \ + fprintf(stderr, "[%s:%d]: ", __func__, __LINE__);\ + perror(func);\ + exit(EXIT_FAILURE);\ + } + +struct media_pad *media_entity_remote_source(struct media_pad *pad) +{ + unsigned int i; + + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + return NULL; + + for (i = 0; i < pad->entity->num_links; ++i) { + struct media_link *link = &pad->entity->links[i]; + + if (!(link->flags & MEDIA_LNK_FL_ENABLED)) + continue; + + if (link->sink == pad) + return link->source; + } + + return NULL; +} + +struct media_entity *media_get_entity_by_name(struct media_device *media, + const char *name, size_t length) +{ + unsigned int i; + struct media_entity *entity; + entity = (struct media_entity*)calloc(1, sizeof(struct media_entity)); + for (i = 0; i < media->entities_count; ++i) { + entity = &media->entities[i]; + + if (strncmp(entity->info.name, name, length) == 0) + return entity; + } + + return NULL; +} + +struct media_entity *media_get_entity_by_id(struct media_device *media, + __u32 id) +{ + unsigned int i; + + for (i = 0; i < media->entities_count; ++i) { + struct media_entity *entity = &media->entities[i]; + + if (entity->info.id == id) + return entity; + } + + return NULL; +} + +int media_setup_link(struct media_device *media, + struct media_pad *source, + struct media_pad *sink, + __u32 flags) +{ + struct media_link *link; + struct media_link_desc ulink; + unsigned int i; + int ret; + + for (i = 0; i < source->entity->num_links; i++) { + link = &source->entity->links[i]; + + if (link->source->entity == source->entity && + link->source->index == source->index && + link->sink->entity == sink->entity && + link->sink->index == sink->index) + break; + } + + if (i == source->entity->num_links) { + LOGE("%s: Link not found", __func__); + return -ENOENT; + } + + /* source pad */ + ulink.source.entity = source->entity->info.id; + ulink.source.index = source->index; + ulink.source.flags = MEDIA_PAD_FL_SOURCE; + + /* sink pad */ + ulink.sink.entity = sink->entity->info.id; + ulink.sink.index = sink->index; + ulink.sink.flags = MEDIA_PAD_FL_SINK; + + ulink.flags = flags | (link->flags & MEDIA_LNK_FL_IMMUTABLE); + + ret = ioctl(media->fd, MEDIA_IOC_SETUP_LINK, &ulink); + if (ret == -1) { + LOGE("%s: Unable to setup link (%s)", + __func__, strerror(errno)); + return -errno; + } + + link->flags = ulink.flags; + link->twin->flags = ulink.flags; + return 0; +} + +int media_reset_links(struct media_device *media) +{ + unsigned int i, j; + int ret; + + for (i = 0; i < media->entities_count; ++i) { + struct media_entity *entity = &media->entities[i]; + + for (j = 0; j < entity->num_links; j++) { + struct media_link *link = &entity->links[j]; + + if (link->flags & MEDIA_LNK_FL_IMMUTABLE || + link->source->entity != entity) + continue; + + ret = media_setup_link(media, link->source, link->sink, + link->flags & ~MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static struct media_link *media_entity_add_link(struct media_entity *entity) +{ + if (entity->num_links >= entity->max_links) { + struct media_link *links = entity->links; + unsigned int max_links = entity->max_links * 2; + unsigned int i; + + links = (struct media_link*)realloc(links, max_links * sizeof *links); + if (links == NULL) + return NULL; + + for (i = 0; i < entity->num_links; ++i) + links[i].twin->twin = &links[i]; + + entity->max_links = max_links; + entity->links = links; + } + + return &entity->links[entity->num_links++]; +} + +static int media_enum_links(struct media_device *media) +{ + LOGV("%s: start", __func__); + __u32 id; + int ret = 0; + + for (id = 1; id <= media->entities_count; id++) { + struct media_entity *entity = &media->entities[id - 1]; + struct media_links_enum links; + unsigned int i; + + links.entity = entity->info.id; + links.pads = (struct media_pad_desc*)malloc(entity->info.pads * sizeof(struct media_pad_desc)); + links.links = (struct media_link_desc*)malloc(entity->info.links * sizeof(struct media_link_desc)); + + if (ioctl(media->fd, MEDIA_IOC_ENUM_LINKS, &links) < 0) { + LOGE( + "%s: Unable to enumerate pads and links (%s).", + __func__, strerror(errno)); + free(links.pads); + free(links.links); + return -errno; + } + + for (i = 0; i < entity->info.pads; ++i) { + entity->pads[i].entity = entity; + entity->pads[i].index = links.pads[i].index; + entity->pads[i].flags = links.pads[i].flags; + } + + for (i = 0; i < entity->info.links; ++i) { + struct media_link_desc *link = &links.links[i]; + struct media_link *fwdlink; + struct media_link *backlink; + struct media_entity *source; + struct media_entity *sink; + + source = media_get_entity_by_id(media, link->source.entity); + sink = media_get_entity_by_id(media, link->sink.entity); + if (source == NULL || sink == NULL) { + LOGE( + "WARNING entity %u link %u from %u/%u to %u/%u is invalid!", + id, i, link->source.entity, + link->source.index, + link->sink.entity, + link->sink.index); + ret = -EINVAL; + } else { + fwdlink = media_entity_add_link(source); + fwdlink->source = &source->pads[link->source.index]; + fwdlink->sink = &sink->pads[link->sink.index]; + fwdlink->flags = link->flags; + + backlink = media_entity_add_link(sink); + backlink->source = &source->pads[link->source.index]; + backlink->sink = &sink->pads[link->sink.index]; + backlink->flags = link->flags; + + fwdlink->twin = backlink; + backlink->twin = fwdlink; + } + } + + free(links.pads); + free(links.links); + } + return ret; +} + +#ifdef HAVE_LIBUDEV + +#include + +static inline int media_udev_open(struct udev **udev) +{ + *udev = udev_new(); + if (*udev == NULL) + return -ENOMEM; + return 0; +} + +static inline void media_udev_close(struct udev *udev) +{ + if (udev != NULL) + udev_unref(udev); +} + +static int media_get_devname_udev(struct udev *udev, + struct media_entity *entity) +{ + struct udev_device *device; + dev_t devnum; + const char *p; + int ret = -ENODEV; + + if (udev == NULL) + return -EINVAL; + + devnum = makedev(entity->info.v4l.major, entity->info.v4l.minor); + LOGE("looking up device: %u:%u", + major(devnum), minor(devnum)); + device = udev_device_new_from_devnum(udev, 'c', devnum); + if (device) { + p = udev_device_get_devnode(device); + if (p) { + strncpy(entity->devname, p, sizeof(entity->devname)); + entity->devname[sizeof(entity->devname) - 1] = '\0'; + } + ret = 0; + } + + udev_device_unref(device); + + return ret; +} + +#else /* HAVE_LIBUDEV */ + +struct udev; + +static inline int media_udev_open(struct udev **udev) { return 0; } + +static inline void media_udev_close(struct udev *udev) { } + +static inline int media_get_devname_udev(struct udev *udev, + struct media_entity *entity) +{ + return -ENOTSUP; +} + +#endif /* HAVE_LIBUDEV */ + +static int media_get_devname_sysfs(struct media_entity *entity) +{ + //struct stat devstat; + char devname[32]; + char sysname[32]; + char target[1024]; + char *p; + int ret; + + sprintf(sysname, "/sys/dev/char/%u:%u", entity->info.v4l.major, + entity->info.v4l.minor); + + ret = readlink(sysname, target, sizeof(target)); + if (ret < 0) + return -errno; + + target[ret] = '\0'; + p = strrchr(target, '/'); + if (p == NULL) + return -EINVAL; + + sprintf(devname, "/tmp/%s", p + 1); + + ret = mknod(devname, 0666 | S_IFCHR, MKDEV(81, entity->info.v4l.minor)); + strcpy(entity->devname, devname); + + return 0; +} + +int get_media_fd(struct media_device *media) +{ + ssize_t num; + int media_node; + char *ptr; + char media_buf[6]; + + LOGV("%s(%s)", __func__, MEDIA_DEV); + + media->fd = open(MEDIA_DEV, O_RDWR, 0); + if( media->fd < 0) { + LOGE("Open sysfs media device failed, media->fd : 0x%p", media->fd); + return -1; + } + LOGV("media->fd : %p", media->fd); + + return media->fd; + +} + +static int media_enum_entities(struct media_device *media) +{ + struct media_entity *entity; + unsigned int size; + __u32 id; + int ret; + entity = (struct media_entity*)calloc(1, sizeof(struct media_entity)); + for (id = 0, ret = 0; ; id = entity->info.id) { + size = (media->entities_count + 1) * sizeof(*media->entities); + media->entities = (struct media_entity*)realloc(media->entities, size); + + entity = &media->entities[media->entities_count]; + memset(entity, 0, sizeof(*entity)); + entity->fd = -1; + entity->info.id = id | MEDIA_ENT_ID_FLAG_NEXT; + entity->media = media; + + ret = ioctl(media->fd, MEDIA_IOC_ENUM_ENTITIES, &entity->info); + + if (ret < 0) { + ret = errno != EINVAL ? -errno : 0; + break; + } + + /* Number of links (for outbound links) plus number of pads (for + * inbound links) is a good safe initial estimate of the total + * number of links. + */ + entity->max_links = entity->info.pads + entity->info.links; + + entity->pads = (struct media_pad*)malloc(entity->info.pads * sizeof(*entity->pads)); + entity->links = (struct media_link*)malloc(entity->max_links * sizeof(*entity->links)); + if (entity->pads == NULL || entity->links == NULL) { + ret = -ENOMEM; + break; + } + + media->entities_count++; + + /* Find the corresponding device name. */ + if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE && + media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) + continue; + + /* Fall back to get the device name via sysfs */ + media_get_devname_sysfs(entity); + if (ret < 0) + LOGE("media_get_devname failed"); + } + + return ret; +} + +static void media_debug_default(void *ptr, ...) +{ + va_list argptr; + va_start(argptr, ptr); + vprintf((const char*)ptr, argptr); + va_end(argptr); +} + +void media_debug_set_handler(struct media_device *media, + void (*debug_handler)(void *, ...), + void *debug_priv) +{ + if (debug_handler) { + media->debug_handler = debug_handler; + media->debug_priv = debug_priv; + } else { + media->debug_handler = media_debug_default; + media->debug_priv = NULL; + } +} + +struct media_device *media_open_debug( + const char *name, void (*debug_handler)(void *, ...), + void *debug_priv) +{ + struct media_device *media; + int ret; + + media = (struct media_device*)calloc(1, sizeof(struct media_device)); + if (media == NULL) { + LOGE("%s: media : %p", __func__, media); + return NULL; + } + + media_debug_set_handler(media, debug_handler, debug_priv); + + LOGV("Opening media device %s", name); + LOGV("%s: media : %p", __func__, media); + + media->fd = get_media_fd(media); + if (media->fd < 0) { + media_close(media); + LOGE("%s: failed get_media_fd %s", + __func__, name); + return NULL; + } + + LOGV("%s: media->fd : %p", __func__, media->fd); + ret = media_enum_entities(media); + + if (ret < 0) { + LOGE( + "%s: Unable to enumerate entities for device %s (%s)", + __func__, name, strerror(-ret)); + media_close(media); + return NULL; + } + + LOGV("Found %u entities", media->entities_count); + LOGV("Enumerating pads and links"); + + ret = media_enum_links(media); + if (ret < 0) { + LOGE( + "%s: Unable to enumerate pads and linksfor device %s", + __func__, name); + media_close(media); + return NULL; + } + + return media; +} + +struct media_device *media_open(void) +{ + return media_open_debug(NULL, (void (*)(void *, ...))fprintf, stdout); +} + +void media_close(struct media_device *media) +{ + unsigned int i; + + if (media->fd != -1) + close(media->fd); + + for (i = 0; i < media->entities_count; ++i) { + struct media_entity *entity = &media->entities[i]; + + free(entity->pads); + free(entity->links); + if (entity->fd != -1) + close(entity->fd); + } + + free(media->entities); + free(media); +} + +struct media_pad *media_parse_pad(struct media_device *media, + const char *p, char **endp) +{ + unsigned int entity_id, pad; + struct media_entity *entity; + char *end; + + for (; isspace(*p); ++p); + + if (*p == '"') { + for (end = (char *)p + 1; *end && *end != '"'; ++end); + if (*end != '"') + return NULL; + + entity = media_get_entity_by_name(media, p + 1, end - p - 1); + if (entity == NULL) + return NULL; + + ++end; + } else { + entity_id = strtoul(p, &end, 10); + entity = media_get_entity_by_id(media, entity_id); + if (entity == NULL) + return NULL; + } + for (; isspace(*end); ++end); + + if (*end != ':') + return NULL; + for (p = end + 1; isspace(*p); ++p); + + pad = strtoul(p, &end, 10); + for (p = end; isspace(*p); ++p); + + if (pad >= entity->info.pads) + return NULL; + + for (p = end; isspace(*p); ++p); + if (endp) + *endp = (char *)p; + + return &entity->pads[pad]; +} + +struct media_link *media_parse_link(struct media_device *media, + const char *p, char **endp) +{ + struct media_link *link; + struct media_pad *source; + struct media_pad *sink; + unsigned int i; + char *end; + + source = media_parse_pad(media, p, &end); + if (source == NULL) + return NULL; + + if (end[0] != '-' || end[1] != '>') + return NULL; + p = end + 2; + + sink = media_parse_pad(media, p, &end); + if (sink == NULL) + return NULL; + + *endp = end; + + for (i = 0; i < source->entity->num_links; i++) { + link = &source->entity->links[i]; + + if (link->source == source && link->sink == sink) + return link; + } + + return NULL; +} + +int media_parse_setup_link(struct media_device *media, + const char *p, char **endp) +{ + struct media_link *link; + __u32 flags; + char *end; + + link = media_parse_link(media, p, &end); + if (link == NULL) { + LOGE( + "%s: Unable to parse link", __func__); + return -EINVAL; + } + + p = end; + if (*p++ != '[') { + LOGE("Unable to parse link flags"); + return -EINVAL; + } + + flags = strtoul(p, &end, 10); + for (p = end; isspace(*p); p++); + if (*p++ != ']') { + LOGE("Unable to parse link flags"); + return -EINVAL; + } + + for (; isspace(*p); p++); + *endp = (char *)p; + + LOGV( + "Setting up link %u:%u -> %u:%u [%u]", + link->source->entity->info.id, link->source->index, + link->sink->entity->info.id, link->sink->index, + flags); + + return media_setup_link(media, link->source, link->sink, flags); +} + +int media_parse_setup_links(struct media_device *media, const char *p) +{ + char *end; + int ret; + + do { + ret = media_parse_setup_link(media, p, &end); + if (ret < 0) + return ret; + + p = end + 1; + } while (*end == ','); + + return *end ? -EINVAL : 0; +} diff --git a/exynos5/hal/libcamera/mediactl.h b/exynos5/hal/libcamera/mediactl.h new file mode 100644 index 0000000..f28ce16 --- /dev/null +++ b/exynos5/hal/libcamera/mediactl.h @@ -0,0 +1,270 @@ +/* + * Media controller interface library + * + * Copyright (C) 2010-2011 Ideas on board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef __MEDIA_H__ +#define __MEDIA_H__ + +#include + +#define GAIA_FW_BETA 1 + +#ifndef GAIA_FW_BETA +#define MEDIA_DEV "/dev/media1" //M5MO : External ISP +#else +#define MEDIA_DEV "/dev/media2" //4E5 : Internal ISP +#endif + +#define MEDIA_MINOR 0 + +#define KF_MSG 0x1 +#define KF_ANY 0x2 + +struct media_link { + struct media_pad *source; + struct media_pad *sink; + struct media_link *twin; + __u32 flags; + __u32 padding[3]; +}; + +struct media_pad { + struct media_entity *entity; + __u32 index; + __u32 flags; + __u32 padding[3]; +}; + +struct media_entity { + struct media_device *media; + struct media_entity_desc info; + struct media_pad *pads; + struct media_link *links; + unsigned int max_links; + unsigned int num_links; + + char devname[32]; + int fd; + __u32 padding[6]; +}; + +struct media_device { + int fd; + struct media_entity *entities; + unsigned int entities_count; + void (*debug_handler)(void *, ...); + void *debug_priv; + __u32 padding[6]; +}; + +#define media_dbg(media, ...) \ + (media)->debug_handler((media)->debug_priv, __VA_ARGS__) + +/** + * @brief Set a handler for debug messages. + * @param media - device instance. + * @param debug_handler - debug message handler + * @param debug_priv - first argument to debug message handler + * + * Set a handler for debug messages that will be called whenever + * debugging information is to be printed. The handler expects an + * fprintf-like function. + */ +void media_debug_set_handler( + struct media_device *media, void (*debug_handler)(void *, ...), + void *debug_priv); + +/** + * @brief Open a media device with debugging enabled. + * @param name - name (including path) of the device node. + * @param debug_handler - debug message handler + * @param debug_priv - first argument to debug message handler + * + * Open the media device referenced by @a name and enumerate entities, pads and + * links. + * + * Calling media_open_debug() instead of media_open() is equivalent to + * media_open() and media_debug_set_handler() except that debugging is + * also enabled during media_open(). + * + * @return A pointer to a newly allocated media_device structure instance on + * success and NULL on failure. The returned pointer must be freed with + * media_close when the device isn't needed anymore. + */ +struct media_device *media_open_debug( + const char *name, void (*debug_handler)(void *, ...), + void *debug_priv); + +/** + * @brief Open a media device. + * @param name - name (including path) of the device node. + * + * Open the media device referenced by @a name and enumerate entities, pads and + * links. + * + * @return A pointer to a newly allocated media_device structure instance on + * success and NULL on failure. The returned pointer must be freed with + * media_close when the device isn't needed anymore. + */ +struct media_device *media_open(void); + +/** + * @brief Close a media device. + * @param media - device instance. + * + * Close the @a media device instance and free allocated resources. Access to the + * device instance is forbidden after this function returns. + */ +void media_close(struct media_device *media); + +/** + * @brief Locate the pad at the other end of a link. + * @param pad - sink pad at one end of the link. + * + * Locate the source pad connected to @a pad through an enabled link. As only one + * link connected to a sink pad can be enabled at a time, the connected source + * pad is guaranteed to be unique. + * + * @return A pointer to the connected source pad, or NULL if all links connected + * to @a pad are disabled. Return NULL also if @a pad is not a sink pad. + */ +struct media_pad *media_entity_remote_source(struct media_pad *pad); + +/** + * @brief Get the type of an entity. + * @param entity - the entity. + * + * @return The type of @a entity. + */ +static inline unsigned int media_entity_type(struct media_entity *entity) +{ + return entity->info.type & MEDIA_ENT_TYPE_MASK; +} + +/** + * @brief Find an entity by its name. + * @param media - media device. + * @param name - entity name. + * @param length - size of @a name. + * + * Search for an entity with a name equal to @a name. + * + * @return A pointer to the entity if found, or NULL otherwise. + */ +struct media_entity *media_get_entity_by_name(struct media_device *media, + const char *name, size_t length); + +/** + * @brief Find an entity by its ID. + * @param media - media device. + * @param id - entity ID. + * + * Search for an entity with an ID equal to @a id. + * + * @return A pointer to the entity if found, or NULL otherwise. + */ +struct media_entity *media_get_entity_by_id(struct media_device *media, + __u32 id); + +/** + * @brief Configure a link. + * @param media - media device. + * @param source - source pad at the link origin. + * @param sink - sink pad at the link target. + * @param flags - configuration flags. + * + * Locate the link between @a source and @a sink, and configure it by applying + * the new @a flags. + * + * Only the MEDIA_LINK_FLAG_ENABLED flag is writable. + * + * @return 0 on success, -1 on failure: + * -ENOENT: link not found + * - other error codes returned by MEDIA_IOC_SETUP_LINK + */ +int media_setup_link(struct media_device *media, + struct media_pad *source, struct media_pad *sink, + __u32 flags); + +/** + * @brief Reset all links to the disabled state. + * @param media - media device. + * + * Disable all links in the media device. This function is usually used after + * opening a media device to reset all links to a known state. + * + * @return 0 on success, or a negative error code on failure. + */ +int media_reset_links(struct media_device *media); + +/** + * @brief Parse string to a pad on the media device. + * @param media - media device. + * @param p - input string + * @param endp - pointer to string where parsing ended + * + * Parse NULL terminated string describing a pad and return its struct + * media_pad instance. + * + * @return Pointer to struct media_pad on success, NULL on failure. + */ +struct media_pad *media_parse_pad(struct media_device *media, + const char *p, char **endp); + +/** + * @brief Parse string to a link on the media device. + * @param media - media device. + * @param p - input string + * @param endp - pointer to p where parsing ended + * + * Parse NULL terminated string p describing a link and return its struct + * media_link instance. + * + * @return Pointer to struct media_link on success, NULL on failure. + */ +struct media_link *media_parse_link(struct media_device *media, + const char *p, char **endp); + +/** + * @brief Parse string to a link on the media device and set it up. + * @param media - media device. + * @param p - input string + * + * Parse NULL terminated string p describing a link and its configuration + * and configure the link. + * + * @return 0 on success, or a negative error code on failure. + */ +int media_parse_setup_link(struct media_device *media, + const char *p, char **endp); + +/** + * @brief Parse string to link(s) on the media device and set it up. + * @param media - media device. + * @param p - input string + * + * Parse NULL terminated string p describing link(s) separated by + * commas (,) and configure the link(s). + * + * @return 0 on success, or a negative error code on failure. + */ +int media_parse_setup_links(struct media_device *media, const char *p); + +#endif diff --git a/exynos5/hal/libcamera/v4l2subdev.h b/exynos5/hal/libcamera/v4l2subdev.h new file mode 100644 index 0000000..20e0557 --- /dev/null +++ b/exynos5/hal/libcamera/v4l2subdev.h @@ -0,0 +1,200 @@ +/* + * V4L2 subdev interface library + * + * Copyright (C) 2010-2011 Ideas on board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef __SUBDEV_H__ +#define __SUBDEV_H__ + +#include + +struct media_entity; + +/** + * @brief Open a sub-device. + * @param entity - sub-device media entity. + * + * Open the V4L2 subdev device node associated with @a entity. The file + * descriptor is stored in the media_entity structure. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_open(struct media_entity *entity); + +/** + * @brief Close a sub-device. + * @param entity - sub-device media entity. + * + * Close the V4L2 subdev device node associated with the @a entity and opened by + * a previous call to v4l2_subdev_open() (either explicit or implicit). + */ +void v4l2_subdev_close(struct media_entity *entity); + +/** + * @brief Retrieve the format on a pad. + * @param entity - subdev-device media entity. + * @param format - format to be filled. + * @param pad - pad number. + * @param which - identifier of the format to get. + * + * Retrieve the current format on the @a entity @a pad and store it in the + * @a format structure. + * + * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try format stored + * in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the current + * active format. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_get_format(struct media_entity *entity, + struct v4l2_mbus_framefmt *format, unsigned int pad, + enum v4l2_subdev_format_whence which); + +/** + * @brief Set the format on a pad. + * @param entity - subdev-device media entity. + * @param format - format. + * @param pad - pad number. + * @param which - identifier of the format to set. + * + * Set the format on the @a entity @a pad to @a format. The driver is allowed to + * modify the requested format, in which case @a format is updated with the + * modifications. + * + * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try format stored in the + * file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the device with an + * active format. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_set_format(struct media_entity *entity, + struct v4l2_mbus_framefmt *format, unsigned int pad, + enum v4l2_subdev_format_whence which); + +/** + * @brief Retrieve the crop rectangle on a pad. + * @param entity - subdev-device media entity. + * @param rect - crop rectangle to be filled. + * @param pad - pad number. + * @param which - identifier of the format to get. + * + * Retrieve the current crop rectangleon the @a entity @a pad and store it in + * the @a rect structure. + * + * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try crop rectangle + * stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the + * current active crop rectangle. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect, + unsigned int pad, enum v4l2_subdev_format_whence which); + +/** + * @brief Set the crop rectangle on a pad. + * @param entity - subdev-device media entity. + * @param rect - crop rectangle. + * @param pad - pad number. + * @param which - identifier of the format to set. + * + * Set the crop rectangle on the @a entity @a pad to @a rect. The driver is + * allowed to modify the requested rectangle, in which case @a rect is updated + * with the modifications. + * + * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try crop rectangle + * stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the + * device with an active crop rectangle. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_set_crop(struct media_entity *entity, struct v4l2_rect *rect, + unsigned int pad, enum v4l2_subdev_format_whence which); + +/** + * @brief Retrieve the frame interval on a sub-device. + * @param entity - subdev-device media entity. + * @param interval - frame interval to be filled. + * + * Retrieve the current frame interval on subdev @a entity and store it in the + * @a interval structure. + * + * Frame interval retrieving is usually supported only on devices at the + * beginning of video pipelines, such as sensors. + * + * @return 0 on success, or a negative error code on failure. + */ + +int v4l2_subdev_get_frame_interval(struct media_entity *entity, + struct v4l2_fract *interval); + +/** + * @brief Set the frame interval on a sub-device. + * @param entity - subdev-device media entity. + * @param interval - frame interval. + * + * Set the frame interval on subdev @a entity to @a interval. The driver is + * allowed to modify the requested frame interval, in which case @a interval is + * updated with the modifications. + * + * Frame interval setting is usually supported only on devices at the beginning + * of video pipelines, such as sensors. + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_set_frame_interval(struct media_entity *entity, + struct v4l2_fract *interval); + +/** + * @brief Parse a string and apply format, crop and frame interval settings. + * @param media - media device. + * @param p - input string + * @param endp - pointer to string p where parsing ended (return) + * + * Parse string @a p and apply format, crop and frame interval settings to a + * subdev pad specified in @a p. @a endp will be written a pointer where + * parsing of @a p ended. + * + * Format strings are separeted by commas (,). + * + * @return 0 on success, or a negative error code on failure. + */ +int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p); + +/** + * @brief Convert media bus pixel code to string. + * @param code - input string + * + * Convert media bus pixel code @a code to a human-readable string. + * + * @return A pointer to a string on success, NULL on failure. + */ +const char *v4l2_subdev_pixelcode_to_string(enum v4l2_mbus_pixelcode code); + +/** + * @brief Parse string to media bus pixel code. + * @param string - input string + * @param lenght - length of the string + * + * Parse human readable string @a string to an media bus pixel code. + * + * @return media bus pixelcode on success, -1 on failure. + */ +enum v4l2_mbus_pixelcode v4l2_subdev_string_to_pixelcode(const char *string, + unsigned int length); +#endif diff --git a/exynos5/hal/libfimg4x/Android.mk b/exynos5/hal/libfimg4x/Android.mk new file mode 100644 index 0000000..d5d18e9 --- /dev/null +++ b/exynos5/hal/libfimg4x/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +ifeq ($(BOARD_USES_FIMGAPI),true) + +#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include +LOCAL_C_INCLUDES += external/skia/include/core +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES:= \ + FimgApi.cpp \ + FimgExynos5.cpp + +LOCAL_SHARED_LIBRARIES:= liblog libutils libbinder + +LOCAL_MODULE:= libfimg + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos5/hal/libfimg4x/FimgApi.cpp b/exynos5/hal/libfimg4x/FimgApi.cpp new file mode 100644 index 0000000..ff11b8d --- /dev/null +++ b/exynos5/hal/libfimg4x/FimgApi.cpp @@ -0,0 +1,376 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "SKIA" +#include + +#include "FimgApi.h" + +struct blit_op_table optbl[] = { + { (int)BLIT_OP_SOLID_FILL, "FILL" }, + { (int)BLIT_OP_CLR, "CLR" }, + { (int)BLIT_OP_SRC, "SRC" }, + { (int)BLIT_OP_DST, "DST" }, + { (int)BLIT_OP_SRC_OVER, "SRC_OVER" }, + { (int)BLIT_OP_DST_OVER, "DST_OVER" }, + { (int)BLIT_OP_SRC_IN, "SRC_IN" }, + { (int)BLIT_OP_DST_IN, "DST_IN" }, + { (int)BLIT_OP_SRC_OUT, "SRC_OUT" }, + { (int)BLIT_OP_DST_OUT, "DST_OUT" }, + { (int)BLIT_OP_SRC_ATOP, "SRC_ATOP" }, + { (int)BLIT_OP_DST_ATOP, "DST_ATOP" }, + { (int)BLIT_OP_XOR, "XOR" }, + { (int)BLIT_OP_ADD, "ADD" }, + { (int)BLIT_OP_MULTIPLY, "MULTIPLY" }, + { (int)BLIT_OP_SCREEN, "SCREEN" }, + { (int)BLIT_OP_DARKEN, "DARKEN" }, + { (int)BLIT_OP_LIGHTEN, "LIGHTEN" }, + { (int)BLIT_OP_DISJ_SRC_OVER, "DISJ_SRC_OVER" }, + { (int)BLIT_OP_DISJ_DST_OVER, "DISJ_DST_OVER" }, + { (int)BLIT_OP_DISJ_SRC_IN, "DISJ_SRC_IN" }, + { (int)BLIT_OP_DISJ_DST_IN, "DISJ_DST_IN" }, + { (int)BLIT_OP_DISJ_SRC_OUT, "DISJ_SRC_OUT" }, + { (int)BLIT_OP_DISJ_DST_OUT, "DISJ_DST_OUT" }, + { (int)BLIT_OP_DISJ_SRC_ATOP, "DISJ_SRC_ATOP" }, + { (int)BLIT_OP_DISJ_DST_ATOP, "DISJ_DST_ATOP" }, + { (int)BLIT_OP_DISJ_XOR, "DISJ_XOR" }, + { (int)BLIT_OP_CONJ_SRC_OVER, "CONJ_SRC_OVER" }, + { (int)BLIT_OP_CONJ_DST_OVER, "CONJ_DST_OVER" }, + { (int)BLIT_OP_CONJ_SRC_IN, "CONJ_SRC_IN" }, + { (int)BLIT_OP_CONJ_DST_IN, "CONJ_DST_IN" }, + { (int)BLIT_OP_CONJ_SRC_OUT, "CONJ_SRC_OUT" }, + { (int)BLIT_OP_CONJ_DST_OUT, "CONJ_DST_OUT" }, + { (int)BLIT_OP_CONJ_SRC_ATOP, "CONJ_SRC_ATOP" }, + { (int)BLIT_OP_CONJ_DST_ATOP, "CONJ_DST_ATOP" }, + { (int)BLIT_OP_CONJ_XOR, "CONJ_XOR" }, + { (int)BLIT_OP_USER_COEFF, "USER_COEFF" }, + { (int)BLIT_OP_END, "" }, +}; + +#ifndef REAL_DEBUG + void VOID_FUNC(const char *format, ...) + {} +#endif + +FimgApi::FimgApi() +{ + m_flagCreate = false; +} + +FimgApi::~FimgApi() +{ + if (m_flagCreate == true) + PRINT("%s::this is not Destroyed fail\n", __func__); +} + +bool FimgApi::Create(void) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto CREATE_DONE; + } + + if (m_flagCreate == true) { + PRINT("%s::Already Created fail\n", __func__); + goto CREATE_DONE; + } + + if (t_Create() == false) { + PRINT("%s::t_Create() fail\n", __func__); + goto CREATE_DONE; + } + + m_flagCreate = true; + + ret = true; + +CREATE_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Destroy(void) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto DESTROY_DONE; + } + + if (m_flagCreate == false) { + PRINT("%s::Already Destroyed fail\n", __func__); + goto DESTROY_DONE; + } + + if (t_Destroy() == false) { + PRINT("%s::t_Destroy() fail\n", __func__); + goto DESTROY_DONE; + } + + m_flagCreate = false; + + ret = true; + +DESTROY_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Stretch(struct fimg2d_blit *cmd) +{ + bool ret = false; + + if (t_Lock() == false) { + PRINT("%s::t_Lock() fail\n", __func__); + goto STRETCH_DONE; + } + + if (m_flagCreate == false) { + PRINT("%s::This is not Created fail\n", __func__); + goto STRETCH_DONE; + } + + if (t_Stretch(cmd) == false) { + goto STRETCH_DONE; + } + + ret = true; + +STRETCH_DONE : + + t_UnLock(); + + return ret; +} + +bool FimgApi::Sync(void) +{ + bool ret = false; + + if (m_flagCreate == false) { + PRINT("%s::This is not Created fail\n", __func__); + goto SYNC_DONE; + } + + if (t_Sync() == false) + goto SYNC_DONE; + + ret = true; + +SYNC_DONE : + + return ret; +} + +bool FimgApi::t_Create(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Destroy(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Stretch(struct fimg2d_blit *cmd) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Sync(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_Lock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +bool FimgApi::t_UnLock(void) +{ + PRINT("%s::This is empty virtual function fail\n", __func__); + return false; +} + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" int stretchFimgApi(struct fimg2d_blit *cmd) +{ + FimgApi * fimgApi = createFimgApi(); + + if (fimgApi == NULL) { + PRINT("%s::createFimgApi() fail\n", __func__); + return -1; + } + + if (fimgApi->Stretch(cmd) == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + +extern "C" int SyncFimgApi(void) +{ + FimgApi * fimgApi = createFimgApi(); + if (fimgApi == NULL) { + PRINT("%s::createFimgApi() fail\n", __func__); + return -1; + } + + if (fimgApi->Sync() == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return -1; + } + + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + +void printDataBlit(char *title, struct fimg2d_blit *cmd) +{ + LOGI("%s\n", title); + + LOGI(" sequence_no. = %u\n", cmd->seq_no); + LOGI(" blit_op = %d(%s)\n", cmd->op, optbl[cmd->op].str); + LOGI(" fill_color = %X\n", cmd->solid_color); + LOGI(" global_alpha = %u\n", (unsigned int)cmd->g_alpha); + LOGI(" PREMULT = %s\n", cmd->premult == PREMULTIPLIED ? "PREMULTIPLIED" : "NON-PREMULTIPLIED"); + LOGI(" do_dither = %s\n", cmd->dither == true ? "dither" : "no-dither"); + + printDataBlitRotate(cmd->rotate); + + printDataBlitScale(cmd->scaling); + + printDataBlitImage("SRC", cmd->src); + printDataBlitImage("DST", cmd->dst); + printDataBlitImage("MSK", cmd->msk); + + printDataBlitRect("SRC", cmd->src_rect); + printDataBlitRect("DST", cmd->dst_rect); + printDataBlitRect("MSK", cmd->msk_rect); + + printDataBlitClip(cmd->clipping); +} + +void printDataBlitImage(char *title, struct fimg2d_image *image) +{ + if (NULL != image) { + LOGI(" Image_%s\n", title); + LOGI(" addr = %X\n", image->addr.start); + LOGI(" size = %u\n", image->addr.size); + LOGI(" (width, height) = (%d, %d)\n", image->width, image->height); + LOGI(" format = %d\n", image->fmt); + } else + LOGI(" Image_%s : NULL\n", title); +} + +void printDataBlitRect(char *title, struct fimg2d_rect *rect) +{ + if (NULL != rect) { + LOGI(" RECT_%s\n", title); + LOGI(" (x1, y1) = (%d, %d)\n", rect->x1, rect->y1); + LOGI(" (x2, y2) = (%d, %d)\n", rect->x2, rect->y2); + LOGI(" (width, height) = (%d, %d)\n", rect->x2 - rect->x1, rect->y2 - rect->y1); + } else + LOGI(" RECT_%s : NULL\n", title); +} + +void printDataBlitRotate(enum rotation rotate) +{ + LOGI(" ROTATE : %d\n", rotate); +} + +void printDataBlitClip(struct fimg2d_clip *clip) +{ + if (NULL != clip) { + LOGI(" CLIP\n"); + LOGI(" clip %s\n", clip->enable == true ? "enabled" : "disabled"); + LOGI(" (x1, y1) = (%d, %d)\n", clip->x1, clip->y1); + LOGI(" (x2, y2) = (%d, %d)\n", clip->x2, clip->y2); + LOGI(" (width, hight) = (%d, %d)\n", clip->x2 - clip->x1, clip->y2 - clip->y1); + } else + LOGI(" CLIP : NULL\n"); +} + +void printDataBlitScale(struct fimg2d_scale *scaling) +{ + if (NULL != scaling) { + LOGI(" SCALING\n"); + LOGI(" scale_mode : %s\n", scaling->mode == 0 ? + "NO_SCALING" : + (scaling->mode == 1 ? "SCALING_NEAREST" : "SCALING_BILINEAR")); + LOGI(" scaling_factor_unit : %s\n", scaling->factor == 0 ? "PERCENT" : "PIXEL"); + + if (scaling->factor == 0) + LOGI(" scaling_factor : (scale_w, scale_y) = (%d, %d)\n", scaling->scale_w, scaling->scale_h); + else { + LOGI(" src : (src_w, src_h) = (%d, %d)\n", scaling->src_w, scaling->src_h); + LOGI(" dst : (dst_w, dst_h) = (%d, %d)\n", scaling->dst_w, scaling->dst_h); + LOGI(" scaling_factor : (scale_w, scale_y) = (%3.2f, %3.2f)\n", (double)scaling->dst_w / scaling->src_w, (double)scaling->dst_h / scaling->src_h); + } + } else + LOGI(" SCALING : NULL(NO SCALE MODE)\n"); + +} + +void printDataMatrix(int matrixType) +{ + LOGI(" MATRIX\n"); + + if (matrixType & SkMatrix::kIdentity_Mask) + LOGI(" Matrix_type : Identity_Mask\n"); + + if (matrixType & SkMatrix::kTranslate_Mask) + LOGI(" Matrix_type : Translate_Mask(the matrix has translation)\n"); + + if (matrixType & SkMatrix::kScale_Mask) + LOGI(" Matrix_type : Scale_Mask(the matrix has X or Y scale)\n"); + + if (matrixType & SkMatrix::kAffine_Mask) + LOGI(" Matrix_type : Affine_Mask(the matrix skews or rotates)\n"); + + if (matrixType & SkMatrix::kPerspective_Mask) + LOGI(" Matrix_type : Perspective_Mask(the matrix is in perspective)\n"); +} diff --git a/exynos5/hal/libfimg4x/FimgApi.h b/exynos5/hal/libfimg4x/FimgApi.h new file mode 100644 index 0000000..a2c9eac --- /dev/null +++ b/exynos5/hal/libfimg4x/FimgApi.h @@ -0,0 +1,114 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_API_H +#define FIMG_API_H + +#include +#include "SkMatrix.h" +#include "sec_g2d_4x.h" + +#define REAL_DEBUG +#define ANDROID_LOG + +#if defined(REAL_DEBUG) +#ifdef ANDROID_LOG +#define PRINT LOGE +#define PRINTD LOGD +#else +#define PRINT printf +#define PRINTD printf +#endif +#else +void VOID_FUNC(const char *format, ...); + +#define PRINT VOID_FUNC +#define PRINTD VOID_FUNC +#endif + +#ifdef __cplusplus + +struct blit_op_table { + int op; + const char *str; +}; + +extern struct blit_op_table optbl[]; + +class FimgApi +{ +public: +#endif + +#ifdef __cplusplus +private : + bool m_flagCreate; + +protected : + FimgApi(); + FimgApi(const FimgApi& rhs) {} + virtual ~FimgApi(); + +public: + bool Create(void); + bool Destroy(void); + inline bool FlagCreate(void) { return m_flagCreate; } + bool Stretch(struct fimg2d_blit *cmd); + bool Sync(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(struct fimg2d_blit *cmd); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +}; +#endif + +#ifdef __cplusplus +extern "C" +#endif +struct FimgApi *createFimgApi(); + +#ifdef __cplusplus +extern "C" +#endif +void destroyFimgApi(FimgApi *ptrFimgApi); + +#ifdef __cplusplus +extern "C" +#endif +int stretchFimgApi(struct fimg2d_blit *cmd); +#ifdef __cplusplus +extern "C" +#endif +int SyncFimgApi(void); + +void printDataBlit(char *title, struct fimg2d_blit *cmd); +void printDataBlitRotate(enum rotation rotate); +void printDataBlitImage(char *title, struct fimg2d_image *image); +void printDataBlitRect(char *title, struct fimg2d_rect *rect); +void printDataBlitClip(struct fimg2d_clip *clip); +void printDataBlitScale(struct fimg2d_scale *scaling); +void printDataMatrix(int matrixType); + +#endif //FIMG_API_H diff --git a/exynos5/hal/libfimg4x/FimgExynos5.cpp b/exynos5/hal/libfimg4x/FimgExynos5.cpp new file mode 100644 index 0000000..87c8527 --- /dev/null +++ b/exynos5/hal/libfimg4x/FimgExynos5.cpp @@ -0,0 +1,301 @@ +/* +** +** Copyright 2009 Samsung Electronics Co, Ltd. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "FimgExynos5" +#include + +#include "FimgExynos5.h" + +namespace android +{ +Mutex FimgV4x::m_instanceLock; +int FimgV4x::m_curFimgV4xIndex = 0; +int FimgV4x::m_numOfInstance = 0; +FimgApi * FimgV4x::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, }; + +//---------------------------------------------------------------------------// + +FimgV4x::FimgV4x() + : m_g2dFd(0), + m_g2dVirtAddr(NULL), + m_g2dSize(0), + m_g2dSrcVirtAddr(NULL), + m_g2dSrcSize(0), + m_g2dDstVirtAddr(NULL), + m_g2dDstSize(0) +{ + m_lock = new Mutex(Mutex::SHARED, "FimgV4x"); +} + +FimgV4x::~FimgV4x() +{ + delete m_lock; +} + +FimgApi *FimgV4x::CreateInstance() +{ + Mutex::Autolock autolock(m_instanceLock); + + FimgApi *ptrFimg = NULL; + + for(int i = m_curFimgV4xIndex; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] == NULL) + m_ptrFimgApiList[i] = new FimgV4x; + + if (m_ptrFimgApiList[i]->FlagCreate() == false) { + if (m_ptrFimgApiList[i]->Create() == false) { + PRINT("%s::Create(%d) fail\n", __func__, i); + goto CreateInstance_End; + } + else + m_numOfInstance++; + } + + if (i < NUMBER_FIMG_LIST - 1) + m_curFimgV4xIndex = i + 1; + else + m_curFimgV4xIndex = 0; + + ptrFimg = m_ptrFimgApiList[i]; + goto CreateInstance_End; + } + +CreateInstance_End : + + return ptrFimg; +} + +void FimgV4x::DestroyInstance(FimgApi * ptrFimgApi) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] != NULL && m_ptrFimgApiList[i] == ptrFimgApi) { + if (m_ptrFimgApiList[i]->FlagCreate() == true && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; + delete tempFimgV4x; + m_ptrFimgApiList[i] = NULL; + + m_numOfInstance--; + } + + break; + } + } +} + +void FimgV4x::DestroyAllInstance(void) +{ + Mutex::Autolock autolock(m_instanceLock); + + for(int i = 0; i < NUMBER_FIMG_LIST; i++) { + if (m_ptrFimgApiList[i] != NULL) { + if (m_ptrFimgApiList[i]->FlagCreate() == true + && m_ptrFimgApiList[i]->Destroy() == false) { + PRINT("%s::Destroy() fail\n", __func__); + } else { + FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; + delete tempFimgV4x; + m_ptrFimgApiList[i] = NULL; + } + } + } +} + +bool FimgV4x::t_Create(void) +{ + bool ret = true; + + if (m_CreateG2D() == false) { + PRINT("%s::m_CreateG2D() fail \n", __func__); + + if (m_DestroyG2D() == false) + PRINT("%s::m_DestroyG2D() fail \n", __func__); + + ret = false; + } + + return ret; +} + +bool FimgV4x::t_Destroy(void) +{ + bool ret = true; + + if (m_DestroyG2D() == false) { + PRINT("%s::m_DestroyG2D() fail \n", __func__); + ret = false; + } + + return ret; +} + +bool FimgV4x::t_Stretch(struct fimg2d_blit *cmd) +{ +#ifdef CHECK_FIMGV4x_PERFORMANCE +#define NUM_OF_STEP (10) + StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE"); + const char *stopWatchName[NUM_OF_STEP]; + nsecs_t stopWatchTime[NUM_OF_STEP]; + int stopWatchIndex = 0; +#endif // CHECK_FIMGV4x_PERFORMANCE + + if (m_DoG2D(cmd) == false) { + goto STRETCH_FAIL; + } + +#ifdef G2D_NONE_BLOCKING_MODE + if (m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto STRETCH_FAIL; + } +#endif + + #ifdef CHECK_FIMGV4x_PERFORMANCE + m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); + #endif // CHECK_FIMGV4x_PERFORMANCE + + return true; + +STRETCH_FAIL: + return false; + +} + +bool FimgV4x::t_Sync(void) +{ + if (m_PollG2D(&m_g2dPoll) == false) + { + PRINT("%s::m_PollG2D() fail\n", __func__); + goto SYNC_FAIL; + } + return true; + +SYNC_FAIL: + return false; + +} + +bool FimgV4x::t_Lock(void) +{ + m_lock->lock(); + return true; +} + +bool FimgV4x::t_UnLock(void) +{ + m_lock->unlock(); + return true; +} + +bool FimgV4x::m_CreateG2D(void) +{ + void * mmap_base; + + if (m_g2dFd != 0) { + PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd); + return false; + } + +#ifdef G2D_NONE_BLOCKING_MODE + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK); +#else + m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR); +#endif + if (m_g2dFd < 0) { + PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno)); + m_g2dFd = 0; + return false; + } + + memset(&m_g2dPoll, 0, sizeof(m_g2dPoll)); + m_g2dPoll.fd = m_g2dFd; + m_g2dPoll.events = POLLOUT | POLLERR; + + return true; +} + +bool FimgV4x::m_DestroyG2D(void) +{ + if (m_g2dVirtAddr != NULL) { + munmap(m_g2dVirtAddr, m_g2dSize); + m_g2dVirtAddr = NULL; + m_g2dSize = 0; + } + + if (0 < m_g2dFd) { + close(m_g2dFd); + } + m_g2dFd = 0; + + return true; +} + +bool FimgV4x::m_DoG2D(struct fimg2d_blit *cmd) +{ + + if (ioctl(m_g2dFd, FIMG2D_BITBLT_BLIT, cmd) < 0) + return false; + + return true; +} + +inline bool FimgV4x::m_PollG2D(struct pollfd * events) +{ +#define G2D_POLL_TIME (1000) + + int ret; + + ret = poll(events, 1, G2D_POLL_TIME); + + if (ret < 0) { + PRINT("%s::poll fail \n", __func__); + return false; + } + else if (ret == 0) { + PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME); + return false; + } + + return true; +} + +//---------------------------------------------------------------------------// +// extern function +//---------------------------------------------------------------------------// +extern "C" struct FimgApi * createFimgApi() +{ + if (fimgApiAutoFreeThread == 0) + fimgApiAutoFreeThread = new FimgApiAutoFreeThread(); + else + fimgApiAutoFreeThread->SetOneMoreSleep(); + + return FimgV4x::CreateInstance(); +} + +extern "C" void destroyFimgApi(FimgApi * ptrFimgApi) +{ + // Dont' call DestroyInstance. +} + +}; // namespace android diff --git a/exynos5/hal/libfimg4x/FimgExynos5.h b/exynos5/hal/libfimg4x/FimgExynos5.h new file mode 100644 index 0000000..71295a6 --- /dev/null +++ b/exynos5/hal/libfimg4x/FimgExynos5.h @@ -0,0 +1,169 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2009 Samsung Electronics Co, Ltd. All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +** +*/ + +#ifndef FIMG_EXYNOS5_H +#define FIMG_EXYNOS5_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "FimgApi.h" + +#include "sec_g2d_4x.h" + +namespace android +{ + +#define NUMBER_FIMG_LIST (1) // kcoolsw : because of pmem +#define GET_RECT_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_REAL_SIZE(rect) ((rect->full_w) * (rect->h) * (rect->bytes_per_pixel)) +#define GET_START_ADDR(rect) (rect->virt_addr + ((rect->y * rect->full_w) * rect->bytes_per_pixel)) +#define SLEEP_TIME (3000000) // 3 sec + +//---------------------------------------------------------------------------// +// class FimgV4x : public FimgBase +//---------------------------------------------------------------------------// +class FimgV4x : public FimgApi +{ +private : + int m_g2dFd; + + unsigned char *m_g2dVirtAddr; + unsigned int m_g2dSize; + unsigned char *m_g2dSrcVirtAddr; + unsigned int m_g2dSrcSize; + unsigned char *m_g2dDstVirtAddr; + unsigned int m_g2dDstSize; + struct pollfd m_g2dPoll; + + Mutex *m_lock; + + static Mutex m_instanceLock; + static int m_curFimgV4xIndex; + static int m_numOfInstance; + + static FimgApi *m_ptrFimgApiList[NUMBER_FIMG_LIST]; + +protected : + FimgV4x(); + virtual ~FimgV4x(); + +public: + static FimgApi *CreateInstance(); + static void DestroyInstance(FimgApi *ptrFimgApi); + static void DestroyAllInstance(void); + +protected: + virtual bool t_Create(void); + virtual bool t_Destroy(void); + virtual bool t_Stretch(struct fimg2d_blit *cmd); + virtual bool t_Sync(void); + virtual bool t_Lock(void); + virtual bool t_UnLock(void); + +private: + bool m_CreateG2D(void); + bool m_DestroyG2D(void); + + bool m_DoG2D(struct fimg2d_blit *cmd); + + inline bool m_PollG2D(struct pollfd *events); + + inline int m_ColorFormatFimgApi2FimgHw(int colorFormat); +}; + +class FimgApiAutoFreeThread; + +static sp fimgApiAutoFreeThread = 0; + +class FimgApiAutoFreeThread : public Thread +{ +private: + bool mOneMoreSleep; + bool mDestroyed; + +public: + FimgApiAutoFreeThread(void): + Thread(false), + mOneMoreSleep(true), + mDestroyed(false) + { } + ~FimgApiAutoFreeThread(void) + { + if (mDestroyed == false) + { + FimgV4x::DestroyAllInstance(); + mDestroyed = true; + } + } + + virtual void onFirstRef() + { + run("FimgApiAutoFreeThread", PRIORITY_BACKGROUND); + } + + virtual bool threadLoop() + { + + if (mOneMoreSleep == true) + { + mOneMoreSleep = false; + usleep(SLEEP_TIME); + + return true; + } + else + { + if (mDestroyed == false) + { + FimgV4x::DestroyAllInstance(); + mDestroyed = true; + } + + fimgApiAutoFreeThread = 0; + + return false; + } + } + + void SetOneMoreSleep(void) + { + mOneMoreSleep = true; + } +}; + +}; // namespace android + +#endif // FIMG_EXYNOS5_H diff --git a/exynos5/hal/libfimg4x/sec_g2d_4x.h b/exynos5/hal/libfimg4x/sec_g2d_4x.h new file mode 100644 index 0000000..b9ddbb2 --- /dev/null +++ b/exynos5/hal/libfimg4x/sec_g2d_4x.h @@ -0,0 +1,326 @@ +/* + * Copyright 2011, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __SEC_G2D_4X_H +#define __SEC_G2D_4X_H __FILE__ + +#define SEC_G2D_DEV_NAME "/dev/fimg2d" + +/* ioctl commands */ +#define FIMG2D_IOCTL_MAGIC 'F' +#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit) +#define FIMG2D_BITBLT_SYNC _IO(FIMG2D_IOCTL_MAGIC, 1) +#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version) + +#define G2D_ALPHA_VALUE_MAX (255) + +enum addr_space { + ADDR_UNKNOWN, + ADDR_PHYS, + ADDR_KERN, + ADDR_USER, + ADDR_DEVICE, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum pixel_order { + AX_RGB = 0, + RGB_AX, + AX_BGR, + BGR_AX, + ARGB_ORDER_END, + + P1_CRY1CBY0, + P1_CBY1CRY0, + P1_Y1CRY0CB, + P1_Y1CBY0CR, + P1_ORDER_END, + + P2_CRCB, + P2_CBCR, + P2_ORDER_END, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum color_format { + CF_XRGB_8888 = 0, + CF_ARGB_8888, + CF_RGB_565, + CF_XRGB_1555, + CF_ARGB_1555, + CF_XRGB_4444, + CF_ARGB_4444, + CF_RGB_888, + CF_YCBCR_444, + CF_YCBCR_422, + CF_YCBCR_420, + CF_A8, + CF_L8, + SRC_DST_FORMAT_END, + + CF_MSK_1BIT, + CF_MSK_4BIT, + CF_MSK_8BIT, + CF_MSK_16BIT_565, + CF_MSK_16BIT_1555, + CF_MSK_16BIT_4444, + CF_MSK_32BIT_8888, + MSK_FORMAT_END, +}; + +enum rotation { + ORIGIN, + ROT_90, /* clockwise */ + ROT_180, + ROT_270, + XFLIP, /* x-axis flip */ + YFLIP, /* y-axis flip */ +}; + +/** + * @NO_REPEAT: no effect + * @REPEAT_NORMAL: repeat horizontally and vertically + * @REPEAT_PAD: pad with pad color + * @REPEAT_REFLECT: reflect horizontally and vertically + * @REPEAT_CLAMP: pad with edge color of original image + * + * DO NOT CHANGE THIS ORDER + */ +enum repeat { + NO_REPEAT = 0, + REPEAT_NORMAL, /* default setting */ + REPEAT_PAD, + REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT, + REPEAT_CLAMP, +}; + +enum scaling { + NO_SCALING, + SCALING_NEAREST, + SCALING_BILINEAR, +}; + +/** + * @SCALING_PERCENTAGE: percentage of width, height + * @SCALING_PIXELS: coordinate of src, dest + */ +enum scaling_factor { + SCALING_PERCENTAGE, + SCALING_PIXELS, +}; + +/** + * premultiplied alpha + */ +enum premultiplied { + PREMULTIPLIED, + NON_PREMULTIPLIED, +}; + +/** + * @TRANSP: discard bluescreen color + * @BLUSCR: replace bluescreen color with background color + */ +enum bluescreen { + OPAQUE, + TRANSP, + BLUSCR, +}; + +/** + * DO NOT CHANGE THIS ORDER + */ +enum blit_op { + BLIT_OP_SOLID_FILL = 0, + + BLIT_OP_CLR, + BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC, + BLIT_OP_DST, + BLIT_OP_SRC_OVER, + BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER, + BLIT_OP_SRC_IN, + BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN, + BLIT_OP_SRC_OUT, + BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT, + BLIT_OP_SRC_ATOP, + BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP, + BLIT_OP_XOR, + + BLIT_OP_ADD, + BLIT_OP_MULTIPLY, + BLIT_OP_SCREEN, + BLIT_OP_DARKEN, + BLIT_OP_LIGHTEN, + + BLIT_OP_DISJ_SRC_OVER, + BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER, + BLIT_OP_DISJ_SRC_IN, + BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN, + BLIT_OP_DISJ_SRC_OUT, + BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT, + BLIT_OP_DISJ_SRC_ATOP, + BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP, + BLIT_OP_DISJ_XOR, + + BLIT_OP_CONJ_SRC_OVER, + BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER, + BLIT_OP_CONJ_SRC_IN, + BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN, + BLIT_OP_CONJ_SRC_OUT, + BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT, + BLIT_OP_CONJ_SRC_ATOP, + BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP, + BLIT_OP_CONJ_XOR, + + /* Add new operation type here */ + + /* user select coefficient manually */ + BLIT_OP_USER_COEFF, + + /* end of blit operation */ + BLIT_OP_END, + + /* driver not supporting format */ + BLIT_OP_NOT_SUPPORTED +}; + +#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END + +struct fimg2d_version { + unsigned int hw; + unsigned int sw; +}; + +/** + * @start: start address or unique id of image + * @size: whole length of allocated image + * @cacheable: memory is cacheable + * @pinnable: memory is pinnable. currently not supported. + */ +struct fimg2d_addr { + enum addr_space type; + unsigned long start; + size_t size; + int cacheable; + int pinnable; +}; + +struct fimg2d_rect { + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +/** + * if factor is percentage, scale_w and scale_h are valid + * if factor is pixels, src_w, src_h, dst_w, dst_h are valid + */ +struct fimg2d_scale { + enum scaling mode; + enum scaling_factor factor; + + /* percentage */ + int scale_w; + int scale_h; + + /* pixels */ + int src_w, src_h; + int dst_w, dst_h; +}; + +/** + * coordinate from start address(0,0) of image + */ +struct fimg2d_clip { + bool enable; + int x1; + int y1; + int x2; /* x1 + width */ + int y2; /* y1 + height */ +}; + +struct fimg2d_repeat { + enum repeat mode; + unsigned long pad_color; +}; + +/** + * @bg_color: bg_color is valid only if bluescreen mode is BLUSCR. + */ +struct fimg2d_bluscr { + enum bluescreen mode; + unsigned long bs_color; + unsigned long bg_color; +}; + +/** + * @plane2: address info for CbCr in YCbCr 2plane mode + */ +struct fimg2d_image { + struct fimg2d_addr addr; + struct fimg2d_addr plane2; + int width; + int height; + int stride; + enum pixel_order order; + enum color_format fmt; +}; + +struct fimg2d_param { + enum blit_op op; + unsigned long fillcolor; + unsigned char g_alpha; + enum premultiplied premult; + bool dither; + enum rotation rotate; + struct fimg2d_scale *scaling; + struct fimg2d_repeat *repeat; + struct fimg2d_bluscr *bluscr; + struct fimg2d_clip *clipping; +}; + +/** + * @g_alpha: 0xff is opaque, 0x0 is transparnet + * @seq_no: used for debugging + */ +struct fimg2d_blit { + enum blit_op op; + + enum premultiplied premult; + unsigned char g_alpha; + bool dither; + enum rotation rotate; + struct fimg2d_scale *scaling; + struct fimg2d_repeat *repeat; + struct fimg2d_bluscr *bluscr; + struct fimg2d_clip *clipping; + + unsigned long solid_color; + struct fimg2d_image *src; + struct fimg2d_image *dst; + struct fimg2d_image *msk; + + struct fimg2d_rect *src_rect; + struct fimg2d_rect *dst_rect; + struct fimg2d_rect *msk_rect; + + unsigned int seq_no; +}; +#endif /* __SEC_G2D_4X_H__ */ diff --git a/exynos5/hal/libgralloc_ump/Android.mk b/exynos5/hal/libgralloc_ump/Android.mk new file mode 100644 index 0000000..a4354d4 --- /dev/null +++ b/exynos5/hal/libgralloc_ump/Android.mk @@ -0,0 +1,59 @@ +# +# Copyright (C) 2010 ARM Limited. All rights reserved. +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +LOCAL_PATH := $(call my-dir) + +# HAL module implemenation, not prelinked and stored in +# hw/..so +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libGLES_mali libion +LOCAL_MODULE_TAGS := eng optional + +# Include the UMP header files +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := \ + gralloc_module.cpp \ + alloc_device.cpp \ + framebuffer_device.cpp + +# For now we override arch and ABI values to allow us to work with a +# libmali that has been forced to armv7, eventually we can let android +# pick for us + +ifeq ($(TARGET_PRODUCT), armboard_v7a) +# Support for ARM platforms +LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -DGRALLOC_16_BITS -DSTANDARD_LINUX_SCREEN \ + -march=armv7-a \ + -mfloat-abi=softfp +LOCAL_MODULE := gralloc.default + +else +#Default to goldfish +LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -DSTANDARD_LINUX_SCREEN \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -DVITHAR_HACK + +LOCAL_MODULE := gralloc.smdk5250 +endif + + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos5/hal/libgralloc_ump/alloc_device.cpp b/exynos5/hal/libgralloc_ump/alloc_device.cpp new file mode 100644 index 0000000..64be027 --- /dev/null +++ b/exynos5/hal/libgralloc_ump/alloc_device.cpp @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "alloc_device.h" +#include "gralloc_priv.h" +#include "gralloc_helper.h" +#include "framebuffer_device.h" + +#include "ump.h" + +#include "sec_format.h" + +#include + +#ifdef ION_ALLOC +#include "ion.h" +#endif + +#include +#include + +/* Treat GPU as UMP Device Z */ +#define GRALLOC_DEVICE_SHIFT UMP_DEVICE_Z_SHIFT + +#define EXYNOS_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) +static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp, int stride_raw, int stride) +{ + ion_buffer ion_fd = 0; + ump_handle ump_mem_handle; + void *cpu_ptr = NULL; + ump_secure_id ump_id=UMP_INVALID_SECURE_ID; + ump_alloc_flags ump_flags = UMP_PROT_SHAREABLE | UMP_HINT_CPU_RD | UMP_HINT_CPU_WR; + int sw_read_usage; + int sw_write_usage; + int hw_usage; + size = round_up_to_page_size(size); + + unsigned int ion_flags = 0; + int priv_alloc_flag = private_handle_t::PRIV_FLAGS_USES_UMP; + + if (usage & GRALLOC_USAGE_HW_ION) { + private_module_t* m = reinterpret_cast(dev->common.module); + ion_fd = ion_alloc(m->ion_client, size, 0, ION_HEAP_EXYNOS_MASK); + if (ion_fd < 0) { + LOGE("Failed to ion_alloc"); + return -1; + } + + cpu_ptr = ion_map(ion_fd, size, 0); + if (NULL == cpu_ptr) { + LOGE("Failed to ion_map"); + ion_free(ion_fd); + return -1; + } + /* TODO: GPU does not use ION. */ + ump_mem_handle = ump_import(UMP_EXTERNAL_MEM_TYPE_ION, &ion_fd, ump_flags); + if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { + priv_alloc_flag = private_handle_t::PRIV_FLAGS_USES_ION; + } else { + LOGE("gralloc_alloc_buffer() failed to import ION memory"); + ion_unmap(cpu_ptr, size); + ion_free(ion_fd); + return -1; + } + } else { + usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER; + sw_read_usage = usage & GRALLOC_USAGE_SW_READ_MASK; + sw_write_usage = usage & GRALLOC_USAGE_SW_WRITE_MASK; + hw_usage = usage & GRALLOC_USAGE_HW_MASK; + + if (sw_read_usage) { + ump_flags |= UMP_PROT_CPU_RD; + if (sw_read_usage == GRALLOC_USAGE_SW_READ_OFTEN) + ump_flags |= UMP_HINT_CPU_RD; + } + if (sw_write_usage) { + ump_flags |= UMP_PROT_CPU_WR; + if (sw_write_usage == GRALLOC_USAGE_SW_WRITE_OFTEN) + ump_flags |= UMP_HINT_CPU_WR; + } + + if (hw_usage) { + int hw_flags = 0; + if (hw_usage & (GRALLOC_USAGE_HW_TEXTURE)) + hw_flags |= (UMP_PROT_DEVICE_RD | UMP_HINT_DEVICE_RD); + + if (hw_usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_FB)) + hw_flags |= (UMP_PROT_DEVICE_RD | UMP_HINT_DEVICE_RD | UMP_PROT_DEVICE_WR | UMP_HINT_DEVICE_WR); + + ump_flags |= (hw_flags << GRALLOC_DEVICE_SHIFT); + } + + ump_mem_handle = ump_allocate_64(size, ump_flags); + if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) + cpu_ptr = ump_map(ump_mem_handle, 0, size); + else + LOGE("gralloc_alloc_buffer() failed to allcoate UMP memory"); + } + + if (NULL != cpu_ptr) { + ump_id = ump_secure_id_get(ump_mem_handle); + + if (UMP_INVALID_SECURE_ID != ump_id || usage & GRALLOC_USAGE_HW_ION) { + private_handle_t* hnd = new private_handle_t(priv_alloc_flag, size, (int)cpu_ptr, + private_handle_t::LOCK_STATE_MAPPED, + ump_id, + ump_mem_handle); + if (NULL != hnd) { + *pHandle = hnd; + hnd->fd = ion_fd; + hnd->format = format; + hnd->usage = usage; + hnd->width = w; + hnd->height = h; + hnd->bpp = bpp; + hnd->stride = stride; + hnd->uoffset = ((EXYNOS_ALIGN(hnd->width, 16) * EXYNOS_ALIGN(hnd->height, 16))); + hnd->voffset = ((EXYNOS_ALIGN((hnd->width >> 1), 8) * EXYNOS_ALIGN((hnd->height >> 1), 8))); + return 0; + } else { + LOGE("gralloc_alloc_buffer() failed to allocate handle"); + } + } else { + LOGE("gralloc_alloc_buffer() failed to retrieve valid secure id"); + } + + ump_unmap(ump_mem_handle, cpu_ptr, size); + } else { + LOGE("gralloc_alloc_buffer() failed to map UMP memory"); + } + + ump_release(ump_mem_handle); + + return -1; +} + +static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp) +{ + private_module_t* m = reinterpret_cast(dev->common.module); + + /* allocate the framebuffer */ + if (m->framebuffer == NULL) { + /* initialize the framebuffer, the framebuffer is mapped once and forever. */ + int err = init_frame_buffer_locked(m); + + if (err < 0) + return err; + } + + const uint32_t bufferMask = m->bufferMask; + const uint32_t numBuffers = m->numBuffers; + const size_t bufferSize = m->finfo.line_length * m->info.yres; + + if (numBuffers == 1) { + /* + * If we have only one buffer, we never use page-flipping. Instead, + * we return a regular buffer which will be memcpy'ed to the main + * screen when post is called. + */ + int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; + + LOGD("fallback to single buffering"); + + return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle, w, h, format, bpp, 0, 0); + } + + if (bufferMask >= ((1LU<framebuffer->base; + /* find a free slot */ + for (uint32_t i = 0; i < numBuffers; i++) { + if ((bufferMask & (1LU<bufferMask |= (1LU<framebuffer->fd), vaddr - m->framebuffer->base); + hnd->format = format; + hnd->usage = usage; + hnd->width = w; + hnd->height = h; + hnd->bpp = bpp; + *pHandle = hnd; + + return 0; +} + +static int gralloc_alloc_framebuffer(alloc_device_t* dev, size_t size, int usage, + buffer_handle_t* pHandle, int w, int h, + int format, int bpp) +{ + private_module_t* m = reinterpret_cast(dev->common.module); + pthread_mutex_lock(&m->lock); + int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle, w, h, format, bpp); + pthread_mutex_unlock(&m->lock); + + return err; +} + +static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, + int usage, buffer_handle_t* pHandle, int* pStride) +{ + if (!pHandle || !pStride) { + LOGE("Invalid Handle, Stride value"); + return -EINVAL; + } + + int err; + int align = 16; + int bpp = 0; + size_t stride_raw = 0; + size_t size = 0; + size_t stride = (w + 15) & ~15; + size_t vstride = (h + 15) & ~15; + + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + bpp = 4; + break; + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + break; + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YV12: + size = stride * vstride * 2; + bpp = 4; + break; + default: + LOGE("Not Support Pixel Format"); + return -EINVAL; + } + + if (format != HAL_PIXEL_FORMAT_YCbCr_420_P && + format != HAL_PIXEL_FORMAT_YCbCr_420_SP && + format != HAL_PIXEL_FORMAT_YV12) { + size_t bpr = (w * bpp + (align-1)) & ~(align-1); + size = bpr * h; + stride = bpr / bpp; + stride_raw = bpr; + } + + if (usage & GRALLOC_USAGE_HW_FB) + err = gralloc_alloc_framebuffer(dev, size, usage, pHandle, w, h, format, 32); + else + err = gralloc_alloc_buffer(dev, size, usage, pHandle, w, h, + format, 0, (int)stride_raw, (int)stride); + + if (err < 0) { + LOGE("Fail to alloc Gralloc memory"); + return err; + } + + *pStride = stride; + return 0; +} + +static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("Invalid Value : private_handle"); + return -EINVAL; + } + + private_handle_t const* hnd = reinterpret_cast(handle); + if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + /* free this buffer */ + private_module_t* m = reinterpret_cast(dev->common.module); + const size_t bufferSize = m->finfo.line_length * m->info.yres; + int index = (hnd->base - m->framebuffer->base) / bufferSize; + m->bufferMask &= ~(1<fd); + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + ump_unmap(hnd->ump_mem_handle, (void*)hnd->base, hnd->size); + ump_release(hnd->ump_mem_handle); + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + ump_reference_release((ump_handle)hnd->ump_mem_handle); + + ion_unmap((void*)hnd->base, hnd->size); + ion_free(hnd->fd); + } + + delete hnd; + + return 0; +} + +static int alloc_device_close(struct hw_device_t *device) +{ + alloc_device_t* dev = reinterpret_cast(device); + if (dev) { + private_module_t* m = reinterpret_cast(dev->common.module); + ion_client_destroy(m->ion_client); + delete dev; + ump_close(); /* Our UMP memory refs will be released automatically here... */ + } + return 0; +} + +int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device) +{ + alloc_device_t *dev; + + dev = new alloc_device_t; + if (NULL == dev) { + LOGE("Fail to create alloc_device"); + return -1; + } + + dev->common.module = const_cast(module); + private_module_t* m = reinterpret_cast(dev->common.module); + m->ion_client=ion_client_create(); + LOGI("gralloc create ion_client %d", m->ion_client); + + ump_result ump_res = ump_open(); + + if ((UMP_OK != ump_res) || (0 > m->ion_client)) { + LOGE("UMP open failed, ump_res %d, ion_client %d", ump_res, m->ion_client); + delete dev; + return -1; + } + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = const_cast(module); + dev->common.close = alloc_device_close; + dev->alloc = alloc_device_alloc; + dev->free = alloc_device_free; + + *device = &dev->common; + + return 0; +} diff --git a/exynos5/hal/libgralloc_ump/alloc_device.h b/exynos5/hal/libgralloc_ump/alloc_device.h new file mode 100644 index 0000000..9877d4d --- /dev/null +++ b/exynos5/hal/libgralloc_ump/alloc_device.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// Create an alloc device +int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device); diff --git a/exynos5/hal/libgralloc_ump/framebuffer_device.cpp b/exynos5/hal/libgralloc_ump/framebuffer_device.cpp new file mode 100644 index 0000000..0015e54 --- /dev/null +++ b/exynos5/hal/libgralloc_ump/framebuffer_device.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "gralloc_priv.h" +#include "gralloc_helper.h" + +#include "linux/fb.h" + +/* numbers of buffers for page flipping */ +#define NUM_BUFFERS 2 + +enum { + PAGE_FLIP = 0x00000001, +}; + +static int fb_set_swap_interval(struct framebuffer_device_t* dev, int interval) +{ + if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval) + return -EINVAL; + + /* TODO: Currently not implemented */ + return 0; +} + +static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) +{ + if (private_handle_t::validate(buffer) < 0) + return -EINVAL; + + private_handle_t const* hnd = reinterpret_cast(buffer); + private_module_t* m = reinterpret_cast(dev->common.module); + + if (m->currentBuffer) { + m->base.unlock(&m->base, m->currentBuffer); + m->currentBuffer = 0; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, + 0, 0, m->info.xres, m->info.yres, NULL); + + const size_t offset = hnd->base - m->framebuffer->base; + m->info.activate = FB_ACTIVATE_VBL; + m->info.yoffset = offset / m->finfo.line_length; + +#ifdef STANDARD_LINUX_SCREEN + if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1) { + LOGE("FBIOPAN_DISPLAY failed"); + m->base.unlock(&m->base, buffer); + return 0; + } + + /* wait for VSYNC */ + int crtc = 0; + if (ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0) { + LOGE("FBIO_WAITFORVSYNC failed"); + return 0; + } +#else + /* Standard Android way */ + if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { + LOGE("FBIOPUT_VSCREENINFO failed"); + m->base.unlock(&m->base, buffer); + return -errno; + } +#endif + + m->currentBuffer = buffer; + } else { + void* fb_vaddr; + void* buffer_vaddr; + + m->base.lock(&m->base, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, + 0, 0, m->info.xres, m->info.yres, &fb_vaddr); + + m->base.lock(&m->base, buffer, GRALLOC_USAGE_SW_READ_RARELY, + 0, 0, m->info.xres, m->info.yres, &buffer_vaddr); + + memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres); + + m->base.unlock(&m->base, buffer); + m->base.unlock(&m->base, m->framebuffer); + } + + return 0; +} + +int init_frame_buffer_locked(struct private_module_t* module) +{ + if (module->framebuffer) + return 0; /* Nothing to do, already initialized */ + + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + NULL + }; + + int fd = -1; + int i = 0; + char name[64]; + + while ((fd == -1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + + if (fd < 0) { + LOGE("/dev/graphics/fb, /dev/fb Open fail"); + return -errno; + } + + struct fb_fix_screeninfo finfo; + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) { + LOGE("Fail to get FB Screen Info"); + return -errno; + } + + struct fb_var_screeninfo info; + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) { + LOGE("First, Fail to get FB VScreen Info"); + return -errno; + } + + info.reserved[0] = 0; + info.reserved[1] = 0; + info.reserved[2] = 0; + info.xoffset = 0; + info.yoffset = 0; + info.activate = FB_ACTIVATE_NOW; + +#ifdef GRALLOC_16_BITS + /* + * Explicitly request 5/6/5 + */ + info.bits_per_pixel = 16; + info.red.offset = 11; + info.red.length = 5; + info.green.offset = 5; + info.green.length = 6; + info.blue.offset = 0; + info.blue.length = 5; + info.transp.offset = 0; + info.transp.length = 0; +#else + /* + * Explicitly request 8/8/8 + */ + info.bits_per_pixel = 32; + info.red.offset = 16; + info.red.length = 8; + info.green.offset = 8; + info.green.length = 8; + info.blue.offset = 0; + info.blue.length = 8; + info.transp.offset = 0; + info.transp.length = 0; +#endif + + /* + * Request NUM_BUFFERS screens (at lest 2 for page flipping) + */ + info.yres_virtual = info.yres * NUM_BUFFERS; + + uint32_t flags = PAGE_FLIP; + if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { + info.yres_virtual = info.yres; + flags &= ~PAGE_FLIP; + LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); + } + + if (info.yres_virtual < info.yres * 2) { + /* we need at least 2 for page-flipping */ + info.yres_virtual = info.yres; + flags &= ~PAGE_FLIP; + LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", + info.yres_virtual, info.yres*2); + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) { + LOGE("Second, Fail to get FB VScreen Info"); + return -errno; + } + + int refreshRate = 1000000000000000LLU / + ( + uint64_t( info.upper_margin + info.lower_margin + info.yres ) + * ( info.left_margin + info.right_margin + info.xres ) + * info.pixclock + ); + + if (refreshRate == 0) + refreshRate = 60*1000; /* 60 Hz */ + + if (int(info.width) <= 0 || int(info.height) <= 0) { + /* the driver doesn't return that information default to 160 dpi */ + info.width = ((info.xres * 25.4f) / 160.0f + 0.5f); + info.height = ((info.yres * 25.4f) / 160.0f + 0.5f); + } + + float xdpi = (info.xres * 25.4f) / info.width; + float ydpi = (info.yres * 25.4f) / info.height; + float fps = refreshRate / 1000.0f; + + LOGI("using (fd=%d)\n" + "id = %s\n" + "xres = %d px\n" + "yres = %d px\n" + "xres_virtual = %d px\n" + "yres_virtual = %d px\n" + "bpp = %d\n" + "r = %2u:%u\n" + "g = %2u:%u\n" + "b = %2u:%u\n", + fd, + finfo.id, + info.xres, + info.yres, + info.xres_virtual, + info.yres_virtual, + info.bits_per_pixel, + info.red.offset, info.red.length, + info.green.offset, info.green.length, + info.blue.offset, info.blue.length); + + LOGI("width = %d mm (%f dpi)\n" + "height = %d mm (%f dpi)\n" + "refresh rate = %.2f Hz\n", + info.width, xdpi, + info.height, ydpi, + fps); + + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) { + LOGE("Fail to get FScreen Info"); + return -errno; + } + + if (finfo.smem_len <= 0) { + LOGE("Invalid Value : finfo.smem_len"); + return -errno; + } + + module->flags = flags; + module->info = info; + module->finfo = finfo; + module->xdpi = xdpi; + module->ydpi = ydpi; + module->fps = fps; + + /* + * map the framebuffer + */ + size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); + void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (vaddr == MAP_FAILED) { + LOGE("Error mapping the framebuffer (%s)", strerror(errno)); + return -errno; + } + + memset(vaddr, 0, fbSize); + + /* Create a "fake" buffer object for the entire frame buffer memory, + * and store it in the module */ + module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, + fbSize, intptr_t(vaddr), + 0, dup(fd), 0); + + module->numBuffers = info.yres_virtual / info.yres; + module->bufferMask = 0; + + return 0; +} + +static int init_frame_buffer(struct private_module_t* module) +{ + pthread_mutex_lock(&module->lock); + int err = init_frame_buffer_locked(module); + pthread_mutex_unlock(&module->lock); + return err; +} + +static int fb_close(struct hw_device_t *device) +{ + framebuffer_device_t* dev = reinterpret_cast(device); + if (dev) { + ump_close(); + delete dev; + } + return 0; +} + +int compositionComplete(struct framebuffer_device_t* dev) +{ + /* By doing a Finish here we force the GL driver to start rendering + all the drawcalls up to this point, and to wait for the rendering to be complete.*/ + + /* It move to HWComposit Module */ + + /* The rendering of the backbuffer is now completed. + When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done + synchronously in the same thread, and not asynchronoulsy in a background thread later. + The SurfaceFlinger requires this behaviour since it releases the lock on all the + SourceBuffers (Layers) after the compositionComplete() function returns. + However this "bad" behaviour by SurfaceFlinger should not affect performance, + since the Applications that render the SourceBuffers (Layers) still get the + full renderpipeline using asynchronouls rendering. So they perform at maximum speed, + and because of their complexity compared to the Surface flinger jobs, the Surface flinger + is normally faster even if it does everyhing synchronous and serial. + */ + return 0; +} + +int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device) +{ + int status = -EINVAL; + + alloc_device_t* gralloc_device; + status = gralloc_open(module, &gralloc_device); + if (status < 0) { + LOGE("Fail to Open gralloc device"); + return status; + } + + private_module_t* m = (private_module_t*)module; + status = init_frame_buffer(m); + if (status < 0) { + LOGE("Fail to init framebuffer"); + gralloc_close(gralloc_device); + return status; + } + + /* initialize our state here */ + framebuffer_device_t *dev = new framebuffer_device_t; + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = const_cast(module); + dev->common.close = fb_close; + dev->setSwapInterval = fb_set_swap_interval; + dev->post = fb_post; + dev->setUpdateRect = 0; + dev->compositionComplete = &compositionComplete; + + int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); + const_cast(dev->flags) = 0; + const_cast(dev->width) = m->info.xres; + const_cast(dev->height) = m->info.yres; + const_cast(dev->stride) = stride; +#ifdef GRALLOC_16_BITS + const_cast(dev->format) = HAL_PIXEL_FORMAT_RGB_565; +#else + const_cast(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888; +#endif + const_cast(dev->xdpi) = m->xdpi; + const_cast(dev->ydpi) = m->ydpi; + const_cast(dev->fps) = m->fps; + const_cast(dev->minSwapInterval) = 1; + const_cast(dev->maxSwapInterval) = 1; + *device = &dev->common; + status = 0; + + return status; +} diff --git a/exynos5/hal/libgralloc_ump/framebuffer_device.h b/exynos5/hal/libgralloc_ump/framebuffer_device.h new file mode 100644 index 0000000..4d84bef --- /dev/null +++ b/exynos5/hal/libgralloc_ump/framebuffer_device.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// Create a framebuffer device +int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device); + +// Initialize the framebuffer (must keep module lock before calling +int init_frame_buffer_locked(struct private_module_t* module); diff --git a/exynos5/hal/libgralloc_ump/gralloc_helper.h b/exynos5/hal/libgralloc_ump/gralloc_helper.h new file mode 100644 index 0000000..6a0a518 --- /dev/null +++ b/exynos5/hal/libgralloc_ump/gralloc_helper.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_HELPER_H_ +#define GRALLOC_HELPER_H_ + +#include + +inline size_t round_up_to_page_size(size_t x) +{ + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} + +#endif /* GRALLOC_HELPER_H_ */ diff --git a/exynos5/hal/libgralloc_ump/gralloc_module.cpp b/exynos5/hal/libgralloc_ump/gralloc_module.cpp new file mode 100644 index 0000000..8ca500b --- /dev/null +++ b/exynos5/hal/libgralloc_ump/gralloc_module.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include +#include "ump.h" + +#include "gralloc_priv.h" +#include "alloc_device.h" +#include "framebuffer_device.h" +#include "ion.h" +#include + +static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; +static int s_ump_is_open = 0; + +static int gralloc_map(gralloc_module_t const* module, + buffer_handle_t handle, void** vaddr) +{ + private_handle_t* hnd = (private_handle_t*)handle; + private_module_t* m = (private_module_t*)module; + + if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + size_t size = hnd->size; + hnd->ion_client = ion_client_create(); + void *mappedAddress = ion_map(hnd->fd, size, 0); + + if (mappedAddress == MAP_FAILED) { + LOGE("Could not ion_map %s fd(%d)", strerror(errno), hnd->fd); + return -errno; + } + + hnd->base = intptr_t(mappedAddress) + hnd->offset; + LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p", + hnd->fd, hnd->offset, hnd->size, mappedAddress); + } else { + LOGE("In case of ION, It could not reach here!"); + } + } + *vaddr = (void*)hnd->base; + return 0; +} + +static int gralloc_unmap(gralloc_module_t const* module, + buffer_handle_t handle) +{ + private_handle_t* hnd = (private_handle_t*)handle; + private_module_t* m = (private_module_t*)module; + + if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + void* base = (void*)hnd->base; + size_t size = hnd->size; + LOGD("unmapping from %p, size=%d", base, size); + + if (ion_unmap(base, size) < 0) + LOGE("Could not ion_unmap %s", strerror(errno)); + + ion_client_destroy(hnd->ion_client); + } + } + hnd->base = 0; + return 0; +} + +static int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device) +{ + int status = -EINVAL; + + LOGI("Opening ARM Gralloc device"); + + if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) + status = alloc_device_open(module, name, device); + else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) + status = framebuffer_device_open(module, name, device); + + return status; +} + +static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle) +{ + int retval = -EINVAL; + void *vaddr; + if (private_handle_t::validate(handle) < 0) { + LOGE("Registering invalid buffer, returning error"); + return -EINVAL; + } + + // if this handle was created in this process, then we keep it as is. + private_handle_t* hnd = (private_handle_t*)handle; + if (hnd->pid == getpid()) { + LOGE("Invalid Process ID from Private_Handle"); + return 0; + } + + pthread_mutex_lock(&s_map_lock); + if (!s_ump_is_open) { + ump_result res = ump_open(); + if (res != UMP_OK) { + pthread_mutex_unlock(&s_map_lock); + LOGE("Failed to open UMP library"); + return retval; + } + s_ump_is_open = 1; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + hnd->ump_mem_handle = ump_from_secure_id(hnd->ump_id); + if (UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle) { + hnd->base = (int)ump_map(hnd->ump_mem_handle, 0, hnd->size); + if (0 != hnd->base) { + hnd->lockState = private_handle_t::LOCK_STATE_MAPPED; + hnd->writeOwner = 0; + hnd->lockState = 0; + + pthread_mutex_unlock(&s_map_lock); + return 0; + } else { + LOGE("Failed to map UMP handle"); + } + + ump_release(hnd->ump_mem_handle); + } else { + LOGE("Failed to create UMP handle"); + } + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + hnd->ump_mem_handle = ump_handle_create_from_secure_id(hnd->ump_id); + retval = gralloc_map(module, handle, &vaddr); + } else { + LOGE("registering non-UMP&ION buffer not supported"); + } + + pthread_mutex_unlock(&s_map_lock); + + return retval; +} + +static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("unregistering invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + + LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, + "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState); + + /* never unmap buffers that were created in this process */ + if (hnd->pid != getpid()) { + pthread_mutex_lock(&s_map_lock); + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + ump_unmap(hnd->ump_mem_handle, (void*)hnd->base, hnd->size); + hnd->base = 0; + ump_release(hnd->ump_mem_handle); + hnd->ump_mem_handle = UMP_INVALID_MEMORY_HANDLE; + } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { + + ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); + ump_reference_release((ump_handle)hnd->ump_mem_handle); + if (hnd->base) + gralloc_unmap(module, handle); + + hnd->base = 0; + hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE; + hnd->lockState = 0; + hnd->writeOwner = 0; + } else { + LOGE("unregistering non-UMP buffer not supported"); + } + + hnd->base = 0; + hnd->lockState = 0; + hnd->writeOwner = 0; + + pthread_mutex_unlock(&s_map_lock); + } + + return 0; +} + +static int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, + int usage, int l, int t, int w, int h, void** vaddr) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("Locking invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { + hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; + + if (usage & GRALLOC_USAGE_SW_READ_MASK) + ump_cpu_msync_now(hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, + (void*)hnd->base, hnd->size); + } + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) + *vaddr = (void*)hnd->base; + + if (usage & GRALLOC_USAGE_YUV_ADDR) { + vaddr[0] = (void*)hnd->base; + vaddr[1] = (void*)(hnd->base + hnd->uoffset); + vaddr[2] = (void*)(hnd->base + hnd->uoffset + hnd->voffset); + } + return 0; +} + +static int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) { + LOGE("Unlocking invalid buffer, returning error"); + return -EINVAL; + } + + private_handle_t* hnd = (private_handle_t*)handle; + private_module_t* m = (private_module_t*)module; + int32_t current_value; + int32_t new_value; + int retry; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner) + ump_cpu_msync_now(hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, (void*)hnd->base, hnd->size); + else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + ion_msync(hnd->ion_client, hnd->fd, IMSYNC_DEV_TO_READ | IMSYNC_SYNC_FOR_DEV, hnd->size, hnd->offset); + + return 0; +} + +static struct hw_module_methods_t gralloc_module_methods = +{ + open: gralloc_device_open +}; + +struct private_module_t HAL_MODULE_INFO_SYM = +{ + base: + { + common: + { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: GRALLOC_HARDWARE_MODULE_ID, + name: "Graphics Memory Allocator Module", + author: "ARM Ltd.", + methods: &gralloc_module_methods, + dso: NULL, + reserved : {0,}, + }, + registerBuffer: gralloc_register_buffer, + unregisterBuffer: gralloc_unregister_buffer, + lock: gralloc_lock, + unlock: gralloc_unlock, + perform: NULL, + reserved_proc: {0,}, + }, + framebuffer: NULL, + flags: 0, + numBuffers: 0, + bufferMask: 0, + lock: PTHREAD_MUTEX_INITIALIZER, + currentBuffer: NULL, + ion_client: -1, +}; diff --git a/exynos5/hal/libhdmi/Android.mk b/exynos5/hal/libhdmi/Android.mk new file mode 100644 index 0000000..9acbc52 --- /dev/null +++ b/exynos5/hal/libhdmi/Android.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(all-subdir-makefiles) +endif diff --git a/exynos5/hal/libhdmi/SecHdmi/Android.mk b/exynos5/hal/libhdmi/SecHdmi/Android.mk new file mode 100644 index 0000000..61bd1a9 --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/Android.mk @@ -0,0 +1,76 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := libutils liblog libedid libcec + +LOCAL_SRC_FILES := \ + SecHdmiV4L2Utils.cpp \ + SecHdmi.cpp \ + SecGscaler.cpp \ + fimd_api.c + +LOCAL_C_INCLUDES += $(LOCAL_PATH) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include + +ifeq ($(TARGET_SOC),exynos5250) + LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250 +endif + +LOCAL_CFLAGS += \ + -DSCREEN_WIDTH=$(SCREEN_WIDTH) \ + -DSCREEN_HEIGHT=$(SCREEN_HEIGHT) \ + -DDEFAULT_FB_NUM=$(DEFAULT_FB_NUM) + +LOCAL_SHARED_LIBRARIES += libion + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +ifeq ($(BOARD_USES_HDMI_FIMGAPI),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_FIMGAPI + LOCAL_C_INCLUDES += device/samsung/$(TARGET_BOARD_PLATFORM)/libfimg4x + LOCAL_C_INCLUDES += external/skia/include/core + LOCAL_SHARED_LIBRARIES += libfimg +endif + +ifeq ($(BOARD_HDMI_STD), STD_NTSC_M) + LOCAL_CFLAGS += -DSTD_NTSC_M +endif + +ifeq ($(BOARD_HDMI_STD),STD_480P) + LOCAL_CFLAGS += -DSTD_480P +endif + +ifeq ($(BOARD_HDMI_STD),STD_720P) + LOCAL_CFLAGS += -DSTD_720P +endif + +ifeq ($(BOARD_HDMI_STD),STD_1080P) + LOCAL_CFLAGS += -DSTD_1080P +endif + +LOCAL_MODULE := libhdmi +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos5/hal/libhdmi/SecHdmi/SecGscaler.cpp b/exynos5/hal/libhdmi/SecHdmi/SecGscaler.cpp new file mode 100644 index 0000000..0a84d11 --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecGscaler.cpp @@ -0,0 +1,1524 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define DEBUG_LIB_FIMC +#define LOG_TAG "libgscaler" +//#define USE_GSC_USERPTR +#include +#include "../libhdmi/SecHdmi/SecGscaler.h" + +#ifdef USE_GSC_USERPTR +#define V4L2_MEMORY_TYPE V4L2_MEMORY_USERPTR +#else +#define V4L2_MEMORY_TYPE V4L2_MEMORY_MMAP +#endif + +struct yuv_fmt_list yuv_list[] = { + { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 1 }, + { "V4L2_PIX_FMT_NV12M", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12M, 12, 2 }, + { "V4L2_PIX_FMT_NV12MT", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12MT, 12, 2 }, + { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 1 }, + { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 }, + { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 }, + { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 }, + { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 }, + { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 }, + { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 }, + { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 }, + { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 }, + { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 }, + { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 }, + { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 }, + { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 }, + { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 }, +}; + +void dump_pixfmt_mp(struct v4l2_pix_format_mplane *pix_mp) +{ + LOGI("w: %d", pix_mp->width); + LOGI("h: %d", pix_mp->height); + LOGI("color: %x", pix_mp->colorspace); + + switch (pix_mp->pixelformat) { + case V4L2_PIX_FMT_YUYV: + LOGI ("YUYV"); + break; + case V4L2_PIX_FMT_UYVY: + LOGI ("UYVY"); + break; + case V4L2_PIX_FMT_RGB565: + LOGI ("RGB565"); + break; + case V4L2_PIX_FMT_RGB565X: + LOGI ("RGB565X"); + break; + default: + LOGI("not supported"); + } +} + +void dump_crop(struct v4l2_rect *rect) +{ + LOGI("crop l: %d", rect->left); + LOGI("crop t: %d", rect->top); + LOGI("crop w: %d", rect->width); + LOGI("crop h: %d", rect->height); +} + +void gsc_v4l2_dump_state(int fd) +{ + struct v4l2_format format; + struct v4l2_crop crop; + struct v4l2_subdev_crop sCrop; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (ioctl(fd, VIDIOC_G_FMT, &format) < 0) + return; + + LOGI("dumping driver state:"); + dump_pixfmt_mp(&format.fmt.pix_mp); + + crop.type = format.type; + if (ioctl(fd, VIDIOC_G_CROP, &crop) < 0) + return; + + LOGI("input image crop:"); + dump_crop(&(crop.c)); + + sCrop.pad = GSC_SUBDEV_PAD_SOURCE; + sCrop.which = V4L2_SUBDEV_FORMAT_ACTIVE; + if (ioctl(fd, VIDIOC_SUBDEV_G_CROP, &sCrop) < 0) + return; + + LOGI("output image crop:"); + dump_crop(&(sCrop.rect)); + +} + +int gsc_v4l2_querycap(int fd, char *node) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_capability v4l2cap; + + if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) { + LOGE("%s::VIDIOC_QUERYCAP failed", __func__); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("%s::%s is not support streaming", __func__, node); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) { + LOGE("%s::%s is not support video output mplane", __func__, node); + return -1; + } + + return 0; +} + +int gsc_v4l2_query_buf(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, int num_plane) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_GSCALER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_GSCALER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + if (MAX_BUFFERS_GSCALER <= buf_index || MAX_PLANES_GSCALER < num_plane) { + LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_plane); + return -1; + } + + buf.type = type; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_index; + buf.length = num_plane; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length); + return -1; + } + + for (int i = 0; i < num_plane; i++) { + if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) { + LOGE("%s::mmap failed", __func__); + LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset); + LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length); + LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + return -1; + } + secBuf->size.extS[i] = buf.m.planes[i].length; + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::vaddr[bufindex=%d][planeindex=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + LOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length); +#endif + } + + return 0; +} + +int gsc_v4l2_req_buf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_requestbuffers reqbuf; + + reqbuf.type = type; + reqbuf.memory = memory; + reqbuf.count = num_bufs; + +#ifdef DEBUG_LIB_FIMC + LOGI("%d buffers needed", reqbuf.count); +#endif + + if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { + LOGE("%s::VIDIOC_REQBUFS failed, reqbuf.count=%d", __func__, reqbuf.count); + return -1; + } + +#ifdef DEBUG_LIB_FIMC + LOGI("%d buffers allocated", reqbuf.count); +#endif + + if (reqbuf.count < num_bufs) { + LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))", + __func__, reqbuf.count, num_bufs); + return -1; + } + + return 0; +} + +int gsc_v4l2_s_ctrl(int fd, int id, int value) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_control vc; + + vc.id = id; + vc.value = value; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value); + return -1; + } + + return 0; +} + +int gsc_v4l2_set_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, s5p_fimc_img_info *img_info) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_format fmt; + struct v4l2_crop crop; + + fmt.type = type; +#ifdef DEBUG_LIB_FIMC + LOGD("%s::fmt.type=%d", __func__, fmt.type); +#endif + if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + return -1; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + fmt.fmt.pix.width = img_info->full_width; + fmt.fmt.pix.height = img_info->full_height; + fmt.fmt.pix.pixelformat = img_info->color_space; + fmt.fmt.pix.field = field; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt.fmt.pix_mp.width = img_info->full_width; + fmt.fmt.pix_mp.height = img_info->full_height; + fmt.fmt.pix_mp.pixelformat = img_info->color_space; + fmt.fmt.pix_mp.field = field; + fmt.fmt.pix_mp.num_planes = img_info->planes; + break; + default: + LOGE("%s::invalid buffer type", __func__); + return -1; + break; + } + +#ifdef DEBUG_LIB_FIMC +for (int i = 0; i < 3; i++) { + LOGD("%s::fmt.fmt.pix_mp. w=%d, h=%d, pixelformat=0x%08x, filed=%d, num_planes=%d", + __func__, + fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.field, + fmt.fmt.pix_mp.num_planes); +} +#endif + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_S_FMT failed", __func__); + return -1; + } + +#ifdef DEBUG_LIB_FIMC +for (int i = 0; i < 3; i++) { + LOGD("%s::pix_mp.pix_mp.plane_fmt[%d].sizeimage =0x%08x", __func__, i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage); + LOGD("%s::pix_mp.pix_mp.plane_fmt[%d].bytesperline=0x%08x", __func__, i, fmt.fmt.pix_mp.plane_fmt[i].bytesperline); +} +#endif + + crop.type = type; + crop.c.left = img_info->start_x; + crop.c.top = img_info->start_y; + crop.c.width = img_info->width; + crop.c.height = img_info->height; + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed", + __func__, + img_info->start_x, + img_info->start_y, + img_info->width, + img_info->height); + return -1; + } + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::pix_mp pixelformat=0x%08x", __func__, fmt.fmt.pix_mp.pixelformat); + LOGD("%s::pix_mp w=%d, h=%d, planes=%d", __func__, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.num_planes); + LOGD("%s::crop x=%d, y=%d, w=%d, h=%d", __func__, crop.c.left, crop.c.top, crop.c.width, crop.c.height); +#endif + + return 0; +} + +int gsc_v4l2_stream_on(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { + LOGE("%s::VIDIOC_STREAMON failed", __func__); + return -1; + } + + return 0; +} + +int gsc_v4l2_queue(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int index, int num_plane) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); + LOGD("%s::num_plane=%d", __func__, num_plane); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_GSCALER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_GSCALER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + buf.type = type; + buf.memory = memory; + buf.length = num_plane; + buf.index = index; + buf.m.planes = planes; + + for (unsigned int i = 0; i < buf.length; i++) { + buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i]; + buf.m.planes[i].length = secBuf->size.extS[i]; + buf.m.planes[i].bytesused = buf.m.planes[i].length; +#ifdef DEBUG_LIB_FIMC + LOGD("%s::buf.index=%d", __func__, buf.index); + LOGD("%s::buf.m.planes[%d].m.userptr=0x%08x", __func__, i, (unsigned int)buf.m.planes[i].m.userptr); + LOGD("%s::buf.m.planes[%d].length =0x%08x", __func__, i, buf.m.planes[i].length); + LOGD("%s::buf.m.planes[%d].bytesused=0x%08x", __func__, i, buf.m.planes[i].bytesused); +#endif + } + + if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QBUF failed", __func__); + return -1; + } + + return 0; +} + +int gsc_v4l2_dequeue(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int *index, int num_plane) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_GSCALER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_GSCALER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + + buf.type = type; + buf.memory = memory; + buf.length = num_plane; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { + LOGE("%s::VIDIOC_DQBUF failed", __func__); + return -1; + } + + *index = buf.index; + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::buf.index=%d", __func__, buf.index); +#endif + + return 0; +} + +int gsc_v4l2_stream_off(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { + LOGE("%s::VIDIOC_STREAMOFF failed", __func__); + return -1; + } + + return 0; +} + +int gsc_v4l2_clr_buf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_requestbuffers req; + + req.count = 0; + req.type = type; + req.memory = memory; + + if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { + LOGE("%s::VIDIOC_REQBUFS failed", __func__); + return -1; + } + + return 0; +} + +int gsc_subdev_set_fmt(int fd, unsigned int pad, enum v4l2_mbus_pixelcode code, s5p_fimc_img_info *img_info) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + struct v4l2_subdev_format fmt; + struct v4l2_subdev_crop crop; + + fmt.pad = pad; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.format.width = img_info->full_width; + fmt.format.height = img_info->full_height; + fmt.format.code = code; + + if (ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_FMT failed", __func__); + return -1; + } + + crop.pad = pad; + crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; + crop.rect.left = img_info->start_x; + crop.rect.top = img_info->start_y; + crop.rect.width = img_info->width; + crop.rect.height = img_info->height; + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::pix_mp w=%d, h=%d", __func__, fmt.format.width, fmt.format.height); + LOGD("%s::crop x=%d, y=%d, w=%d, h=%d", __func__, crop.rect.left, crop.rect.top, crop.rect.width, crop.rect.height); +#endif + + if (ioctl(fd, VIDIOC_SUBDEV_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_CROP failed", __func__); + return -1; + } + + return 0; +} + +static inline int multipleOfN(int number, int N) +{ + int result = number; + switch (N) { + case 1: + case 2: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + result = (number - (number & (N-1))); + break; + default: + result = number - (number % N); + break; + } + return result; +} + +SecGscaler::SecGscaler() +: mFlagCreate(false) +{ +} + +SecGscaler::~SecGscaler() +{ + if (mFlagCreate == true) { + LOGE("%s::this is not Destroyed fail", __func__); + + if (destroy() == false) + LOGE("%s::destroy failed", __func__); + } +} + +bool SecGscaler::create(enum DEV dev, enum MODE mode, unsigned int numOfBuf) +{ + create(dev, numOfBuf); + return true; +} + +bool SecGscaler::create(enum DEV dev, unsigned int numOfBuf) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + if (mFlagCreate == true) { + LOGE("%s::Already Created", __func__); + return true; + } + + char node[20]; + char subdevname[32]; + char videodevname[32]; + + struct v4l2_capability v4l2cap; + struct media_entity_desc entity_desc; + + mDev = dev; + mVideoNodeNum = dev; + mNumOfBuf = numOfBuf; + + mVideodevFd = 0; + mMediadevFd = 0; + mSubdevFd = 0; + + mSrcIndex = 0; + mRotVal = 0; + mFlagGlobalAlpha = false; + mGlobalAlpha = 0x0; + mFlagLocalAlpha = false; + mFlagColorKey = false; + mColorKey = 0x0; + mFlagSetSrcParam = false; + mFlagSetDstParam = false; + mFlagStreamOn = false; + + memset(&mS5pFimc, 0, sizeof(s5p_fimc_t)); + + switch(mDev) { + case DEV_0: + mVideoNodeNum = 24; + mSubdevNodeNum = 4; + break; + case DEV_1: + mVideoNodeNum = 27; + mSubdevNodeNum = 5; + break; + case DEV_2: + mVideoNodeNum = 30; + mSubdevNodeNum = 6; + break; + case DEV_3: + mVideoNodeNum = 33; + mSubdevNodeNum = 3; // need to modify //carrotsm + break; + default: + LOGE("%s::invalid mDev(%d)", __func__, mDev); + goto err; + break; + } + + sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0); + mMediadevFd = open(node, O_RDONLY); + + if (mMediadevFd < 0) { + LOGE("%s::open(%s) failed : O_RDONLY", __func__, node); + goto err; + } + + sprintf(subdevname, PFX_ENTITY_SUBDEV_GSC, mDev); + sprintf(videodevname, PFX_ENTITY_OUTPUTDEV_GSC, mDev); + + for (__u32 id = 0; ; id = entity_desc.id) { + entity_desc.id = id | MEDIA_ENT_ID_FLAG_NEXT; + + if (ioctl(mMediadevFd, MEDIA_IOC_ENUM_ENTITIES, &entity_desc) < 0) { + if (errno == EINVAL) { + LOGD("%s::MEDIA_IOC_ENUM_ENTITIES ended", __func__); + break; + } + LOGE("%s::MEDIA_IOC_ENUM_ENTITIES failed", __func__); + goto err; + } + +#ifdef DEBUG_LIB_FIMC + LOGD("%s::entity_desc.id=%d, .minor=%d .name=%s", __func__, entity_desc.id, entity_desc.v4l.minor, entity_desc.name); +#endif + + if (strncmp(entity_desc.name, subdevname, strlen(subdevname)) == 0) + mSubdevEntity = entity_desc.id; + + if (strncmp(entity_desc.name, videodevname, strlen(videodevname)) == 0) + mVideodevEntity = entity_desc.id; + } + + if (0 < mMediadevFd) + close(mMediadevFd); + mMediadevFd = -1; + + sprintf(node, "%s%d", PFX_NODE_SUBDEV, mSubdevNodeNum); + mSubdevFd = open(node, O_RDWR); + if (mSubdevFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto err; + } + + sprintf(node, "%s%d", PFX_NODE_VIDEODEV, mVideoNodeNum); + mVideodevFd = open(node, O_RDWR); + if (mVideodevFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto err; + } + + /* check capability */ + if (gsc_v4l2_querycap(mVideodevFd, node) < 0 ) { + LOGE("%s::tvout_std_v4l2_querycap failed", __func__); + goto err; + } + + mFlagCreate = true; + + return true; + +err : + if (0 < mVideodevFd) + close(mVideodevFd); + + if (0 < mMediadevFd) + close(mMediadevFd); + + if (0 < mSubdevFd) + close(mSubdevFd); + + mVideodevFd = -1; + mMediadevFd = -1; + mSubdevFd = -1; + + return false; +} + +bool SecGscaler::destroy() +{ + s5p_fimc_params_t *params = &(mS5pFimc.params); + + if (mFlagCreate == false) { + LOGE("%s::Already Destroyed", __func__); + return true; + } + + if (mFlagStreamOn == true) { + if (streamOff() == false) { + LOGE("%s::streamOff() failed", __func__); + return false; + } + + if (closeVideodevFd() == false) { + LOGE("%s::closeVideodevFd() failed", __func__); + return false; + } + + mFlagStreamOn = false; + } + + if (0 < mMediadevFd) + close(mMediadevFd); + + if (0 < mSubdevFd) + close(mSubdevFd); + + mVideodevFd = -1; + mMediadevFd = -1; + mSubdevFd = -1; + + mFlagCreate = false; + + return true; +} + +bool SecGscaler::flagCreate(void) +{ + return mFlagCreate; +} + +int SecGscaler::getFd(void) +{ + return getVideodevFd(); +} + +int SecGscaler::getVideodevFd(void) +{ + return mVideodevFd; +} + +bool SecGscaler::openVideodevFd(void) +{ + char node[32]; + + sprintf(node, "%s%d", PFX_NODE_VIDEODEV, mVideoNodeNum); + mVideodevFd = open(node, O_RDWR); + if (mVideodevFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + return false; + } + + return true; +} + +bool SecGscaler::closeVideodevFd(void) +{ + if (mFlagSetSrcParam == true) { + if (gsc_v4l2_clr_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE) < 0) { + LOGE("%s::gsc_v4l2_clr_buf() failed", __func__); + return false; + } + } + + if (0 < mVideodevFd) { + if (close(mVideodevFd) < 0) { + LOGE("%s::close Videodev failed", __func__); + return false; + } + } + mVideodevFd = -1; + + return true; +} + +int SecGscaler::getSubdevFd(void) +{ + return mSubdevFd; +} + +__u32 SecGscaler::getSubdevEntity(void) +{ + return mSubdevEntity; +} + +__u32 SecGscaler::getVideodevEntity(void) +{ + return mVideodevEntity; +} + +bool SecGscaler::getFlagSteamOn(void) +{ + return mFlagStreamOn; +} + +SecBuffer * SecGscaler::getSrcBufferAddr(int index) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + return &mSrcBuffer[index]; +} + +bool SecGscaler::setSrcParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(colorFormat); + if (v4l2ColorFormat < 0) { + LOGE("%s::not supported color format", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + + unsigned int fimcWidth = *cropWidth; + unsigned int fimcHeight = *cropHeight; + int src_planes = m_getYuvPlanes(v4l2ColorFormat); + int src_bpp = m_getYuvBpp(v4l2ColorFormat); + unsigned int frame_size = width * height; + unsigned int frame_ratio = 8; + + if (m_checkSrcSize(width, height, cropX, cropY, + &fimcWidth, &fimcHeight, v4l2ColorFormat, false) == false) { + LOGE("%s::::size align error!", __func__); + return false; + } + + if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) { + if (forceChange == true) { +#ifdef DEBUG_LIB_FIMC + LOGD("size is changed from [w=%d, h=%d] to [w=%d, h=%d]", + *cropWidth, *cropHeight, fimcWidth, fimcHeight); +#endif + } else { + LOGE("%s::invalid source params", __func__); + return false; + } + } + + if ( (params->src.full_width == width) + && (params->src.full_height == height) + && (params->src.start_x == cropX) + && (params->src.start_y == cropY) + && (params->src.width == fimcWidth) + && (params->src.height == fimcHeight) + && (params->src.color_space == (unsigned int)v4l2ColorFormat)) + return true; + + params->src.full_width = width; + params->src.full_height = height; + params->src.start_x = cropX; + params->src.start_y = cropY; + params->src.width = fimcWidth; + params->src.height = fimcHeight; + params->src.color_space = v4l2ColorFormat; + src_planes = (src_planes == -1) ? 1 : src_planes; + params->src.planes = src_planes; + + mSrcBuffer[mSrcIndex].size.extS[0] = 0; + mSrcBuffer[mSrcIndex].size.extS[1] = 0; + mSrcBuffer[mSrcIndex].size.extS[2] = 0; + + frame_ratio = frame_ratio * (src_planes -1) / (src_bpp - 8); +#ifdef USE_GSC_USERPTR + for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) { + switch (src_planes) { + case 1: + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_BGR32: + params->src.color_space = V4L2_PIX_FMT_RGB32; + case V4L2_PIX_FMT_RGB32: + mSrcBuffer[buf_index].size.extS[0] = frame_size << 2; + break; + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_YVYU: + mSrcBuffer[buf_index].size.extS[0] = frame_size << 1; + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + mSrcBuffer[buf_index].size.extS[0] = (frame_size * 3) >> 1; + break; + default: + LOGE("%s::invalid color type", __func__); + return false; + break; + } + mSrcBuffer[buf_index].size.extS[1] = 0; + mSrcBuffer[buf_index].size.extS[2] = 0; + break; + case 2: + case 3: + mSrcBuffer[buf_index].size.extS[0] = frame_size; + mSrcBuffer[buf_index].size.extS[1] = frame_size / frame_ratio; + mSrcBuffer[buf_index].size.extS[2] = frame_size / frame_ratio; + break; + default: + LOGE("%s::invalid color foarmt", __func__); + return false; + break; + } + } +#else + if (v4l2ColorFormat == V4L2_PIX_FMT_BGR32) + params->src.color_space = V4L2_PIX_FMT_RGB32; +#endif + + if (mFlagSetSrcParam == true) { + if (gsc_v4l2_clr_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE) < 0) { + LOGE("%s::gsc_v4l2_clr_buf() failed", __func__); + return false; + } + } + + if (gsc_v4l2_set_fmt(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_NONE, &(params->src)) < 0) { + LOGE("%s::fimc_v4l2_set_fmt()[src] failed", __func__); + return false; + } + + if (gsc_v4l2_req_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mNumOfBuf) < 0) { + LOGE("%s::fimc_v4l2_req_buf()[src] failed", __func__); + return false; + } +#ifdef USE_GSC_USERPTR +#else + for (unsigned int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) { + if (gsc_v4l2_query_buf(mVideodevFd, &mSrcBuffer[buf_index], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP, buf_index, params->src.planes) < 0) { + LOGE("%s::gsc_v4l2_query_buf() failed", __func__); + return false; + } + } +#endif + + *cropWidth = fimcWidth; + *cropHeight = fimcHeight; + + mFlagSetSrcParam = true; + + return true; +} + +bool SecGscaler::getSrcParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *v4l2colorFormat) +{ + struct v4l2_format fmt; + struct v4l2_crop crop; + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (ioctl(mVideodevFd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT(fmt.type : %d) failed", __func__, fmt.type); + return false; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + *width = fmt.fmt.pix.width; + *height = fmt.fmt.pix.height; + *v4l2colorFormat = fmt.fmt.pix.pixelformat; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + *width = fmt.fmt.pix_mp.width; + *height = fmt.fmt.pix_mp.height; + *v4l2colorFormat = fmt.fmt.pix_mp.pixelformat; + break; + default: + LOGE("%s::Invalid buffer type", __func__); + return false; + break; + } + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (ioctl(mVideodevFd, VIDIOC_G_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_G_CROP failed", __func__); + return false; + } + + *cropX = crop.c.left; + *cropY = crop.c.top; + *cropWidth = crop.c.width; + *cropHeight = crop.c.height; + + return true; +} + +bool SecGscaler::setSrcAddr(unsigned int YAddr, + unsigned int CbAddr, + unsigned int CrAddr, + int colorFormat) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagSetSrcParam == false) { + LOGE("%s::mFlagSetSrcParam == false", __func__); + return false; + } + +#ifdef USE_GSC_USERPTR + mSrcBuffer[mSrcIndex].virt.extP[0] = (char *)YAddr; + mSrcBuffer[mSrcIndex].virt.extP[1] = (char *)CbAddr; + mSrcBuffer[mSrcIndex].virt.extP[2] = (char *)CrAddr; +#else + unsigned int srcAddr[MAX_PLANES_GSCALER]; + + srcAddr[0] = YAddr; + srcAddr[1] = CbAddr; + srcAddr[2] = CrAddr; + + for (int plane_index = 0; plane_index < mS5pFimc.params.src.planes; plane_index++) { + memcpy((void *)mSrcBuffer[mSrcIndex].virt.extP[plane_index], (void *)srcAddr[plane_index], mSrcBuffer[mSrcIndex].size.extS[plane_index]); + } +#endif + + return true; +} + +bool SecGscaler::setDstParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + int mbusFormat = V4L2_MBUS_FMT_YUV8_1X24; + + s5p_fimc_params_t *params = &(mS5pFimc.params); + + unsigned int fimcWidth = *cropWidth; + unsigned int fimcHeight = *cropHeight; + + if( m_checkDstSize(width, height, cropX, cropY, + &fimcWidth, &fimcHeight, V4L2_PIX_FMT_YUV444, + mRotVal, true) == false) { + LOGE("%s::size align error!", __func__); + return false; + } + + + if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) { + if (forceChange == true) { +#ifdef DEBUG_LIB_FIMC + LOGD("size is changed from [w = %d, h= %d] to [w = %d, h = %d]", + *cropWidth, *cropHeight, fimcWidth, fimcHeight); +#endif + } else { + LOGE("%s::Invalid destination params", __func__); + return false; + } + } + + if (90 == mRotVal || 270 == mRotVal) { + params->dst.full_width = height; + params->dst.full_height = width; + + if (90 == mRotVal) { + params->dst.start_x = cropY; + params->dst.start_y = width - (cropX + fimcWidth); + } else { + params->dst.start_x = height - (cropY + fimcHeight); + params->dst.start_y = cropX; + } + + params->dst.width = fimcHeight; + params->dst.height = fimcWidth; + + params->dst.start_y += (fimcWidth - params->dst.height); + + } else { + params->dst.full_width = width; + params->dst.full_height = height; + + if (180 == mRotVal) { + params->dst.start_x = width - (cropX + fimcWidth); + params->dst.start_y = height - (cropY + fimcHeight); + } else { + params->dst.start_x = cropX; + params->dst.start_y = cropY; + } + + params->dst.width = fimcWidth; + params->dst.height = fimcHeight; + } + + if (gsc_subdev_set_fmt(mSubdevFd, GSC_SUBDEV_PAD_SOURCE, V4L2_MBUS_FMT_YUV8_1X24, &(params->dst)) < 0) { + LOGE("%s::gsc_subdev_set_fmt()[dst] failed", __func__); + return false; + } + + mFlagSetDstParam = true; + + return true; +} + +bool SecGscaler::getDstParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *mbusColorFormat) +{ + struct v4l2_subdev_format fmt; + struct v4l2_subdev_crop crop; + + fmt.pad = GSC_SUBDEV_PAD_SOURCE; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + if (ioctl(mSubdevFd, VIDIOC_SUBDEV_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_FMT", __func__); + return -1; + } + + *width = fmt.format.width; + *height = fmt.format.height; + *mbusColorFormat = fmt.format.code; + + crop.pad = GSC_SUBDEV_PAD_SOURCE; + crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + if (ioctl(mSubdevFd, VIDIOC_SUBDEV_G_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_CROP", __func__); + return -1; + } + + *cropX = crop.rect.left; + *cropY = crop.rect.top; + *cropWidth = crop.rect.width; + *cropHeight = crop.rect.height; + + return true; +} + +bool SecGscaler::setDstAddr(unsigned int YAddr, unsigned int CbAddr, unsigned int CrAddr, int buf_index) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + return true; +} + +bool SecGscaler::setRotVal(unsigned int rotVal) +{ + struct v4l2_control vc; + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (gsc_v4l2_s_ctrl(mVideodevFd, V4L2_CID_ROTATE, rotVal) < 0) { + LOGE("%s::fimc_v4l2_s_ctrl(V4L2_CID_ROTATE) failed", __func__); + return false; + } + + mRotVal = rotVal; + return true; +} + +bool SecGscaler::setGlobalAlpha(bool enable, int alpha) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + mFlagGlobalAlpha = enable; + mGlobalAlpha = alpha; + + return true; + +} + +bool SecGscaler::setLocalAlpha(bool enable) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + if (mFlagLocalAlpha == enable) + return true; + + return true; +} + +bool SecGscaler::setColorKey(bool enable, int colorKey) +{ + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::mFlagStreamOn == true", __func__); + return false; + } + + mFlagColorKey = enable; + mColorKey = colorKey; + + return true; +} + +bool SecGscaler::run() +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagSetSrcParam == false) { + LOGE("%s::faild : Need to set source parameters of Gscaler", __func__); + return false; + } + + if (mFlagSetDstParam == false) { + LOGE("%s::faild : Need to set destination parameters of Gscaler", __func__); + return false; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + int src_planes = m_getYuvPlanes(params->src.color_space); + unsigned int dqIndex = 0; + src_planes = (src_planes == -1) ? 1 : src_planes; + + if (gsc_v4l2_queue(mVideodevFd, &(mSrcBuffer[mSrcIndex]), V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mSrcIndex, src_planes) < 0) { + LOGE("%s::fimc_v4l2_queue[src](mNumOfBuf : %d,mSrcIndex=%d) failed", __func__, mNumOfBuf, mSrcIndex); + return false; + } + + mSrcIndex++; + if (mSrcIndex >= MAX_BUFFERS_GSCALER) { + mSrcIndex = 0; + } + + if (gsc_v4l2_dequeue(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, &dqIndex, src_planes) < 0) { + LOGE("%s::fimc_v4l2_dequeue[src](mNumOfBuf : %d, dqIndex=%d) failed", __func__, mNumOfBuf, dqIndex); + return false; + } + + return true; +} + +bool SecGscaler::streamOn(void) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == true) { + LOGE("%s::already streamon", __func__); + return true; + } + + s5p_fimc_params_t *params = &(mS5pFimc.params); + int src_planes = m_getYuvPlanes(params->src.color_space); + src_planes = (src_planes == -1) ? 1 : src_planes; + + if (gsc_v4l2_queue(mVideodevFd, &(mSrcBuffer[mSrcIndex]), V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mSrcIndex, src_planes) < 0) { + LOGE("%s::fimc_v4l2_queue[src](mNumOfBuf : %d,mSrcIndex=%d) failed", __func__, mNumOfBuf, mSrcIndex); + return false; + } + + mSrcIndex++; + if (mSrcIndex == MAX_BUFFERS_GSCALER - 1) { + if (gsc_v4l2_stream_on(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::fimc_v4l2_stream_on() failed", __func__); + return false; + } + mFlagStreamOn = true; + } + + if (mSrcIndex >= MAX_BUFFERS_GSCALER) { + mSrcIndex = 0; + } + + return true; +} + +bool SecGscaler::streamOff(void) +{ +#ifdef DEBUG_LIB_FIMC + LOGD("%s", __func__); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagStreamOn == false) { + LOGE("%s::already streamoff", __func__); + return true; + } + + if (gsc_v4l2_stream_off(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::fimc_v4l2_stream_off() failed", __func__); + return false; + } + + mSrcIndex = 0; +#ifdef USE_GSC_USERPTR + SecBuffer zeroBuf; + for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) + mSrcBuffer[buf_index] = zeroBuf; +#else + for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) { + for (int plane_index = 0; plane_index < MAX_PLANES_GSCALER; plane_index++) { + munmap((void *)mSrcBuffer[buf_index].virt.extP[plane_index], mSrcBuffer[buf_index].size.extS[plane_index]); + } + } +#endif + + mFlagStreamOn = false; + + return true; +} + +bool SecGscaler::m_checkSrcSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange) +{ + bool ret = true; + + if (8 <= height && *cropHeight < 8) { + if (forceChange) + *cropHeight = 8; + ret = false; + } + + if (16 <= width && *cropWidth < 16) { + if (forceChange) + *cropWidth = 16; + ret = false; + } + + if (height < 8) + return false; + + if (width % 16 != 0) + return false; + + if (*cropWidth % 16 != 0) { + if (forceChange) + *cropWidth = multipleOfN(*cropWidth, 16); + ret = false; + } + + return ret; +} + +bool SecGscaler::m_checkDstSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, int rotVal, bool forceChange) +{ + bool ret = true; + unsigned int rotWidth; + unsigned int rotHeight; + unsigned int *rotCropWidth; + unsigned int *rotCropHeight; + + if (rotVal == 90 || rotVal == 270) { + rotWidth = height; + rotHeight = width; + rotCropWidth = cropHeight; + rotCropHeight = cropWidth; + } else { + rotWidth = width; + rotHeight = height; + rotCropWidth = cropWidth; + rotCropHeight = cropHeight; + } + + if (rotHeight < 8) + return false; + + if (rotWidth % 8 != 0) + return false; + + switch (colorFormat) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_YUV420M: + case V4L2_PIX_FMT_YUV420: + if (*rotCropHeight % 2 != 0) { + if (forceChange) + *rotCropHeight = multipleOfN(*rotCropHeight, 2); + ret = false; + } + } + return ret; +} + +int SecGscaler::m_widthOfFimc(int v4l2ColorFormat, int width) +{ + int newWidth = width; + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_RGB565: + newWidth = multipleOfN(width, 8); + break; + case V4L2_PIX_FMT_RGB32: + newWidth = multipleOfN(width, 4); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + newWidth = multipleOfN(width, 4); + break; + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + newWidth = multipleOfN(width, 8); + break; + case V4L2_PIX_FMT_YUV422P: + newWidth = multipleOfN(width, 16); + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12MT: + newWidth = multipleOfN(width, 8); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV420M: + newWidth = multipleOfN(width, 16); + break; + default : + break; + } + + return newWidth; +} + +int SecGscaler::m_heightOfFimc(int v4l2ColorFormat, int height) +{ + int newHeight = height; + + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV12MT: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV420M: + newHeight = multipleOfN(height, 2); + break; + default : + break; + } + return newHeight; +} + +int SecGscaler::m_getYuvBpp(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].bpp; +} + +int SecGscaler::m_getYuvPlanes(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].planes; +} diff --git a/exynos5/hal/libhdmi/SecHdmi/SecGscaler.h b/exynos5/hal/libhdmi/SecHdmi/SecGscaler.h new file mode 100644 index 0000000..e9867ed --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecGscaler.h @@ -0,0 +1,195 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SEC_GSC_OUT_H__ +#define __SEC_GSC_OUT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "utils/Timers.h" + +#include "s5p_fimc_v4l2.h" +#include "sec_utils_v4l2.h" +#include "media.h" +#include "v4l2-subdev.h" + +#include "sec_format.h" + +#include "SecBuffer.h" + +#define PFX_NODE_MEDIADEV "/dev/media" +#define PFX_NODE_SUBDEV "/dev/v4l-subdev" +#define PFX_NODE_VIDEODEV "/dev/video" +#define PFX_ENTITY_SUBDEV_GSC "exynos-gsc-sd.%d" +#define PFX_ENTITY_OUTPUTDEV_GSC "exynos-gsc.%d.output" + +#define GSC_SUBDEV_PAD_SINK (0) +#define GSC_SUBDEV_PAD_SOURCE (1) +#define GSC_VIDEODEV_PAD_SOURCE (0) +#define MAX_BUFFERS_GSCALER (2) +#define MAX_PLANES_GSCALER (3) + +#ifdef __cplusplus +} + +class SecGscaler +{ +public: + enum DEV { + DEV_0 = 0, + DEV_1, + DEV_2, + DEV_3, + DEV_MAX, + }; + + enum MODE { + MODE_NONE = 0, + MODE_SINGLE_BUF, + MODE_MULTI_BUF, + MODE_DMA_AUTO, + MODE_MAX, + }; + +private: + bool mFlagCreate; + int mDev; + int mVideoNodeNum; + int mSubdevNodeNum; + int mVideodevFd; + int mMediadevFd; + int mSubdevFd; + unsigned int mNumOfBuf; + unsigned int mSrcIndex; + int mRotVal; + bool mFlagGlobalAlpha; + int mGlobalAlpha; + bool mFlagLocalAlpha; + bool mFlagColorKey; + int mColorKey; + bool mFlagSetSrcParam; + bool mFlagSetDstParam; + bool mFlagStreamOn; + + s5p_fimc_t mS5pFimc; + SecBuffer mSrcBuffer[MAX_BUFFERS_GSCALER]; + + __u32 mSubdevEntity; + __u32 mVideodevEntity; + //struct media_link_desc mlink_desc; + +public: + SecGscaler(); + virtual ~SecGscaler(); + + bool create(enum DEV dev, enum MODE mode, unsigned int numOfBuf); + bool create(enum DEV dev, unsigned int numOfBuf); + + bool destroy(void); + bool flagCreate(void); + + int getFd(void); + int getVideodevFd(void); + bool openVideodevFd(void); + bool closeVideodevFd(void); + + int getSubdevFd(void); + __u32 getSubdevEntity(void); + __u32 getVideodevEntity(void); + bool getFlagSteamOn(void); + + SecBuffer * getSrcBufferAddr(int index); + + bool setSrcParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = true); + + bool getSrcParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *v4l2colorFormat); + + bool setSrcAddr(unsigned int YAddr, + unsigned int CbAddr = 0, + unsigned int CrAddr = 0, + int colorFormat = 0); + + bool setDstParams(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = true); + + bool getDstParams(unsigned int *width, unsigned int *height, + unsigned int *cropX, unsigned int *cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int *mbusColorFormat); + + bool setDstAddr(unsigned int YAddr, + unsigned int CbAddr = 0, + unsigned int CrAddr = 0, + int buf_index = 0); + + bool setRotVal(unsigned int rotVal); + bool setGlobalAlpha(bool enable = true, int alpha = 0xff); + bool setLocalAlpha(bool enable); + bool setColorKey(bool enable = true, int colorKey = 0xff); + + bool run(void); + bool streamOn(void); + bool streamOff(void); + +private: + bool m_checkSrcSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + bool forceChange = false); + + bool m_checkDstSize(unsigned int width, unsigned int height, + unsigned int cropX, unsigned int cropY, + unsigned int *cropWidth, unsigned int *cropHeight, + int colorFormat, + int rotVal, + bool forceChange = false); + int m_widthOfFimc(int v4l2ColorFormat, int width); + int m_heightOfFimc(int v4l2ColorFormat, int height); + int m_getYuvBpp(unsigned int fmt); + int m_getYuvPlanes(unsigned int fmt); +}; +#endif + +#endif //__SEC_GSC_OUT_H__ diff --git a/exynos5/hal/libhdmi/SecHdmi/SecHdmi.cpp b/exynos5/hal/libhdmi/SecHdmi/SecHdmi.cpp new file mode 100644 index 0000000..8f0f80b --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecHdmi.cpp @@ -0,0 +1,1985 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define DEBUG_MSG_ENABLE +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#include +#include "ion.h" +#include "SecHdmi.h" +#include "SecHdmiV4L2Utils.h" + +#define CHECK_GRAPHIC_LAYER_TIME (0) + +namespace android { + +extern unsigned int output_type; +extern v4l2_std_id t_std_id; +extern int g_hpd_state; +extern unsigned int g_hdcp_en; + +#if defined(BOARD_USES_HDMI_FIMGAPI) +extern unsigned int g2d_reserved_memory0; +extern unsigned int g2d_reserved_memory1; +extern unsigned int g2d_reserved_memory_size; +extern unsigned int cur_g2d_address; +#endif + +#if defined(BOARD_USES_CEC) +SecHdmi::CECThread::~CECThread() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + mFlagRunning = false; +} + +bool SecHdmi::CECThread::threadLoop() +{ + unsigned char buffer[CEC_MAX_FRAME_SIZE]; + int size; + unsigned char lsrc, ldst, opcode; + + { + Mutex::Autolock lock(mThreadLoopLock); + mFlagRunning = true; + + size = CECReceiveMessage(buffer, CEC_MAX_FRAME_SIZE, 100000); + + if (!size) // no data available or ctrl-c + return true; + + if (size == 1) + return true; // "Polling Message" + + lsrc = buffer[0] >> 4; + + /* ignore messages with src address == mLaddr*/ + if (lsrc == mLaddr) + return true; + + opcode = buffer[1]; + + if (CECIgnoreMessage(opcode, lsrc)) { + LOGE("### ignore message coming from address 15 (unregistered)\n"); + return true; + } + + if (!CECCheckMessageSize(opcode, size)) { + LOGE("### invalid message size: %d(opcode: 0x%x) ###\n", size, opcode); + return true; + } + + /* check if message broadcasted/directly addressed */ + if (!CECCheckMessageMode(opcode, (buffer[0] & 0x0F) == CEC_MSG_BROADCAST ? 1 : 0)) { + LOGE("### invalid message mode (directly addressed/broadcast) ###\n"); + return true; + } + + ldst = lsrc; + + //TODO: macroses to extract src and dst logical addresses + //TODO: macros to extract opcode + + switch (opcode) { + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + /* responce with "Report Physical Address" */ + buffer[0] = (mLaddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS; + buffer[2] = (mPaddr >> 8) & 0xFF; + buffer[3] = mPaddr & 0xFF; + buffer[4] = mDevtype; + size = 5; + break; + + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + LOGD("[CEC_OPCODE_REQUEST_ACTIVE_SOURCE]\n"); + /* responce with "Active Source" */ + buffer[0] = (mLaddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_ACTIVE_SOURCE; + buffer[2] = (mPaddr >> 8) & 0xFF; + buffer[3] = mPaddr & 0xFF; + size = 4; + LOGD("Tx : [CEC_OPCODE_ACTIVE_SOURCE]\n"); + break; + + case CEC_OPCODE_ABORT: + case CEC_OPCODE_FEATURE_ABORT: + default: + /* send "Feature Abort" */ + buffer[0] = (mLaddr << 4) | ldst; + buffer[1] = CEC_OPCODE_FEATURE_ABORT; + buffer[2] = CEC_OPCODE_ABORT; + buffer[3] = 0x04; // "refused" + size = 4; + break; + } + + if (CECSendMessage(buffer, size) != size) + LOGE("CECSendMessage() failed!!!\n"); + + } + return true; +} + +bool SecHdmi::CECThread::start() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mThreadControlLock); + if (exitPending()) { + if (requestExitAndWait() == WOULD_BLOCK) { + LOGE("mCECThread.requestExitAndWait() == WOULD_BLOCK"); + return false; + } + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("EDIDGetCECPhysicalAddress"); +#endif + /* set to not valid physical address */ + mPaddr = CEC_NOT_VALID_PHYSICAL_ADDRESS; + + if (!EDIDGetCECPhysicalAddress(&mPaddr)) { + LOGE("Error: EDIDGetCECPhysicalAddress() failed.\n"); + return false; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("CECOpen"); +#endif + if (!CECOpen()) { + LOGE("CECOpen() failed!!!\n"); + return false; + } + + /* a logical address should only be allocated when a device \ + has a valid physical address, at all other times a device \ + should take the 'Unregistered' logical address (15) + */ + + /* if physical address is not valid device should take \ + the 'Unregistered' logical address (15) + */ + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("CECAllocLogicalAddress"); +#endif + mLaddr = CECAllocLogicalAddress(mPaddr, mDevtype); + + if (!mLaddr) { + LOGE("CECAllocLogicalAddress() failed!!!\n"); + if (!CECClose()) + LOGE("CECClose() failed!\n"); + return false; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("request to run CECThread"); +#endif + + status_t ret = run("SecHdmi::CECThread", PRIORITY_DISPLAY); + if (ret != NO_ERROR) { + LOGE("%s fail to run thread", __func__); + return false; + } + return true; +} + +bool SecHdmi::CECThread::stop() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s request Exit", __func__); +#endif + Mutex::Autolock lock(mThreadControlLock); + if (requestExitAndWait() == WOULD_BLOCK) { + LOGE("mCECThread.requestExitAndWait() == WOULD_BLOCK"); + return false; + } + + if (!CECClose()) + LOGE("CECClose() failed!\n"); + + mFlagRunning = false; + return true; +} +#endif + +SecHdmi::SecHdmi(): +#if defined(BOARD_USES_CEC) + mCECThread(NULL), +#endif + mFlagCreate(false), + mFlagConnected(false), + mPreviousHdmiPresetId(V4L2_DV_1080P60), + mHdmiDstWidth(0), + mHdmiDstHeight(0), + mHdmiSrcYAddr(0), + mHdmiSrcCbCrAddr(0), + mFBaddr(0), + mFBsize(0), + mFBionfd(-1), + mFBoffset(0), + mHdmiOutputMode(DEFAULT_OUPUT_MODE), + mHdmiResolutionValue(DEFAULT_HDMI_RESOLUTION_VALUE), // V4L2_STD_480P_60_4_3 + mHdmiStdId(DEFAULT_HDMI_STD_ID), // V4L2_STD_480P_60_4_3 + mCompositeStd(DEFAULT_COMPOSITE_STD), + mHdcpMode(false), + mAudioMode(2), + mUIRotVal(0), + mG2DUIRotVal(0), + mCurrentHdmiOutputMode(-1), + mCurrentHdmiResolutionValue(0), // 1080960 + mCurrentHdcpMode(false), + mCurrentAudioMode(-1), + mHdmiInfoChange(true), + mFlagGscalerStart(false), + mGscalerDstColorFormat(0), + mDefaultFBFd(-1), + mCurrentsrcW(0), + mCurrentsrcH(0), + mCurrentsrcColorFormat(0), + mCurrentsrcYAddr(0), + mCurrentsrcCbAddr(0), + mCurrentdstX(0), + mCurrentdstY(0), + mCurrenthdmiLayer(0), + mCurrentNumOfHWCLayer(0), + mDisplayWidth(DEFALULT_DISPLAY_WIDTH), + mDisplayHeight(DEFALULT_DISPLAY_HEIGHT) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + for (int i = 0; i < HDMI_LAYER_MAX; i++) { + mFlagLayerEnable[i] = false; + mFlagHdmiStart[i] = false; + + mSrcWidth [i] = 0; + mSrcHeight [i] = 0; + mSrcColorFormat[i] = 0; + mHdmiResolutionWidth [i] = 0; + mHdmiResolutionHeight [i] = 0; + mPreviousNumofHwLayer [i] = 0; + mSrcIndex[i] = 0; + } + + //All layer is on + mFlagLayerEnable[HDMI_LAYER_VIDEO] = true; + mFlagLayerEnable[HDMI_LAYER_GRAPHIC_0] = true; + mFlagLayerEnable[HDMI_LAYER_GRAPHIC_1] = true; + + mHdmiSizeOfResolutionValueList = 14; + + mHdmiResolutionValueList[0] = 1080960; + mHdmiResolutionValueList[1] = 1080950; + mHdmiResolutionValueList[2] = 1080930; + mHdmiResolutionValueList[3] = 1080924; + mHdmiResolutionValueList[4] = 1080160; + mHdmiResolutionValueList[5] = 1080150; + mHdmiResolutionValueList[6] = 720960; + mHdmiResolutionValueList[7] = 7209601; + mHdmiResolutionValueList[8] = 720950; + mHdmiResolutionValueList[9] = 7209501; + mHdmiResolutionValueList[10] = 5769501; + mHdmiResolutionValueList[11] = 5769502; + mHdmiResolutionValueList[12] = 4809601; + mHdmiResolutionValueList[13] = 4809602; + +#if defined(BOARD_USES_CEC) + mCECThread = new CECThread(this); +#endif + + mGscalerForceUpdate = false; +} + +SecHdmi::~SecHdmi() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (mFlagCreate == true) + LOGE("%s::this is not Destroyed fail", __func__); + else + disconnect(); +} + +bool SecHdmi::create(int width, int height) +{ + Mutex::Autolock lock(mLock); + unsigned int fimc_buf_size = 0; + int stride; + int vstride; + + int ionfd_G2D = 0; + void * ion_base_addr = NULL; + + struct s3c_fb_user_ion_client ion_handle; + unsigned int FB_size = ALIGN(width, 16) * ALIGN(height, 16) * HDMI_G2D_BUFFER_BPP_SIZE * 2; + int ionfd_FB = 0; + +/* + * Video plaback (I420): output buffer size of FIMC3 is (1920 x 1088 x 1.5) + * Video plaback (NV12): FIMC3 is not used. + * Camera preview (YV12): output buffer size of FIMC3 is (640 x 480 x 1.5) + * UI mode (ARGB8888) : output buffer size of FIMC3 is (480 x 800 x 1.5) + */ +#ifndef SUPPORT_1080P_FIMC_OUT + setDisplaySize(width, height); +#endif + + stride = ALIGN(HDMI_MAX_WIDTH, 16); + vstride = ALIGN(HDMI_MAX_HEIGHT, 16); + + fimc_buf_size = stride * vstride * HDMI_FIMC_BUFFER_BPP_SIZE; +#if defined(BOARD_USES_HDMI_FIMGAPI) + g2d_reserved_memory_size = stride * vstride * HDMI_G2D_BUFFER_BPP_SIZE; +#endif + +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (mFlagCreate == true) { + LOGE("%s::Already Created", __func__); + return true; + } + + if (mDefaultFBFd <= 0) { + if ((mDefaultFBFd = fb_open(DEFAULT_FB)) < 0) { + LOGE("%s:Failed to open default FB", __func__); + return false; + } + } + + if (mSecGscaler.create(SecGscaler::DEV_3, MAX_BUFFERS_GSCALER) == false) { + LOGE("%s::SecGscaler create() failed", __func__); + goto CREATE_FAIL; + } + + mIonClient = ion_client_create(); + if (mIonClient < 0) { + mIonClient = -1; + LOGE("%s::ion_client_create() failed", __func__); + goto CREATE_FAIL; + } + + // get framebuffer virtual address for LCD + if (ioctl(mDefaultFBFd, S3CFB_GET_ION_USER_HANDLE, &ion_handle) == -1) { + LOGE("%s:ioctl(S3CFB_GET_ION_USER_HANDLE) failed", __func__); + return false; + } + + mFBaddr = (unsigned int)ion_map(ion_handle.fd, ALIGN(FB_size, PAGE_SIZE), 0); + mFBsize = FB_size; + mFBionfd = ion_handle.fd; + +#if defined(BOARD_USES_HDMI_FIMGAPI) + ionfd_G2D = ion_alloc(mIonClient, ALIGN(g2d_reserved_memory_size * 2, PAGE_SIZE), 0, ION_HEAP_EXYNOS_MASK); + + if (ionfd_G2D < 0) { + LOGE("%s::ION memory allocation failed", __func__); + } else { + ion_base_addr = ion_map(ionfd_G2D, ALIGN(g2d_reserved_memory_size * 2, PAGE_SIZE), 0); + if (ion_base_addr == MAP_FAILED) + LOGE("%s::ION mmap failed", __func__); + } + + g2d_reserved_memory0 = (unsigned int)ion_base_addr; + g2d_reserved_memory1 = g2d_reserved_memory0 + g2d_reserved_memory_size; +#endif + + v4l2_std_id std_id; + __u32 preset_id; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::mHdmiOutputMode(%d) \n", __func__, mHdmiOutputMode); +#endif + if (mHdmiOutputMode == COMPOSITE_OUTPUT_MODE) { + std_id = composite_std_2_v4l2_std_id(mCompositeStd); + if ((int)std_id < 0) { + LOGE("%s::composite_std_2_v4l2_std_id(%d) fail\n", __func__, mCompositeStd); + goto CREATE_FAIL; + } + if (m_setCompositeResolution(mCompositeStd) == false) { + LOGE("%s::m_setCompositeResolution(%d) fail\n", __func__, mCompositeStd); + goto CREATE_FAIL; + } + } else if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (hdmi_resolution_2_std_id(mHdmiResolutionValue, &mHdmiDstWidth, &mHdmiDstHeight, &std_id, &preset_id) < 0) { + LOGE("%s::hdmi_resolution_2_std_id(%d) fail\n", __func__, mHdmiResolutionValue); + goto CREATE_FAIL; + } + } + + if (m_setupLink() == false) { + LOGE("%s:Enable the link failed", __func__); + return false; + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (m_openLayer(layer) == false) + LOGE("%s::hdmi_init_layer(%d) failed", __func__, layer); + } + + for (int layer = HDMI_LAYER_BASE + 2; layer < HDMI_LAYER_MAX; layer++) { + if (tvout_std_v4l2_s_ctrl(mVideodevFd[layer], V4L2_CID_TV_LAYER_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ENABLE) failed", __func__, layer); + return false; + } + + if (tvout_std_v4l2_s_ctrl(mVideodevFd[layer], V4L2_CID_TV_PIXEL_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ENABLE) failed", __func__, layer); + return false; + } + + if (tvout_std_v4l2_s_ctrl(mVideodevFd[layer], V4L2_CID_TV_LAYER_BLEND_ALPHA, 255) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ALPHA) failed", __func__, layer); + return false; + } + } + + mFlagCreate = true; + + return true; + +CREATE_FAIL : + + if (mSecGscaler.flagCreate() == true && + mSecGscaler.destroy() == false) + LOGE("%s::Gscaler destory failed", __func__); + + return false; +} + +bool SecHdmi::destroy(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + char node[32]; + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Already Destroyed fail \n", __func__); + goto DESTROY_FAIL; + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (mFlagHdmiStart[layer] == true && m_stopHdmi(layer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail \n", __func__, layer); + goto DESTROY_FAIL; + } + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (m_closeLayer(layer) == false) + LOGE("%s::hdmi_deinit_layer(%d) failed", __func__, layer); + } + + if (mSecGscaler.flagCreate() == true && mSecGscaler.destroy() == false) { + LOGE("%s::fimc destory fail \n", __func__); + goto DESTROY_FAIL; + } + +#ifdef USE_LCD_ADDR_IN_HERE + { + if (0 < mDefaultFBFd) { + close(mDefaultFBFd); + mDefaultFBFd = -1; + } + } +#endif //USE_LCD_ADDR_IN_HERE + +#if defined(BOARD_USES_HDMI_FIMGAPI) + ion_unmap((void *)g2d_reserved_memory0, ALIGN(g2d_reserved_memory_size * 2, PAGE_SIZE)); +#endif + + if (0 < mFBaddr) + ion_unmap((void *)mFBaddr, ALIGN(mFBsize, PAGE_SIZE)); + + if (0 < mFBionfd) + ion_free(mFBionfd); + + sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0); + mMediadevFd = open(node, O_RDONLY); + + if (mMediadevFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto DESTROY_FAIL; + } + + mlink_desc.flags = 0; + if (ioctl(mMediadevFd, MEDIA_IOC_SETUP_LINK, &mlink_desc) < 0) { + LOGE("%s::MEDIA_IOC_SETUP_UNLINK failed", __func__); + goto DESTROY_FAIL; + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (m_closeLayer(layer) == false) + LOGE("%s::hdmi_deinit_layer(%d) failed", __func__, layer); + } + + if (0 < mMediadevFd) + close(mMediadevFd); + + if (0 < mSubdevMixerFd) + close(mSubdevMixerFd); + + mMediadevFd = -1; + mSubdevMixerFd = -1; + + mFlagCreate = false; + + return true; + +DESTROY_FAIL : + + return false; +} + +bool SecHdmi::connect(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + { + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (mFlagConnected == true) { + LOGD("%s::Already Connected.. \n", __func__); + return true; + } + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (m_flagHWConnected() == false) { + LOGD("%s::m_flagHWConnected() fail \n", __func__); + return false; + } + +#if defined(BOARD_USES_EDID) + if (!EDIDOpen()) + LOGE("EDIDInit() failed!\n"); + + if (!EDIDRead()) { + LOGE("EDIDRead() failed!\n"); + if (!EDIDClose()) + LOGE("EDIDClose() failed!\n"); + } +#endif + +#if defined(BOARD_USES_CEC) + if (!(mCECThread->mFlagRunning)) + mCECThread->start(); +#endif + } + } + + if (this->setHdmiOutputMode(mHdmiOutputMode, true) == false) + LOGE("%s::setHdmiOutputMode(%d) fail \n", __func__, mHdmiOutputMode); + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (this->setHdmiResolution(mHdmiResolutionValue, true) == false) + LOGE("%s::setHdmiResolution(%d) fail \n", __func__, mHdmiResolutionValue); + + if (this->setHdcpMode(mHdcpMode, false) == false) + LOGE("%s::setHdcpMode(%d) fail \n", __func__, mHdcpMode); + +/* if (this->m_setAudioMode(mAudioMode) == false) + LOGE("%s::m_setAudioMode(%d) fail \n", __func__, mAudioMode); +*/ + mHdmiInfoChange = true; + mFlagConnected = true; + +#if defined(BOARD_USES_EDID) + display_menu(); +#endif + } + + return true; +} + +bool SecHdmi::disconnect(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (mFlagConnected == false) { + LOGE("%s::Already Disconnected.. \n", __func__); + return true; + } + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USES_CEC) + if (mCECThread->mFlagRunning) + mCECThread->stop(); +#endif + +#if defined(BOARD_USES_EDID) + if (!EDIDClose()) { + LOGE("EDIDClose() failed!\n"); + return false; + } +#endif + } + + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (mFlagHdmiStart[layer] == true && m_stopHdmi(layer) == false) { + LOGE("%s::hdmiLayer(%d) layer fail \n", __func__, layer); + return false; + } + } + + mFlagConnected = false; + mPreviousHdmiPresetId = V4L2_DV_1080P60; + + mHdmiOutputMode = DEFAULT_OUPUT_MODE; + mHdmiResolutionValue = DEFAULT_HDMI_RESOLUTION_VALUE; + mHdmiStdId = DEFAULT_HDMI_STD_ID; + mCompositeStd = DEFAULT_COMPOSITE_STD; + mAudioMode = 2; + mCurrentHdmiOutputMode = -1; + mCurrentHdmiResolutionValue = 0; + mCurrentAudioMode = -1; + + return true; +} + +bool SecHdmi::startHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + if (mFlagHdmiStart[hdmiLayer] == false && + m_startHdmi(hdmiLayer) == false) { + LOGE("%s::hdmiLayer(%d) fail \n", __func__, hdmiLayer); + return false; + } + return true; +} + +bool SecHdmi::stopHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + if (mFlagHdmiStart[hdmiLayer] == true && + m_stopHdmi(hdmiLayer) == false) { + LOGE("%s::hdmiLayer(%d) layer fail \n", __func__, hdmiLayer); + return false; + } + tvout_deinit(); + return true; +} + +bool SecHdmi::flagConnected(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + return mFlagConnected; +} + +bool SecHdmi::flush(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, unsigned int srcCrAddr, + int dstX, int dstY, + int hdmiLayer, + int num_of_hwc_layer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer=%d", __func__, hdmiLayer); +#endif + + Mutex::Autolock lock(mLock); + +#ifdef DEBUG_MSG_ENABLE + LOGD("%s [srcW = %d, srcH = %d, srcColorFormat = 0x%x, srcYAddr= 0x%x, srcCbAddr = 0x%x, srcCrAddr = 0x%x, dstX = %d, dstY = %d, hdmiLayer = %d, num_of_hwc_layer=%d", + __func__, srcW, srcH, srcColorFormat, + srcYAddr, srcCbAddr, srcCrAddr, + dstX, dstY, hdmiLayer, num_of_hwc_layer); + LOGD("saved param(%d, %d, %d)", + mSrcWidth[hdmiLayer], mSrcHeight[hdmiLayer], mSrcColorFormat[hdmiLayer]); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created", __func__); + return false; + } + + if (srcW != mSrcWidth[hdmiLayer] || + srcH != mSrcHeight[hdmiLayer] || + srcColorFormat != mSrcColorFormat[hdmiLayer] || + mHdmiDstWidth != mHdmiResolutionWidth[hdmiLayer] || + mHdmiDstHeight != mHdmiResolutionHeight[hdmiLayer] || + num_of_hwc_layer != mPreviousNumofHwLayer[hdmiLayer] || + mHdmiInfoChange == true) { +#ifdef DEBUG_MSG_ENABLE + LOGD("m_reset param(%d, %d, %d, %d, %d, %d, %d)", + srcW, mSrcWidth[hdmiLayer], + srcH, mSrcHeight[hdmiLayer], + srcColorFormat, mSrcColorFormat[hdmiLayer], + hdmiLayer); +#endif + if (m_reset(srcW, srcH, dstX, dstY, srcColorFormat, hdmiLayer, num_of_hwc_layer) == false) { + LOGE("%s::m_reset(%d, %d, %d, %d) failed", __func__, srcW, srcH, srcColorFormat, hdmiLayer); + return false; + } + } + + if (srcYAddr == 0) { + unsigned int FB_size = ALIGN(srcW, 16) * ALIGN(srcH, 16) * HDMI_G2D_BUFFER_BPP_SIZE; + + srcYAddr = (unsigned int)mFBaddr + mFBoffset; + srcCbAddr = srcYAddr; + + mFBoffset += FB_size; + if (FB_size < mFBoffset) + mFBoffset = 0; + +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::mFBaddr=0x%08x, srcYAddr=0x%08x, mFBoffset=0x%08x", __func__, mFBaddr, srcYAddr, mFBoffset); +#endif + } + + if (hdmiLayer == HDMI_LAYER_VIDEO) { + if (mSecGscaler.setSrcAddr(srcYAddr, srcCbAddr, srcCrAddr, srcColorFormat) == false) { + LOGE("%s::setSrcAddr(0x%08x, 0x%08x, 0x%08x)", __func__, srcYAddr, srcCbAddr, srcCrAddr); + return false; + } + } else { +#if CHECK_GRAPHIC_LAYER_TIME + nsecs_t start, end; + start = systemTime(); +#endif + + if (num_of_hwc_layer == 0) { /* UI only mode */ + struct v4l2_rect rect; + + if (mG2DUIRotVal == 0 || mG2DUIRotVal == 180) { + hdmi_cal_rect(srcW, srcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + } else { + hdmi_cal_rect(srcH, srcW, mHdmiDstWidth, mHdmiDstHeight, &rect); + } + + rect.left = ALIGN(rect.left, 16); + + if (hdmi_set_graphiclayer(mSubdevMixerFd, mVideodevFd[hdmiLayer], hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, &mSrcBuffer[hdmiLayer][mSrcIndex[hdmiLayer]], + rect.left, rect.top, + rect.width, rect.height, + mG2DUIRotVal) < 0) + return false; + + } else { // Video Playback + UI Mode + if (hdmi_set_graphiclayer(mSubdevMixerFd, mVideodevFd[hdmiLayer], hdmiLayer, + srcColorFormat, + srcW, srcH, + srcYAddr, &mSrcBuffer[hdmiLayer][mSrcIndex[hdmiLayer]], + dstX, dstY, + mHdmiDstWidth, mHdmiDstHeight, + mG2DUIRotVal) < 0) + return false; + } + +#if CHECK_GRAPHIC_LAYER_TIME + end = systemTime(); + LOGD("[UI] hdmi_gl_set_param[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + } + + if (mFlagConnected) { + if (mFlagHdmiStart[hdmiLayer] == true) { + if (m_run(hdmiLayer) == false) { + LOGE("%s::m_run(%d) failed", __func__, hdmiLayer); + return false; + } + } + + if (mFlagHdmiStart[hdmiLayer] == false && m_startHdmi(hdmiLayer) == false) { + LOGE("%s::start hdmiLayer(%d) failed", __func__, hdmiLayer); + return false; + } + } + return true; +} + +bool SecHdmi::clear(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer = %d", __func__, hdmiLayer); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + if (mFlagHdmiStart[hdmiLayer] == true && m_stopHdmi(hdmiLayer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] fail \n", __func__, hdmiLayer); + return false; + } + return true; +} + +void SecHdmi::clearGraphicLayer(int hdmiLayer) +{ + mSrcWidth[hdmiLayer] = 0; + mSrcHeight[hdmiLayer] = 0; + mSrcColorFormat[hdmiLayer] = 0; +} + +bool SecHdmi::enableGraphicLayer(int hdmiLayer) +{ + Mutex::Autolock lock(mLock); +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmiLayer(%d)",__func__, hdmiLayer); +#endif + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + case HDMI_LAYER_GRAPHIC_0: + case HDMI_LAYER_GRAPHIC_1: + mFlagLayerEnable[hdmiLayer] = true; + if (mFlagConnected == true) + m_startHdmi(hdmiLayer); + break; + default: + return false; + } + return true; +} + +bool SecHdmi::disableGraphicLayer(int hdmiLayer) +{ + Mutex::Autolock lock(mLock); +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmiLayer(%d)",__func__, hdmiLayer); +#endif + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + case HDMI_LAYER_GRAPHIC_0: + case HDMI_LAYER_GRAPHIC_1: + if (mFlagConnected == true && mFlagLayerEnable[hdmiLayer]) + if (m_stopHdmi(hdmiLayer) == false ) + LOGE("%s::m_stopHdmi: layer[%d] fail \n", __func__, hdmiLayer); + + mFlagLayerEnable[hdmiLayer] = false; + break; + default: + return false; + } + return true; +} + +bool SecHdmi::setHdmiOutputMode(int hdmiOutputMode, bool forceRun) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmiOutputMode = %d, forceRun = %d", __func__, hdmiOutputMode, forceRun); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdmiOutputMode == hdmiOutputMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiOutputMode(%d) \n", __func__, hdmiOutputMode); +#endif + return true; + } + + int newHdmiOutputMode = hdmiOutputMode; + + int v4l2OutputType = hdmi_outputmode_2_v4l2_output_type(hdmiOutputMode); + if (v4l2OutputType < 0) { + LOGD("%s::hdmi_outputmode_2_v4l2_output_type(%d) fail\n", __func__, hdmiOutputMode); + return false; + } + +#if defined(BOARD_USES_EDID) + int newV4l2OutputType = hdmi_check_output_mode(v4l2OutputType); + if (newV4l2OutputType != v4l2OutputType) { + newHdmiOutputMode = hdmi_v4l2_output_type_2_outputmode(newV4l2OutputType); + if (newHdmiOutputMode < 0) { + LOGD("%s::hdmi_v4l2_output_type_2_outputmode(%d) fail\n", __func__, newV4l2OutputType); + return false; + } + + LOGD("%s::calibration mode(%d -> %d)... \n", __func__, hdmiOutputMode, newHdmiOutputMode); + mHdmiInfoChange = true; + } +#endif + + if (mHdmiOutputMode != newHdmiOutputMode) { + mHdmiOutputMode = newHdmiOutputMode; + mHdmiInfoChange = true; + } + + return true; +} + +bool SecHdmi::setHdmiResolution(unsigned int hdmiResolutionValue, bool forceRun) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiResolutionValue = %d, forceRun = %d", __func__, hdmiResolutionValue, forceRun); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdmiResolutionValue == hdmiResolutionValue) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiResolutionValue(%d) \n", __func__, hdmiResolutionValue); +#endif + return true; + } + + unsigned int newHdmiResolutionValue = hdmiResolutionValue; + int w = 0; + int h = 0; + v4l2_std_id std_id; + __u32 preset_id; + +#if defined(BOARD_USES_EDID) + // find perfect resolutions.. + if (hdmi_resolution_2_std_id(newHdmiResolutionValue, &w, &h, &std_id, &preset_id) < 0 || + hdmi_check_resolution(std_id) < 0) { + bool flagFoundIndex = false; + int resolutionValueIndex = m_resolutionValueIndex(newHdmiResolutionValue); + + for (int i = resolutionValueIndex + 1; i < mHdmiSizeOfResolutionValueList; i++) { + if (hdmi_resolution_2_std_id(mHdmiResolutionValueList[i], &w, &h, &std_id, &preset_id) == 0 && + hdmi_check_resolution(std_id) == 0) { + newHdmiResolutionValue = mHdmiResolutionValueList[i]; + flagFoundIndex = true; + break; + } + } + + if (flagFoundIndex == false) { + LOGE("%s::hdmi cannot control this resolution(%d) fail \n", __func__, hdmiResolutionValue); + // Set resolution to 480P + newHdmiResolutionValue = mHdmiResolutionValueList[mHdmiSizeOfResolutionValueList-2]; + } else { + LOGD("%s::HDMI resolutions size is calibrated(%d -> %d)..\n", __func__, hdmiResolutionValue, newHdmiResolutionValue); + } + } else { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::find resolutions(%d) at once\n", __func__, hdmiResolutionValue); +#endif + } +#endif + + if (mHdmiResolutionValue != newHdmiResolutionValue) { + mHdmiResolutionValue = newHdmiResolutionValue; + mHdmiInfoChange = true; + } + + return true; +} + +bool SecHdmi::setHdcpMode(bool hdcpMode, bool forceRun) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (forceRun == false && mHdcpMode == hdcpMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdcpMode(%d) \n", __func__, hdcpMode); +#endif + return true; + } + + mHdcpMode = hdcpMode; + mHdmiInfoChange = true; + + return true; +} + +bool SecHdmi::setUIRotation(unsigned int rotVal, unsigned int hwcLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + Mutex::Autolock lock(mLock); + + if (mFlagCreate == false) { + LOGE("%s::Not Yet Created \n", __func__); + return false; + } + + if (rotVal % 90 != 0) { + LOGE("%s::Invalid rotation value(%d)", __func__, rotVal); + return false; + } + + /* G2D rotation */ + if (rotVal != mG2DUIRotVal) { + mG2DUIRotVal = rotVal; + mHdmiInfoChange = true; + } + + /* FIMC rotation */ + if (hwcLayer == 0) { /* Rotate in UI only mode */ + if (rotVal != mUIRotVal) { + mSecGscaler.setRotVal(rotVal); + mUIRotVal = rotVal; + mHdmiInfoChange = true; + } + } else { /* Don't rotate video layer when video is played. */ + rotVal = 0; + if (rotVal != mUIRotVal) { + mSecGscaler.setRotVal(rotVal); + mUIRotVal = rotVal; + mHdmiInfoChange = true; + } + } + + return true; +} + +bool SecHdmi::setDisplaySize(int width, int height) +{ + mDisplayWidth = width; + mDisplayHeight = height; + + return true; +} + +void SecHdmi::setDisplayInfo(int srcW, int srcH, int srcColorFormat, + unsigned int srcYAddr, unsigned int srcCbAddr, + int dstX, int dstY, + int hdmiLayer, + int num_of_hwc_layer) +{ +#ifdef DEBUG_MSG_ENABLE +LOGD("%s [srcW = %d, srcH = %d, srcColorFormat = 0x%x, srcYAddr= 0x%x, srcCbAddr = 0x%x, dstX = %d, dstY = %d, hdmiLayer = %d", + __func__, srcW, srcH, srcColorFormat, srcYAddr, srcCbAddr, dstX, dstY, hdmiLayer); +#endif + + mCurrentsrcW = srcW; + mCurrentsrcH = srcH; + mCurrentsrcColorFormat = srcColorFormat; + mCurrentsrcYAddr = srcYAddr; + mCurrentsrcCbAddr = srcCbAddr, + mCurrentdstX = dstX; + mCurrentdstY = dstY; + mCurrenthdmiLayer = hdmiLayer; + mCurrentNumOfHWCLayer = num_of_hwc_layer; + + return; +} + +bool SecHdmi::m_setupLink(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + int ret; + char node[32]; + char subdevname[32]; + char videodevname[32]; + + struct v4l2_capability v4l2cap; + struct media_entity_desc entity_desc; + + sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0); + mMediadevFd = open(node, O_RDWR); + if (mMediadevFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto err; + } + + /* open subdev fd */ + sprintf(subdevname, PFX_ENTITY_SUBDEV_MIXER, 0); + for (__u32 id = 0; ; id = entity_desc.id) { + entity_desc.id = id | MEDIA_ENT_ID_FLAG_NEXT; + + if (ioctl(mMediadevFd, MEDIA_IOC_ENUM_ENTITIES, &entity_desc) < 0) { + if (errno == EINVAL) { + LOGD("%s::MEDIA_IOC_ENUM_ENTITIES ended", __func__); + break; + } + LOGE("%s::MEDIA_IOC_ENUM_ENTITIES failed", __func__); + goto err; + } + LOGD("%s::entity_desc.id=%d, .minor=%d .name=%s", __func__, entity_desc.id, entity_desc.v4l.minor, entity_desc.name); + + if (strncmp(entity_desc.name, subdevname, strlen(subdevname)) == 0) + mMixerSubdevEntity = entity_desc.id; + } + + mlink_desc.source.entity = mSecGscaler.getSubdevEntity(); + mlink_desc.source.index = GSCALER_SUBDEV_PAD_SOURCE; + mlink_desc.source.flags = MEDIA_PAD_FL_SOURCE; + + mlink_desc.sink.entity = mMixerSubdevEntity; + mlink_desc.sink.index = MIXER_V_SUBDEV_PAD_SINK; + mlink_desc.sink.flags = MEDIA_PAD_FL_SINK; + mlink_desc.flags = MEDIA_LNK_FL_ENABLED; + +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::mlink_desc.source.entity=%02d, .pad=%d", __func__, mlink_desc.source.entity, mlink_desc.source.index); + LOGD("%s::mlink_desc.sink.entity =%02d, .pad=%d", __func__, mlink_desc.sink.entity, mlink_desc.sink.index); +#endif + + if (ioctl(mMediadevFd, MEDIA_IOC_SETUP_LINK, &mlink_desc) < 0) { + LOGE("%s::MEDIA_IOC_SETUP_LINK [src.entity=%d->sink.entity=%d] failed", __func__, mlink_desc.source.entity, mlink_desc.sink.entity); + goto err; + } + + sprintf(node, "%s%d", PFX_NODE_SUBDEV, 4); // Mixer0 minor=132 /dev/v4l-subdev4 // need to modify //carrotsm + mSubdevMixerFd = open(node, O_RDWR, 0); + if (mSubdevMixerFd < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto err; + } + + if (0 < mMediadevFd) + close(mMediadevFd); + mMediadevFd = -1; + + return true; + +err : + + if (0 < mMediadevFd) + close(mMediadevFd); + + if (0 < mSubdevMixerFd) + close(mSubdevMixerFd); + + mMediadevFd = -1; + mSubdevMixerFd = -1; + + return false; +} + +bool SecHdmi::m_openLayer(int layer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::layer=%d", __func__, layer); +#endif + char node[32]; + + switch (layer) { + case HDMI_LAYER_VIDEO: + mVideodevFd[layer] = mSecGscaler.getVideodevFd(); + + if (0 < mVideodevFd[layer]) { + LOGD("%s::Layer[%d] device already opened", __func__, layer); + return true; + } + + if (mSecGscaler.openVideodevFd() == false) + LOGE("%s::open(%s) failed", __func__, node); + else + mVideodevFd[layer] = mSecGscaler.getVideodevFd(); + + goto open_success; + break; + case HDMI_LAYER_GRAPHIC_0: + sprintf(node, "%s", TVOUT0_DEV_G0); + break; + case HDMI_LAYER_GRAPHIC_1: + sprintf(node, "%s", TVOUT0_DEV_G1); + break; + default: + LOGE("%s::unmatched layer[%d]", __func__, layer); + return false; + break; + } + + mVideodevFd[layer] = open(node, O_RDWR); + if (mVideodevFd[layer] < 0) { + LOGE("%s::open(%s) failed", __func__, node); + goto err; + } + +open_success : + +#ifdef DEBUG_MSG_ENABLE + LOGD("layer=%d, mVideodevFd=%d", layer, mVideodevFd[layer]); +#endif + + if (tvout_std_v4l2_querycap(mVideodevFd[layer], node) < 0 ) { + LOGE("%s::tvout_std_v4l2_querycap failed", __func__); + goto err; + } + + return true; + +err : + + if (0 < mVideodevFd[layer]) + close(mVideodevFd[layer]); + + mVideodevFd[layer] = -1; + + return false; + +} + +bool SecHdmi::m_closeLayer(int layer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::layer=%d", __func__, layer); +#endif + switch (layer) { + case HDMI_LAYER_VIDEO: + mVideodevFd[layer] = mSecGscaler.getVideodevFd(); + + if (mVideodevFd[layer] < 0) { + LOGD("%s::Layer[%d] device already closed", __func__, layer); + return true; + } else { + mSecGscaler.closeVideodevFd(); + mVideodevFd[layer] = mSecGscaler.getVideodevFd(); + } + goto close_success; + break; + case HDMI_LAYER_GRAPHIC_0: + case HDMI_LAYER_GRAPHIC_1: + /* clear buffer */ + if (0 < mVideodevFd[layer]) { + if (tvout_std_v4l2_reqbuf(mVideodevFd[layer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, 0) < 0) { + LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[graphic layer] failed", __func__, 0); + return -1; + } + } + break; + default: + LOGE("%s::unmatched layer[%d]", __func__, layer); + return false; + break; + } + + if (0 < mVideodevFd[layer]) { + if (close(mVideodevFd[layer]) < 0) { + LOGE("%s::close %d layer failed", __func__, layer); + return false; + } + } + + mVideodevFd[layer] = -1; + +close_success : + + return true; +} + +bool SecHdmi::m_reset(int w, int h, int dstX, int dstY, int colorFormat, int hdmiLayer, int num_of_hwc_layer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::w=%d, h=%d, dstX=%d, dstY=%d, colorFormat=%d, hdmiLayer=%d, num_of_hwc_layer=%d", + __func__, w, h, dstX, dstY, colorFormat, hdmiLayer, num_of_hwc_layer); +#endif + + v4l2_std_id std_id = 0; + + int srcW = w; + int srcH = h; + int dstW = 0; + int dstH = 0; + + if (mFlagHdmiStart[hdmiLayer] == true && m_stopHdmi(hdmiLayer) == false) { + LOGE("%s::m_stopHdmi: layer[%d] failed", __func__, hdmiLayer); + return false; + } + + if (m_closeLayer(hdmiLayer) == false) { + LOGE("%s::m_closeLayer: layer[%d] failed", __func__, hdmiLayer); + return false; + } + + if (m_openLayer(hdmiLayer) == false) { + LOGE("%s::m_closeLayer: layer[%d] failed", __func__, hdmiLayer); + return false; + } + + if (w != mSrcWidth[hdmiLayer] || + h != mSrcHeight[hdmiLayer] || + mHdmiDstWidth != mHdmiResolutionWidth[hdmiLayer] || + mHdmiDstHeight != mHdmiResolutionHeight[hdmiLayer] || + num_of_hwc_layer != mPreviousNumofHwLayer[hdmiLayer] || + colorFormat != mSrcColorFormat[hdmiLayer] || + mHdmiInfoChange == true) { + int preVideoSrcColorFormat = mSrcColorFormat[hdmiLayer]; + int videoSrcColorFormat = colorFormat; + + if (preVideoSrcColorFormat != HAL_PIXEL_FORMAT_YCbCr_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP && + preVideoSrcColorFormat != HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED) { + LOGI("%s: Unsupported preVideoSrcColorFormat = 0x%x", __func__, preVideoSrcColorFormat); + preVideoSrcColorFormat = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + } + + if (hdmiLayer == HDMI_LAYER_VIDEO) { + unsigned int full_wdith = ALIGN(w, 16); + unsigned int full_height = ALIGN(h, 16); + + if (mSecGscaler.setSrcParams(full_wdith, full_height, 0, 0, + (unsigned int*)&w, (unsigned int*)&h, colorFormat, true) == false) { + LOGE("%s::mSecGscaler.setSrcParams(w=%d, h=%d, color=%d) failed", + __func__, w, h, colorFormat); + return false; + } + mGscalerDstColorFormat = V4L2_MBUS_FMT_YUV8_1X24; + + /* calculate destination buffer width and height */ + struct v4l2_rect rect; + + if (mUIRotVal == 0 || mUIRotVal == 180) { + hdmi_cal_rect(srcW, srcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + } else { + hdmi_cal_rect(srcH, srcW, mHdmiDstWidth, mHdmiDstHeight, &rect); + } + + rect.width = ALIGN(rect.width, 16); + + if (mSecGscaler.setDstParams((unsigned int)rect.width, (unsigned int)rect.height, 0, 0, + (unsigned int*)&rect.width, (unsigned int*)&rect.height, mGscalerDstColorFormat, true) == false) { + LOGE("%s::mSecGscaler.setDstParams(w=%d, h=%d, V4L2_MBUS_FMT_YUV8_1X24) failed", + __func__, rect.width, rect.height); + return false; + } + + hdmi_set_videolayer(mSubdevMixerFd, mHdmiDstWidth, mHdmiDstHeight, &rect); + } else { + if (tvout_std_v4l2_s_ctrl(mVideodevFd[hdmiLayer], V4L2_CID_TV_LAYER_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ENABLE) failed", __func__, hdmiLayer); + return false; + } + + if (tvout_std_v4l2_s_ctrl(mVideodevFd[hdmiLayer], V4L2_CID_TV_PIXEL_BLEND_ENABLE, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ENABLE) failed", __func__, hdmiLayer); + return false; + } + + if (tvout_std_v4l2_s_ctrl(mVideodevFd[hdmiLayer], V4L2_CID_TV_LAYER_BLEND_ALPHA, 255) < 0) { + LOGE("%s::tvout_std_v4l2_s_ctrl [layer=%d] (V4L2_CID_TV_LAYER_BLEND_ALPHA) failed", __func__, hdmiLayer); + return false; + } + + struct v4l2_rect rect; + int tempSrcW, tempSrcH; + int gr_frame_size = 0; + + if (mG2DUIRotVal == 0 || mG2DUIRotVal == 180) { + tempSrcW = srcW; + tempSrcH = srcH; + } else { + tempSrcW = srcH; + tempSrcH = srcW; + } + + hdmi_cal_rect(tempSrcW, tempSrcH, mHdmiDstWidth, mHdmiDstHeight, &rect); + rect.left = ALIGN(rect.left, 16); + + if (num_of_hwc_layer == 0) { /* UI only mode */ + hdmi_set_g_Params(mSubdevMixerFd, mVideodevFd[hdmiLayer], hdmiLayer, + colorFormat, srcW, srcH, + rect.left, rect.top, rect.width, rect.height); + dstW = rect.width; + dstH = rect.height; + } else { /* Video Playback + UI Mode */ + hdmi_set_g_Params(mSubdevMixerFd, mVideodevFd[hdmiLayer], hdmiLayer, + colorFormat, srcW, srcH, + dstX, dstY, mHdmiDstWidth, mHdmiDstHeight); + dstW = mHdmiDstWidth; + dstH = mHdmiDstHeight; + } + +#if defined(BOARD_USES_HDMI_FIMGAPI) + gr_frame_size = dstW * dstH; +#else + gr_frame_size = srcW * srcH; +#endif + for (int buf_index = 0; buf_index < MAX_BUFFERS_MIXER; buf_index++) { + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(colorFormat); + switch (v4l2ColorFormat) { + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + mSrcBuffer[hdmiLayer][buf_index].size.s = gr_frame_size << 2; + break; + case V4L2_PIX_FMT_RGB565X: + mSrcBuffer[hdmiLayer][buf_index].size.s = gr_frame_size << 1; + break; + default: + LOGE("%s::invalid color type", __func__); + return false; + break; + } + } + + } + + if (preVideoSrcColorFormat != videoSrcColorFormat) + mHdmiInfoChange = true; + + mSrcWidth[hdmiLayer] = srcW; + mSrcHeight[hdmiLayer] = srcH; + mSrcColorFormat[hdmiLayer] = colorFormat; + + mHdmiResolutionWidth[hdmiLayer] = mHdmiDstWidth; + mHdmiResolutionHeight[hdmiLayer] = mHdmiDstHeight; + mPreviousNumofHwLayer[hdmiLayer] = num_of_hwc_layer; + +#ifdef DEBUG_MSG_ENABLE + LOGD("m_reset saved param(%d, %d, %d, %d, %d, %d, %d)", + srcW, mSrcWidth[hdmiLayer], \ + srcH, mSrcHeight[hdmiLayer], \ + colorFormat,mSrcColorFormat[hdmiLayer], \ + hdmiLayer); +#endif + } + + if (mHdmiInfoChange == true) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("mHdmiInfoChange: %d", mHdmiInfoChange); +#endif + +#if defined(BOARD_USES_CEC) + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (mCECThread->mFlagRunning) + mCECThread->stop(); + } +#endif + + if (m_setHdmiOutputMode(mHdmiOutputMode) == false) { + LOGE("%s::m_setHdmiOutputMode() failed", __func__); + return false; + } + if (mHdmiOutputMode == COMPOSITE_OUTPUT_MODE) { + std_id = composite_std_2_v4l2_std_id(mCompositeStd); + if ((int)std_id < 0) { + LOGE("%s::composite_std_2_v4l2_std_id(%d) failed", __func__, mCompositeStd); + return false; + } + if (m_setCompositeResolution(mCompositeStd) == false) { + LOGE("%s::m_setCompositeRsolution() failed", __func__); + return false; + } + } else if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (m_setHdmiResolution(mHdmiResolutionValue) == false) { + LOGE("%s::m_setHdmiResolution() failed", __func__); + return false; + } + + if (m_setHdcpMode(mHdcpMode) == false) { + LOGE("%s::m_setHdcpMode() failed", __func__); + return false; + } + std_id = mHdmiStdId; + } + + if (mPreviousHdmiPresetId != mHdmiPresetId) { + for (int layer = HDMI_LAYER_BASE + 1; layer < HDMI_LAYER_MAX; layer++) { + if (m_stopHdmi(layer) == false) { + LOGE("%s::m_stopHdmi(%d) failed", __func__, layer); + return false; + } + } + + if (tvout_init(mVideodevFd[HDMI_LAYER_GRAPHIC_0], mHdmiPresetId) < 0) { + LOGE("%s::tvout_init(mHdmiPresetId=%d) failed", __func__, mHdmiPresetId); + return false; + } + mPreviousHdmiPresetId = mHdmiPresetId; + } + + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { +#if defined(BOARD_USES_CEC) + if (!(mCECThread->mFlagRunning)) + mCECThread->start(); +#endif + +/* if (m_setAudioMode(mAudioMode) == false) + LOGE("%s::m_setAudioMode() failed", __func__); +*/ + } + + mHdmiInfoChange = false; + + } + + return true; +} + +bool SecHdmi::m_streamOn(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer = %d", __func__, hdmiLayer); +#endif + + if (mFlagCreate == false) { + LOGE("%s::Not yet created", __func__); + return false; + } + + if (mFlagHdmiStart[hdmiLayer] == true) { + LOGE("%s::[layer=%d] already streamon", __func__, hdmiLayer); + return true; + } + + switch(hdmiLayer) { + case HDMI_LAYER_GRAPHIC_0: + break; + case HDMI_LAYER_GRAPHIC_1: + break; + default : + LOGE("%s::unmathced layer(%d) failed", __func__, hdmiLayer); + return false; + break; + } + + if (tvout_std_v4l2_qbuf(mVideodevFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, + mSrcIndex[hdmiLayer], 1, &mSrcBuffer[hdmiLayer][0]) < 0) { + LOGE("%s::gsc_v4l2_queue(index : %d) (mSrcBufNum : %d) failed", __func__, mSrcIndex[hdmiLayer], 1); + return false; + } + + mSrcIndex[hdmiLayer]++; + if (mSrcIndex[hdmiLayer] == MAX_BUFFERS_MIXER) { + if (tvout_std_v4l2_streamon(mVideodevFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::gsc_v4l2_stream_on() failed", __func__); + return false; + } + mFlagHdmiStart[hdmiLayer] = true; + } + + if (mSrcIndex[hdmiLayer] >= MAX_BUFFERS_MIXER) { + mSrcIndex[hdmiLayer] = 0; + } + + return true; +} + +bool SecHdmi::m_run(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer = %d", __func__, hdmiLayer); +#endif + + int buf_index = 0; + + if (mFlagHdmiStart[hdmiLayer] == false || mFlagLayerEnable[hdmiLayer] == false) { + LOGD("%s::HDMI(%d layer) started not yet", __func__, hdmiLayer); + return true; + } + + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + if (mSecGscaler.run() == false) { + LOGE("%s::mSecGscaler.draw() failed", __func__); + return false; + } + break; + case HDMI_LAYER_GRAPHIC_0 : + case HDMI_LAYER_GRAPHIC_1 : + if (tvout_std_v4l2_dqbuf(mVideodevFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, &buf_index, 1) < 0) { + LOGE("%s::tvout_std_v4l2_dqbuf(mNumOfBuf : %d, dqIndex=%d) failed", __func__, 1, buf_index); + return false; + } + + if (tvout_std_v4l2_qbuf(mVideodevFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, + mSrcIndex[hdmiLayer], 1, &mSrcBuffer[hdmiLayer][mSrcIndex[hdmiLayer]]) < 0) { + LOGE("%s::tvout_std_v4l2_qbuf(mNumOfBuf : %d,mSrcIndex=%d) failed", __func__, 1, mSrcIndex[hdmiLayer]); + return false; + } + + mSrcIndex[hdmiLayer]++; + if (mSrcIndex[hdmiLayer] >= MAX_BUFFERS_MIXER) { + mSrcIndex[hdmiLayer] = 0; + } + + break; + default : + LOGE("%s::unmathced layer(%d) failed", __func__, hdmiLayer); + return false; + break; + } + + return true; +} + +bool SecHdmi::m_startHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer = %d", __func__, hdmiLayer); +#endif + + int buf_index = 0; + + if (mFlagHdmiStart[hdmiLayer] == true) { + LOGD("%s::already HDMI(%d layer) started..", __func__, hdmiLayer); + return true; + } + +#ifdef DEBUG_MSG_ENABLE + LOGD("### %s: hdmiLayer(%d) called", __func__, hdmiLayer); +#endif + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + if (mSecGscaler.streamOn() == false) { + LOGE("%s::mSecGscaler.streamOn() failed", __func__); + return false; + } + if (mSecGscaler.getFlagSteamOn() == true) + mFlagHdmiStart[hdmiLayer] = true; + break; + case HDMI_LAYER_GRAPHIC_0 : + case HDMI_LAYER_GRAPHIC_1 : + if (m_streamOn(hdmiLayer) == false) { + LOGE("%s::m_streamOn layer(%d) failed", __func__, hdmiLayer); + return false; + } + break; + default : + LOGE("%s::unmathced layer(%d) failed", __func__, hdmiLayer); + return false; + break; + } + return true; +} + +bool SecHdmi::m_stopHdmi(int hdmiLayer) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::hdmiLayer = %d", __func__, hdmiLayer); +#endif + + if (mFlagHdmiStart[hdmiLayer] == false) { + LOGD("%s::already HDMI(%d layer) stopped..", __func__, hdmiLayer); + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s : layer[%d] called", __func__, hdmiLayer); +#endif + + switch (hdmiLayer) { + case HDMI_LAYER_VIDEO: + if (mSecGscaler.streamOff() == false) { + LOGE("%s::mSecGscaler.streamOff() failed", __func__); + return false; + } + mFlagHdmiStart[hdmiLayer] = false; + break; + case HDMI_LAYER_GRAPHIC_1 : + case HDMI_LAYER_GRAPHIC_0 : +#if defined(BOARD_USES_HDMI_FIMGAPI) + cur_g2d_address = 0; +#endif + if (tvout_std_v4l2_streamoff(mVideodevFd[hdmiLayer], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { + LOGE("%s::tvout_std_v4l2_streamon layer(%d) failed", __func__, hdmiLayer); + return false; + } + + mSrcIndex[hdmiLayer] = 0; + mFlagHdmiStart[hdmiLayer] = false; + break; + default : + LOGE("%s::unmathced layer(%d) failed", __func__, hdmiLayer); + return false; + break; + } + + return true; +} + +bool SecHdmi::m_setHdmiOutputMode(int hdmiOutputMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdmiOutputMode == mCurrentHdmiOutputMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiOutputMode(%d) \n", __func__, hdmiOutputMode); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int v4l2OutputType = hdmi_outputmode_2_v4l2_output_type(hdmiOutputMode); + if (v4l2OutputType < 0) { + LOGE("%s::hdmi_outputmode_2_v4l2_output_type(%d) fail\n", __func__, hdmiOutputMode); + return false; + } + + output_type = v4l2OutputType; + + mCurrentHdmiOutputMode = hdmiOutputMode; + + return true; +} + +bool SecHdmi::m_setCompositeResolution(unsigned int compositeStdId) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int w = 0; + int h = 0; + + if (mHdmiOutputMode != COMPOSITE_OUTPUT_MODE) { + LOGE("%s::not supported output type \n", __func__); + return false; + } + + switch (compositeStdId) { + case COMPOSITE_STD_NTSC_M: + case COMPOSITE_STD_NTSC_443: + w = 704; + h = 480; + break; + case COMPOSITE_STD_PAL_BDGHI: + case COMPOSITE_STD_PAL_M: + case COMPOSITE_STD_PAL_N: + case COMPOSITE_STD_PAL_Nc: + case COMPOSITE_STD_PAL_60: + w = 704; + h = 576; + break; + default: + LOGE("%s::unmathced composite_std(%d)", __func__, compositeStdId); + return false; + } + + t_std_id = composite_std_2_v4l2_std_id(mCompositeStd); + + mHdmiDstWidth = w; + mHdmiDstHeight = h; + + mCurrentHdmiResolutionValue = -1; + return true; +} + +bool SecHdmi::m_setHdmiResolution(unsigned int hdmiResolutionValue) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdmiResolutionValue == mCurrentHdmiResolutionValue) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdmiResolutionValue(%d) \n", __func__, hdmiResolutionValue); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + int w = 0; + int h = 0; + + v4l2_std_id std_id; + if (mHdmiOutputMode >= HDMI_OUTPUT_MODE_YCBCR && + mHdmiOutputMode <= HDMI_OUTPUT_MODE_DVI) { + if (hdmi_resolution_2_std_id(hdmiResolutionValue, &w, &h, &std_id, &mHdmiPresetId) < 0) { + LOGE("%s::hdmi_resolution_2_std_id(%d) fail\n", __func__, hdmiResolutionValue); + return false; + } + mHdmiStdId = std_id; + } else { + LOGE("%s::not supported output type \n", __func__); + return false; + } + + t_std_id = std_id; + + mHdmiDstWidth = w; + mHdmiDstHeight = h; + + mCurrentHdmiResolutionValue = hdmiResolutionValue; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::mHdmiDstWidth = %d, mHdmiDstHeight = %d, mHdmiStdId = 0x%x, hdmiResolutionValue = 0x%x\n", + __func__, + mHdmiDstWidth, + mHdmiDstHeight, + mHdmiStdId, + hdmiResolutionValue); +#endif + + return true; +} + +bool SecHdmi::m_setHdcpMode(bool hdcpMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (hdcpMode == mCurrentHdcpMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same hdcpMode(%d) \n", __func__, hdcpMode); +#endif + + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + if (hdcpMode == true) + g_hdcp_en = 1; + else + g_hdcp_en = 0; + + mCurrentHdcpMode = hdcpMode; + + return true; +} + +bool SecHdmi::m_setAudioMode(int audioMode) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + if (audioMode == mCurrentAudioMode) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::same audioMode(%d) \n", __func__, audioMode); +#endif + return true; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + if (hdmi_check_audio(mVideodevFd[HDMI_LAYER_GRAPHIC_0]) < 0) { + LOGE("%s::hdmi_check_audio() fail \n", __func__); + return false; + } + + mCurrentAudioMode = audioMode; + + return true; +} + +int SecHdmi::m_resolutionValueIndex(unsigned int ResolutionValue) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + + int index = -1; + + for (int i = 0; i < mHdmiSizeOfResolutionValueList; i++) { + if (mHdmiResolutionValueList[i] == ResolutionValue) { + index = i; + break; + } + } + return index; +} + +bool SecHdmi::m_flagHWConnected(void) +{ +#ifdef DEBUG_MSG_ENABLE + LOGD("%s", __func__); +#endif + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("### %s called\n", __func__); +#endif + + bool ret = true; + int hdmiStatus = hdmi_cable_status(); + + if (hdmiStatus <= 0) { +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::hdmi_cable_status() fail \n", __func__); +#endif + ret = false; + } else { + ret = true; + } + + return ret; +} + +}; // namespace android diff --git a/exynos5/hal/libhdmi/SecHdmi/SecHdmiCommon.h b/exynos5/hal/libhdmi/SecHdmi/SecHdmiCommon.h new file mode 100644 index 0000000..5ca9e4e --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecHdmiCommon.h @@ -0,0 +1,118 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +** +** @author Sangwoo, Park(sw5771.park@samsung.com) +** @date 2010-09-10 +** +*/ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +#include + +#include "../libhdmi/SecHdmi/fimd_api.h" + +//#define DEBUG_MSG_ENABLE +//#define DEBUG_HDMI_HW_LEVEL +//#define BOARD_USES_EDID +//#define BOARD_USES_CEC +//#define SUPPORT_G2D_UI_MODE + +#define DEFAULT_FB (0) +#define MAX_MIXER_NUM (1) +#define MAX_BUFFERS_MIXER (2) +#define MAX_PLANES_MIXER (3) + +#define HDMI_GSCALER_BUF_NUM (3) +#define HDMI_FIMC_BUFFER_BPP_SIZE (1.5) //NV12 Tiled is 1.5 bytes, RGB565 is 2, RGB888 is 4, Default is NV12 Tiled +#define HDMI_G2D_BUFFER_BPP_SIZE (4) //NV12 Tiled is 1.5 bytes, RGB565 is 2, RGB888 is 4 +#define SUPPORT_1080P_FIMC_OUT +#define HDMI_MAX_WIDTH (1920) +#define HDMI_MAX_HEIGHT (1080) + +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +#if defined(STD_NTSC_M) + #define DEFAULT_OUPUT_MODE (COMPOSITE_OUTPUT_MODE) + #define DEFAULT_HDMI_RESOLUTION_VALUE (1080960) // 1080P_60 + #define DEFAULT_HDMI_STD_ID (V4L2_STD_1080P_60) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif (STD_1080P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_RGB) + #define DEFAULT_HDMI_RESOLUTION_VALUE (1080960) // 1080P_60 + #define DEFAULT_HDMI_STD_ID (V4L2_STD_1080P_60) + #define DEFALULT_DISPLAY_WIDTH (1920) + #define DEFALULT_DISPLAY_HEIGHT (1080) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif defined(STD_720P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (720960) // 720P_60 + #define DEFAULT_HDMI_STD_ID (V4L2_STD_720P_60) + #define DEFALULT_DISPLAY_WIDTH (1280) + #define DEFALULT_DISPLAY_HEIGHT (720) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#elif defined(STD_480P) + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (4809601) // 480P_60_4_3 + #define DEFAULT_HDMI_STD_ID (V4L2_STD_480P_60_16_9) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#else + #define DEFAULT_OUPUT_MODE (HDMI_OUTPUT_MODE_YCBCR) + #define DEFAULT_HDMI_RESOLUTION_VALUE (4809602) // 480P_60_4_3 + #define DEFAULT_HDMI_STD_ID (V4L2_STD_480P_60_4_3) + #define DEFALULT_DISPLAY_WIDTH (720) + #define DEFALULT_DISPLAY_HEIGHT (480) + #define DEFAULT_COMPOSITE_STD (COMPOSITE_STD_NTSC_M) +#endif + +enum hdp_cable_status { + HPD_CABLE_OUT = 0, // HPD_CABLE_OUT indicates HDMI cable out. + HPD_CABLE_IN // HPD_CABLE_IN indicates HDMI cable in. +}; + +enum state { + OFF = 0, + ON = 1, + NOT_SUPPORT = 2, +}; + +enum tv_mode { + HDMI_OUTPUT_MODE_YCBCR = 0, + HDMI_OUTPUT_MODE_RGB = 1, + HDMI_OUTPUT_MODE_DVI = 2, + COMPOSITE_OUTPUT_MODE = 3 +}; + +enum composite_std { + COMPOSITE_STD_NTSC_M = 0, + COMPOSITE_STD_PAL_BDGHI = 1, + COMPOSITE_STD_PAL_M = 2, + COMPOSITE_STD_PAL_N = 3, + COMPOSITE_STD_PAL_Nc = 4, + COMPOSITE_STD_PAL_60 = 5, + COMPOSITE_STD_NTSC_443 = 6 +}; + +enum hdmi_layer { + HDMI_LAYER_BASE = 0, + HDMI_LAYER_VIDEO, + HDMI_LAYER_GRAPHIC_0, + HDMI_LAYER_GRAPHIC_1, + HDMI_LAYER_MAX, +}; diff --git a/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp b/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp new file mode 100644 index 0000000..ac4717b --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.cpp @@ -0,0 +1,1350 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" +//#define DEBUG_HDMI_HW_LEVEL +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sec_utils_v4l2.h" +#include "s5p_tvout_v4l2.h" + +#include "videodev2.h" + +#if defined(BOARD_USES_HDMI_FIMGAPI) +#include "sec_g2d_4x.h" +#include "FimgApi.h" +#endif + +#include "audio.h" +#include "video.h" +#include "../libhdmi/libsForhdmi/libedid/libedid.h" +#include "../libhdmi/libsForhdmi/libcec/libcec.h" + +#include "SecGscaler.h" +#include "SecHdmiCommon.h" +#include "SecHdmiV4L2Utils.h" + +namespace android { + +unsigned int output_type = V4L2_OUTPUT_TYPE_DIGITAL; +v4l2_std_id t_std_id = V4L2_STD_1080P_30; +int g_hpd_state = HPD_CABLE_OUT; +unsigned int g_hdcp_en = 0; + +#if defined(BOARD_USES_HDMI_FIMGAPI) +unsigned int g2d_reserved_memory0 = 0; +unsigned int g2d_reserved_memory1 = 0; +unsigned int g2d_reserved_memory_size = 0; +unsigned int cur_g2d_address = 0; +#endif + +void display_menu(void) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + + LOGI("=============== HDMI Audio =============\n"); + + if (EDIDAudioModeSupport(&audio)) + LOGI("= 2CH_PCM 44100Hz audio supported =\n"); + + LOGI("========= HDMI Mode & Color Space =======\n"); + + video.mode = HDMI; + if (EDIDHDMIModeSupport(&video)) { + video.colorSpace = HDMI_CS_YCBCR444; + if (EDIDColorSpaceSupport(&video)) + LOGI("= 1. HDMI(YCbCr) =\n"); + + video.colorSpace = HDMI_CS_RGB; + if (EDIDColorSpaceSupport(&video)) + LOGI("= 2. HDMI(RGB) =\n"); + } else { + video.mode = DVI; + if (EDIDHDMIModeSupport(&video)) + LOGI("= 3. DVI =\n"); + } + + LOGI("=========== HDMI Rseolution ========\n"); + + /* 480P */ + video.resolution = v720x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 4. 480P_60_16_9 (0x04000000) =\n"); + + video.resolution = v640x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 5. 480P_60_4_3 (0x05000000) =\n"); + + /* 576P */ + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 6. 576P_50_16_9 (0x06000000) =\n"); + + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 7. 576P_50_4_3 (0x07000000) =\n"); + + /* 720P 60 */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 8. 720P_60 (0x08000000) =\n"); + + /* 720P_50 */ + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 9. 720P_50 (0x09000000) =\n"); + + /* 1080P_60 */ + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= a. 1080P_60 (0x0a000000) =\n"); + + /* 1080P_50 */ + video.resolution = v1920x1080p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= b. 1080P_50 (0x0b000000) =\n"); + + /* 1080I_60 */ + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= c. 1080I_60 (0x0c000000) =\n"); + + /* 1080I_50 */ + video.resolution = v1920x1080i_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= d. 1080I_50 (0x0d000000) =\n"); + + /* 1080P_30 */ + video.resolution = v1920x1080p_30Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= e. 1080P_30 (0x12000000) =\n"); + + LOGI("=========== HDMI 3D Format ========\n"); + + /* 720P_60_SBS_HALF */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= f. 720P_60_SBS_HALF (0x13000000) =\n"); + + /* 720P_59_SBS_HALF */ + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 10. 720P_59_SBS_HALF (0x14000000) =\n"); + + /* 720P_50_TB */ + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 11. 720P_50_TB (0x15000000) =\n"); + + /* 1080P_24_TB */ + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 12. 1080P_24_TB (0x16000000) =\n"); + + /* 1080P_23_TB */ + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + if (EDIDVideoResolutionSupport(&video)) + LOGI("= 13. 1080P_24_TB (0x17000000) =\n"); + LOGI("=========================================\n"); +} + +int tvout_init(int fd_tvout, __u32 preset_id) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::preset_id = 0x%x", __func__, preset_id); +#endif + + int ret; + struct v4l2_output output; + struct v4l2_dv_preset preset; + + unsigned int matched = 0, i = 0; + int output_index; + + if (fd_tvout <= 0) { + fd_tvout = open(TVOUT0_DEV_G0, O_RDWR); + if (fd_tvout < 0) { + LOGE("%s::fd_tvout open failed", __func__); + return -1; + } + } +/* + if (output_type >= V4L2_OUTPUT_TYPE_DIGITAL && + output_type <= V4L2_OUTPUT_TYPE_DVI) + if (ioctl(fd_tvout, VIDIOC_HDCP_ENABLE, g_hdcp_en) < 0) + LOGE("%s::VIDIOC_HDCP_ENABLE failed %d", __func__, errno); +*/ + i = 0; + + do { + output.index = i; + ret = tvout_v4l2_enum_output(fd_tvout, &output); + LOGV("%s::output_type=%d output.index=%d .name=%s", __func__, output_type, output.index, output.name); + if (output.type == output_type) { + matched = 1; + break; + } + i++; + } while (ret >=0); +/* + if (!matched) { + LOGE("%s::no matched output type [type=0x%08x]", __func__, output_type); + return -1; + } + + tvout_v4l2_s_output(fd_tvout, output.index); + output_index = 0; + tvout_v4l2_g_output(fd_tvout, &output_index); +*/ + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::input preset_id=0x%08x", __func__, preset_id); +#endif + + if (output.capabilities & V4L2_OUT_CAP_PRESETS) { + tvout_std_v4l2_enum_dv_presets(fd_tvout); + preset.preset = preset_id; + if (tvout_std_v4l2_s_dv_preset(fd_tvout, &preset) < 0 ) { + LOGE("%s::tvout_std_v4l2_s_dv_preset failed", __func__); + return -1; + } + } + + return fd_tvout; +} + +int tvout_deinit() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + return 0; +} + +int tvout_std_v4l2_querycap(int fd, char *node) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_capability v4l2cap; + + if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) { + LOGE("%s::VIDIOC_QUERYCAP failed", __func__); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) { + LOGE("%s::%s is not support streaming", __func__, node); + return -1; + } + + if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) { + LOGE("%s::%s is not support video output mplane", __func__, node); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_s_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, int w, int h, int colorformat, int num_planes) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + struct v4l2_format fmt; + + fmt.type = type; + if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_G_FMT failed", __func__); + return -1; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + fmt.fmt.pix.width = w; + fmt.fmt.pix.height = h; + fmt.fmt.pix.pixelformat = colorformat; + fmt.fmt.pix.field = field; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt.fmt.pix_mp.width = w; + fmt.fmt.pix_mp.height = h; + fmt.fmt.pix_mp.pixelformat = colorformat; + fmt.fmt.pix_mp.field = field; + fmt.fmt.pix_mp.num_planes = num_planes; + break; + default: + LOGE("%s::invalid buffer type", __func__); + return -1; + break; + } + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_S_FMT failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field, int x, int y, int w, int h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_crop crop; + + crop.type = type; + crop.c.left = x; + crop.c.top = y; + crop.c.width = w; + crop.c.height = h; + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed", + __func__, x, y, w, h); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_s_ctrl(int fd, int id, int value) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_control vc; + + vc.id = id; + vc.value = value; + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_requestbuffers reqbuf; + + reqbuf.type = type; + reqbuf.memory = memory; + reqbuf.count = num_bufs; + + if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { + LOGE("%s::VIDIOC_REQBUFS failed", __func__); + return -1; + } + + if (reqbuf.count < num_bufs) { + LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))", + __func__, reqbuf.count, num_bufs); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_querybuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, unsigned int num_planes, SecBuffer *secBuf) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_MIXER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + if (MAX_BUFFERS_MIXER <= buf_index || MAX_PLANES_MIXER <= num_planes) { + LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_planes); + return -1; + } + + buf.type = type; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_index; + buf.length = num_planes; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length); + return -1; + } + + for (unsigned int i = 0; i < num_planes; i++) { + if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) { + LOGE("%s::mmap failed", __func__); + LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset); + LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length); + LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + return -1; + } + secBuf->size.extS[i] = buf.m.planes[i].length; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::vaddr[bufindex=%d][planeidx=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]); + LOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length); +#endif + } + + return 0; +} + +int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_MIXER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + buf.type = type; + buf.memory = memory; + buf.length = num_planes; + buf.index = buf_index; + buf.m.planes = planes; + + for (unsigned int i = 0; i < buf.length; i++) { + buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i]; + buf.m.planes[i].length = secBuf->size.extS[i]; + buf.m.planes[i].bytesused = buf.m.planes[i].length; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::buf.index=%d", __func__, buf.index); + LOGD("%s::buf.m.planes[%d].m.userptr=0x%08x", __func__, i, (unsigned int)buf.m.planes[i].m.userptr); + LOGD("%s::buf.m.planes[%d].length =0x%08x", __func__, i, buf.m.planes[i].length); + LOGD("%s::buf.m.planes[%d].bytesused=0x%08x", __func__, i, buf.m.planes[i].bytesused); +#endif + } + + if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { + LOGE("%s::VIDIOC_QBUF failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_buffer buf; + struct v4l2_plane planes[MAX_PLANES_MIXER]; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + for (int i = 0; i < MAX_PLANES_GSCALER; i++) + memset(&planes[i], 0, sizeof(struct v4l2_plane)); + + + buf.type = type; + buf.memory = memory; + buf.length = num_planes; + buf.m.planes = planes; + + if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { + LOGE("%s::VIDIOC_DQBUF failed", __func__); + return -1; + } + *buf_index = buf.index; + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::buf.index=%d", __func__, buf.index); +#endif + + return 0; +} + +int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { + LOGE("%s::VIDIOC_STREAMON failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { + LOGE("%s::VIDIOC_STREAMOFF failed", __func__); + return -1; + } + + return 0; +} + +int tvout_v4l2_enum_output(int fd, struct v4l2_output *output) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + int ret = -1 ; + ret = ioctl(fd, VIDIOC_ENUMOUTPUT, output); + + if (ret < 0) { + if (errno == EINVAL) + return -1; + LOGE("%s::VIDIOC_ENUMOUTPUT", __func__); + return -1; + } + LOGD("%s::index=%d, type=0x%08x, name=%s", + __func__, output->index, output->type, output->name); + + return ret; +} + +int tvout_v4l2_s_output(int fd, int index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_S_OUTPUT, &index) < 0) { + LOGE("%s::VIDIOC_S_OUTPUT failed", __func__); + return -1; + } + + return 0; +} + +int tvout_v4l2_g_output(int fd, int *index) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_G_OUTPUT, index) < 0) { + LOGE("%s::VIDIOC_G_OUTPUT failed", __func__); + return -1; + } + + return 0; +} + +int tvout_std_v4l2_enum_dv_presets(int fd) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_dv_enum_preset enum_preset; + int ret = -1; + + for (int index = 0; ; index++) { + enum_preset.index = index; + ret = ioctl(fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset); + + if (ret < 0) { + if (errno == EINVAL) + break; + LOGE("%s::VIDIOC_ENUM_DV_PRESETS", __func__); + return -1; + } + LOGD("%s::index=%d, preset=0x%08x, name=%s, w=%d, h=%d", + __func__, enum_preset.index, enum_preset.preset, enum_preset.name, enum_preset.width, enum_preset.height); + } + + return 0; +} + +int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (ioctl(fd, VIDIOC_S_DV_PRESET, preset) < 0) { + LOGE("%s::VIDIOC_S_DV_PRESET failed preset_id=%d", __func__, preset->preset); + return -1; + } +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::preset_id=%d", __func__, preset->preset); +#endif + return 0; +} + +int tvout_std_subdev_s_fmt(int fd, unsigned int pad, int w, int h, enum v4l2_mbus_pixelcode code) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_subdev_format fmt; + + fmt.pad = pad; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.format.width = w; + fmt.format.height = h; + fmt.format.code = code; + + if (ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_FMT", __func__); + return -1; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::format w=%d, h=%d", __func__, fmt.format.width, fmt.format.height); +#endif + return 0; +} +int tvout_std_subdev_s_crop(int fd, unsigned int pad, int x, int y, int w, int h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::pad=%d, crop x=%d, y=%d, w=%d, h=%d", __func__, pad, x, y, w, h); +#endif + + struct v4l2_subdev_crop crop; + + crop.pad = pad; + crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; + crop.rect.left = x; + crop.rect.top = y; + crop.rect.width = w; + crop.rect.height = h; + + if (ioctl(fd, VIDIOC_SUBDEV_S_CROP, &crop) < 0) { + LOGE("%s::VIDIOC_SUBDEV_S_CROP", __func__); + return -1; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s::pad=%d, crop x=%d, y=%d, w=%d, h=%d", __func__, pad, crop.rect.left, crop.rect.top, crop.rect.width, crop.rect.height); +#endif + + return 0; +} + +#define ROUND_UP(value, boundary) ((((uint32_t)(value)) + \ + (((uint32_t) boundary)-1)) & \ + (~(((uint32_t) boundary)-1))) + +void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect) +{ + if (dst_w * src_h <= dst_h * src_w) { + dst_rect->left = 0; + dst_rect->top = (dst_h - ((dst_w * src_h) / src_w)) >> 1; + dst_rect->width = dst_w; + dst_rect->height = ((dst_w * src_h) / src_w); + } else { + dst_rect->left = (dst_w - ((dst_h * src_w) / src_h)) >> 1; + dst_rect->top = 0; + dst_rect->width = ((dst_h * src_w) / src_h); + dst_rect->height = dst_h; + } +} + +int hdmi_set_videolayer(int fd, int hdmiW, int hdmiH, struct v4l2_rect * rect) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + if (tvout_std_subdev_s_fmt(fd, MIXER_V_SUBDEV_PAD_SINK, hdmiW, hdmiH, V4L2_MBUS_FMT_YUV8_1X24) < 0) { + LOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK); + return -1; + } + + if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SINK, 0, 0, rect->width, rect->height) < 0) { + LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SINK); + return -1; + } + + if (tvout_std_subdev_s_crop(fd, MIXER_V_SUBDEV_PAD_SOURCE, rect->left, rect->top, rect->width, rect->height) < 0) { + LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[videolayer] failed", __func__, MIXER_V_SUBDEV_PAD_SOURCE); + return -1; + } + return 0; +} + +int hdmi_set_graphiclayer(int fd_subdev, int fd_videodev,int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_address, SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif +#if defined(BOARD_USES_HDMI_FIMGAPI) + int dst_color_format; + int dst_bpp; + unsigned char *dst_addr; + fimg2d_blit BlitParam; + rotation g2d_rotation; + + fimg2d_addr srcAddr; + fimg2d_image srcImage; + fimg2d_rect srcRect; + + fimg2d_addr dstAddr; + fimg2d_image dstImage; + fimg2d_rect dstRect; + + fimg2d_clip dstClip; + fimg2d_scale Scaling; + + switch (t_std_id) { + case V4L2_STD_1080P_60: + case V4L2_STD_1080P_30: + case V4L2_STD_1080I_60: + case V4L2_STD_TVOUT_720P_60_SBS_HALF: + case V4L2_STD_TVOUT_720P_59_SBS_HALF: + case V4L2_STD_TVOUT_1080P_24_TB: + case V4L2_STD_TVOUT_1080P_23_TB: + dst_color_format = CF_ARGB_8888; + dst_bpp = 4; + break; + case V4L2_STD_480P_60_16_9: + case V4L2_STD_576P_50_16_9: + case V4L2_STD_720P_60: + case V4L2_STD_TVOUT_720P_50_TB: + default: + dst_color_format = CF_ARGB_4444; + dst_bpp = 2; + break; + } + + static unsigned int prev_src_addr = 0; + + if ((cur_g2d_address == 0) || (src_address != prev_src_addr)) { + if ((cur_g2d_address == 0) || (cur_g2d_address == g2d_reserved_memory1)) + dst_addr = (unsigned char *)g2d_reserved_memory0; + else + dst_addr = (unsigned char *)g2d_reserved_memory1; + + cur_g2d_address = (unsigned int)dst_addr; + prev_src_addr = src_address; + + srcAddr = {(addr_space)ADDR_USER, (unsigned long)src_address, src_w*src_h*4, 1, 0}; + srcImage = {srcAddr, srcAddr, src_w, src_h, src_w*4, AX_RGB, CF_ARGB_8888}; + srcRect = {0, 0, src_w, src_h}; + + dstAddr = {(addr_space)ADDR_USER, (unsigned long)dst_addr, dst_w*dst_h*dst_bpp, 1, 0}; + dstImage = {dstAddr, dstAddr, dst_w, dst_h, dst_w*dst_bpp, AX_RGB, (color_format)dst_color_format}; + dstRect = {0, 0, dst_w, dst_h}; + dstClip = {0, 0, 0, dst_w, dst_h}; + + if (rotVal == 0 || rotVal == 180) + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_w, dst_h}; + else + Scaling = {SCALING_BILINEAR, SCALING_PIXELS, 0, 0, src_w, src_h, dst_h, dst_w}; + + switch (rotVal) { + case 0: + g2d_rotation = ORIGIN; + break; + case 90: + g2d_rotation = ROT_90; + break; + case 180: + g2d_rotation = ROT_180; + break; + case 270: + g2d_rotation = ROT_270; + break; + default: + LOGE("%s::invalid rotVal(%d) : failed", __func__, rotVal); + return -1; + break; + } + + BlitParam = {BLIT_OP_SRC, NON_PREMULTIPLIED, 0xff, 0, g2d_rotation, &Scaling, 0, 0, &dstClip, 0, &srcImage, &dstImage, NULL, &srcRect, &dstRect, NULL, 0}; + + if (stretchFimgApi(&BlitParam) < 0) { + LOGE("%s::stretchFimgApi() failed", __func__); + return -1; + } + + dstBuffer->virt.p = (char *)dst_addr; + } +#else + dstBuffer->virt.p = (char *)src_address; +#endif + + return 0; +} + +int hdmi_set_g_Params(int fd_subdev, int fd_videodev, int layer, + int srcColorFormat, + int src_w, int src_h, + int dst_x, int dst_y, int dst_w, int dst_h) +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + struct v4l2_rect rect; + int src_pad = 0; + int sink_pad = 0; + int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(srcColorFormat); + + switch (layer) { + case HDMI_LAYER_GRAPHIC_0: + sink_pad = MIXER_G0_SUBDEV_PAD_SINK; + src_pad = MIXER_G0_SUBDEV_PAD_SOURCE; + break; + case HDMI_LAYER_GRAPHIC_1: + sink_pad = MIXER_G1_SUBDEV_PAD_SINK; + src_pad = MIXER_G1_SUBDEV_PAD_SOURCE; + break; + default: + LOGE("%s::invalid layer(%d)", __func__, layer); + break; + }; + + rect.left = dst_x; + rect.top = dst_y; + +#if defined(BOARD_USES_HDMI_FIMGAPI) + rect.width = dst_w; + rect.height = dst_h; +#else + rect.width = src_w; + rect.height = src_h; +#endif + + /* set sub device for mixer graphic layer input */ + if (tvout_std_subdev_s_fmt(fd_subdev, sink_pad, rect.width, rect.height, V4L2_MBUS_FMT_XRGB8888_4X8_LE) < 0) { + LOGE("%s::tvout_std_subdev_s_fmt(PAD=%d)[graphic layer] failed", __func__, sink_pad); + return -1; + } + + if (tvout_std_subdev_s_crop(fd_subdev, sink_pad, 0, 0, rect.width, rect.height) < 0) { + LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, sink_pad); + return -1; + } + + if (tvout_std_subdev_s_crop(fd_subdev, src_pad, rect.left, rect.top, rect.width, rect.height) < 0) { + LOGE("%s::tvout_std_subdev_s_crop(PAD=%d)[graphic layer] failed", __func__, src_pad); + return -1; + } + + /* set format for mixer graphic layer input device*/ + if (tvout_std_v4l2_s_fmt(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.width, rect.height, v4l2ColorFormat, 1) < 0) { + LOGE("%s::tvout_std_v4l2_s_fmt()[graphic layer] failed", __func__); + return -1; + } + + if (tvout_std_v4l2_s_crop(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_ANY, rect.left, rect.top, rect.width, rect.height) < 0) { + LOGE("%s::tvout_std_v4l2_s_crop()[graphic layer] failed", __func__); + return -1; + } + + /* request buffer for mixer graphic layer input device */ + if (tvout_std_v4l2_reqbuf(fd_videodev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_USERPTR, 2) < 0) { + LOGE("%s::tvout_std_v4l2_reqbuf(buf_num=%d)[graphic layer] failed", __func__, 2); + return -1; + } + + return 0; +} + +int hdmi_cable_status() +{ +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("%s", __func__); +#endif + + int cable_status = 0; + int fd = 0; + struct v4l2_control ctrl; + + fd = open(TVOUT0_DEV_G0, O_RDWR); + if (fd <= 0) { + LOGE("%s: graphic layer 0 drv open failed", __func__); + return -1; + } + + ctrl.id = V4L2_CID_TV_HPD_STATUS; + + if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) { + LOGE("Get HPD_STATUS fail"); + cable_status = -1; + } else { + cable_status = ctrl.value; + } + +#ifdef DEBUG_HDMI_HW_LEVEL + LOGD("HPD_STATUS = %d", cable_status); +#endif + + close(fd); + + return cable_status; +} + +int hdmi_outputmode_2_v4l2_output_type(int output_mode) +{ + int v4l2_output_type = -1; + + switch (output_mode) { + case HDMI_OUTPUT_MODE_YCBCR: + v4l2_output_type = V4L2_OUTPUT_TYPE_DIGITAL; + break; + case HDMI_OUTPUT_MODE_RGB: + v4l2_output_type = V4L2_OUTPUT_TYPE_HDMI_RGB; + break; + case HDMI_OUTPUT_MODE_DVI: + v4l2_output_type = V4L2_OUTPUT_TYPE_DVI; + break; + case COMPOSITE_OUTPUT_MODE: + v4l2_output_type = V4L2_OUTPUT_TYPE_COMPOSITE; + break; + default: + LOGE("%s::unmathced HDMI_mode(%d)", __func__, output_mode); + v4l2_output_type = -1; + break; + } + + return v4l2_output_type; +} + +int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type) +{ + int outputMode = -1; + + switch (v4l2_output_type) { + case V4L2_OUTPUT_TYPE_DIGITAL: + outputMode = HDMI_OUTPUT_MODE_YCBCR; + break; + case V4L2_OUTPUT_TYPE_HDMI_RGB: + outputMode = HDMI_OUTPUT_MODE_RGB; + break; + case V4L2_OUTPUT_TYPE_DVI: + outputMode = HDMI_OUTPUT_MODE_DVI; + break; + case V4L2_OUTPUT_TYPE_COMPOSITE: + outputMode = COMPOSITE_OUTPUT_MODE; + break; + default: + LOGE("%s::unmathced v4l2_output_type(%d)", __func__, v4l2_output_type); + outputMode = -1; + break; + } + + return outputMode; +} + +int composite_std_2_v4l2_std_id(int std) +{ + int std_id = -1; + + switch (std) { + case COMPOSITE_STD_NTSC_M: + std_id = V4L2_STD_NTSC_M; + break; + case COMPOSITE_STD_NTSC_443: + std_id = V4L2_STD_NTSC_443; + break; + case COMPOSITE_STD_PAL_BDGHI: + std_id = V4L2_STD_PAL_BDGHI; + break; + case COMPOSITE_STD_PAL_M: + std_id = V4L2_STD_PAL_M; + break; + case COMPOSITE_STD_PAL_N: + std_id = V4L2_STD_PAL_N; + break; + case COMPOSITE_STD_PAL_Nc: + std_id = V4L2_STD_PAL_Nc; + break; + case COMPOSITE_STD_PAL_60: + std_id = V4L2_STD_PAL_60; + break; + default: + LOGE("%s::unmathced composite_std(%d)", __func__, std); + break; + } + + return std_id; +} + +int hdmi_check_output_mode(int v4l2_output_type) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + int calbirate_v4l2_mode = v4l2_output_type; + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + + switch (v4l2_output_type) { + case V4L2_OUTPUT_TYPE_DIGITAL : + video.mode = HDMI; + if (!EDIDHDMIModeSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; + LOGI("Change mode into DVI\n"); + break; + } + + video.colorSpace = HDMI_CS_YCBCR444; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; + LOGI("Change mode into HDMI_RGB\n"); + } + break; + + case V4L2_OUTPUT_TYPE_HDMI_RGB: + video.mode = HDMI; + if (!EDIDHDMIModeSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DVI; + LOGI("Change mode into DVI\n"); + break; + } + + video.colorSpace = HDMI_CS_RGB; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; + LOGI("Change mode into HDMI_YCBCR\n"); + } + break; + + case V4L2_OUTPUT_TYPE_DVI: + video.mode = DVI; + if (!EDIDHDMIModeSupport(&video)) { + video.colorSpace = HDMI_CS_YCBCR444; + if (!EDIDColorSpaceSupport(&video)) { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_HDMI_RGB; + LOGI("Change mode into HDMI_RGB\n"); + } else { + calbirate_v4l2_mode = V4L2_OUTPUT_TYPE_DIGITAL; + LOGI("Change mode into HDMI_YCBCR\n"); + } + break; + } + + break; + + default: + break; + } + return calbirate_v4l2_mode; +} + +int hdmi_check_resolution(v4l2_std_id std_id) +{ + struct HDMIVideoParameter video; + struct HDMIAudioParameter audio; + + switch (std_id) { + case V4L2_STD_480P_60_16_9: + video.resolution = v720x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_480P_60_4_3: + video.resolution = v640x480p_60Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_576P_50_16_9: + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_16_9; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_576P_50_4_3: + video.resolution = v720x576p_50Hz; + video.pixelAspectRatio = HDMI_PIXEL_RATIO_4_3; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_60: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_50: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_60: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_50: + video.resolution = v1920x1080p_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_60: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_50: + video.resolution = v1920x1080i_50Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_480P_59: + video.resolution = v720x480p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_720P_59: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080I_59: + video.resolution = v1920x1080i_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_59: + video.resolution = v1920x1080p_60Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_1080P_30: + video.resolution = v1920x1080p_30Hz; + video.hdmi_3d_format = HDMI_2D_VIDEO_FORMAT; + break; + case V4L2_STD_TVOUT_720P_60_SBS_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_STD_TVOUT_720P_59_SBS_HALF: + video.resolution = v1280x720p_60Hz; + video.hdmi_3d_format = HDMI_3D_SSH_FORMAT; + break; + case V4L2_STD_TVOUT_720P_50_TB: + video.resolution = v1280x720p_50Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_STD_TVOUT_1080P_24_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + case V4L2_STD_TVOUT_1080P_23_TB: + video.resolution = v1920x1080p_24Hz; + video.hdmi_3d_format = HDMI_3D_TB_FORMAT; + break; + default: + LOGE("%s::unmathced std_id(%lld)", __func__, std_id); + return -1; + break; + } + + if (!EDIDVideoResolutionSupport(&video)) { +#ifdef DEBUG_MSG_ENABLE + LOGD("%s::EDIDVideoResolutionSupport(%llx) fail (not suppoted std_id) \n", __func__, std_id); +#endif + return -1; + } + + return 0; +} + +int hdmi_resolution_2_std_id(unsigned int resolution, int * w, int * h, v4l2_std_id * std_id, __u32 *preset_id) +{ + int ret = 0; + + switch (resolution) { + case 1080960: + *std_id = V4L2_STD_1080P_60; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P60; + break; + case 1080950: + *std_id = V4L2_STD_1080P_50; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P50; + break; + case 1080930: + *std_id = V4L2_STD_1080P_30; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P30; + break; + case 1080924: + *std_id = V4L2_STD_TVOUT_1080P_24_TB; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080P24_TB; + break; + case 1080160: + *std_id = V4L2_STD_1080I_60; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080I60; + break; + case 1080150: + *std_id = V4L2_STD_1080I_50; + *w = 1920; + *h = 1080; + *preset_id = V4L2_DV_1080I50; + break; + case 720960: + *std_id = V4L2_STD_720P_60; + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P60; + break; + case 7209601: + *std_id = V4L2_STD_TVOUT_720P_60_SBS_HALF; + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P60_SB_HALF; + break; + case 720950: + *std_id = V4L2_STD_720P_50; + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P50; + break; + case 7209501: + *std_id = V4L2_STD_TVOUT_720P_50_TB; + *w = 1280; + *h = 720; + *preset_id = V4L2_DV_720P50_TB; + break; + case 5769501: + *std_id = V4L2_STD_576P_50_16_9; + *w = 720; + *h = 576; + *preset_id = V4L2_DV_576P50; + break; + case 5769502: + *std_id = V4L2_STD_576P_50_4_3; + *w = 720; + *h = 576; + *preset_id = V4L2_DV_576P50; + break; + case 4809601: + *std_id = V4L2_STD_480P_60_16_9; + *w = 720; + *h = 480; + *preset_id = V4L2_DV_480P60; + break; + case 4809602: + *std_id = V4L2_STD_480P_60_4_3; + *w = 720; + *h = 480; + *preset_id = V4L2_DV_480P60; + break; + default: + LOGE("%s::unmathced resolution(%d)", __func__, resolution); + ret = -1; + break; + } + + return ret; +} + +int hdmi_enable_hdcp(int fd, unsigned int hdcp_en) +{ + if (ioctl(fd, VIDIOC_HDCP_ENABLE, hdcp_en) < 0) { + LOGD("%s::VIDIOC_HDCP_ENABLE(%d) fail \n", __func__, hdcp_en); + return -1; + } + + return 0; +} + +int hdmi_check_audio(int fd) +{ + struct HDMIAudioParameter audio; + enum state audio_state = ON; + int ret = 0; + + audio.formatCode = LPCM_FORMAT; + audio.outPacket = HDMI_ASP; + audio.channelNum = CH_2; + audio.sampleFreq = SF_44KHZ; + +#if defined(BOARD_USES_EDID) + if (!EDIDAudioModeSupport(&audio)) + audio_state = NOT_SUPPORT; + else + audio_state = ON; +#endif + if (audio_state == ON) { + if (ioctl(fd, VIDIOC_INIT_AUDIO, 1) < 0) { + LOGE("%s::VIDIOC_INIT_AUDIO(1) failed", __func__); + ret = -1; + } + } else { + if (ioctl(fd, VIDIOC_INIT_AUDIO, 0) < 0) { + LOGE("%s::VIDIOC_INIT_AUDIO(0) failed", __func__); + ret = -1; + } + } + + return ret; +} + +} diff --git a/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h b/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h new file mode 100644 index 0000000..67c0729 --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/SecHdmiV4L2Utils.h @@ -0,0 +1,86 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HDMI_HAL_V4L2_UTILS_H__ +#define __HDMI_HAL_V4L2_UTILS_H__ + +//#define LOG_NDEBUG 0 +//#define LOG_TAG "libhdmi" + +#include "fimd_api.h" +#include "SecBuffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +namespace android { + +void display_menu(void); + +int tvout_init(int fd_tvout, __u32 preset_id); +int tvout_deinit(); +int tvout_std_v4l2_querycap(int fd, char *node); +int tvout_std_v4l2_s_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, int w, int h, int colorformat, int num_planes); +int tvout_std_v4l2_s_crop(int fd, enum v4l2_buf_type type, enum v4l2_field field, int x, int y, int w, int h); +int tvout_std_v4l2_s_ctrl(int fd, int id, int value); +int tvout_std_v4l2_reqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs); +int tvout_std_v4l2_querybuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, unsigned int num_planes, SecBuffer *secBuf); +int tvout_std_v4l2_qbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int buf_index, int num_planes, SecBuffer *secBuf); +int tvout_std_v4l2_dqbuf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_index, int num_planes); +int tvout_std_v4l2_streamon(int fd, enum v4l2_buf_type type); +int tvout_std_v4l2_streamoff(int fd, enum v4l2_buf_type type); + +int tvout_v4l2_enum_output(int fp, struct v4l2_output *output); +int tvout_v4l2_s_output(int fp, int index); +int tvout_v4l2_g_output(int fp, int *index); +int tvout_std_v4l2_enum_dv_presets(int fd); +int tvout_std_v4l2_s_dv_preset(int fd, struct v4l2_dv_preset *preset); +int tvout_std_subdev_s_fmt(int fd, unsigned int pad, int w, int h, enum v4l2_mbus_pixelcode code); +int tvout_std_subdev_s_crop(int fd, unsigned int pad, int w, int h, int x, int y); + +void hdmi_cal_rect(int src_w, int src_h, int dst_w, int dst_h, struct v4l2_rect *dst_rect); +int hdmi_set_videolayer(int fd, int hdmiW, int hdmiH, struct v4l2_rect * rect); +int hdmi_set_graphiclayer(int fd_subdev, int fd_videodev,int layer, + int srcColorFormat, + int src_w, int src_h, + unsigned int src_address, SecBuffer * dstBuffer, + int dst_x, int dst_y, int dst_w, int dst_h, + int rotVal); +int hdmi_set_g_Params(int fd_subdev, int fd_videodev, int layer, + int srcColorFormat, + int src_w, int src_h, + int dst_x, int dst_y, int dst_w, int dst_h); + +int hdmi_cable_status(); +int hdmi_outputmode_2_v4l2_output_type(int output_mode); +int hdmi_v4l2_output_type_2_outputmode(int v4l2_output_type); +int composite_std_2_v4l2_std_id(int std); + +int hdmi_check_output_mode(int v4l2_output_type); +int hdmi_check_resolution(v4l2_std_id std_id); + +int hdmi_resolution_2_std_id(unsigned int resolution, int *w, int *h, v4l2_std_id *std_id, __u32 *preset_id); +int hdmi_enable_hdcp(int fd, unsigned int hdcp_en); +int hdmi_check_audio(int fd); + +#ifdef __cplusplus +} +#endif + +} //namespace android + +#endif //__HDMI_HAL_V4L2_UTILS_H__ diff --git a/exynos5/hal/libhdmi/SecHdmi/fimd_api.c b/exynos5/hal/libhdmi/SecHdmi/fimd_api.c new file mode 100644 index 0000000..0e07ef3 --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/fimd_api.c @@ -0,0 +1,229 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fimd_api.h" + +int fb_open(int win) +{ + char node[20]; + int fp = -1; + + sprintf(node, "%s%d", PFX_NODE_FB, win); + + fp = open(node, O_RDWR); + if (fp < 0) + LOGE("%s: fb[%d] open failed", __func__, win); + + return fp; +} + +int fb_close(int fp) +{ + if (fp) + close(fp); + else + LOGE("%s: fb is not allocated %d", __func__, fp); + + return 0; +} + +int get_fscreeninfo(int fp, struct fb_fix_screeninfo *fix) +{ + int ret = -1; + + ret = ioctl(fp, FBIOGET_FSCREENINFO, fix); + if (ret) + LOGE("%s: FBIOGET_FSCREENINFO failed", __func__); + + return ret; +} + +int get_vscreeninfo(int fp, struct fb_var_screeninfo *var) +{ + int ret = -1; + + ret = ioctl(fp, FBIOGET_VSCREENINFO, var); + if (ret) + LOGE("%s:: FBIOGET_VSCREENINFO failed", __func__); + + return ret; +} + +int put_vscreeninfo(int fp, struct fb_var_screeninfo *var) +{ + int ret = -1; + + ret = ioctl(fp, FBIOPUT_VSCREENINFO, var); + if (ret) + LOGE("%s:: FBIOPUT_VSCREENINFO failed", __func__); + + return ret; +} + +int get_bytes_per_pixel(int bits_per_pixel) +{ + return (bits_per_pixel == 24 || bits_per_pixel == 25 || + bits_per_pixel == 28) ? 4 : bits_per_pixel / 8; +} + +char *fb_mmap(__u32 size, int fp) +{ + char *buffer; + + buffer = (char *)mmap(0, size, PROT_READ | PROT_WRITE, + MAP_SHARED, fp, 0); + if (!buffer) { + LOGE("%s:: mmap failed", __func__); + return NULL; + } + + return buffer; +} + +int fb_ioctl(int fp, __u32 cmd, void *arg) +{ + int ret = -1; + + ret = ioctl(fp, cmd, arg); + if (ret < 0) + LOGE("%s:: ioctl (%d) failed", __func__, cmd); + + return ret; +} + +int fb_on(int fp) +{ + int ret = -1; + + ret = ioctl(fp, FBIOBLANK, FB_BLANK_UNBLANK); + if (ret) + LOGE("%s:: FBIOBLANK failed", __func__); + + return ret; +} + +int fb_off(int fp) +{ + int ret = -1; + + ret = ioctl(fp, FBIOBLANK, FB_BLANK_POWERDOWN); + if (ret) + LOGE("%s:: FBIOBLANK failed", __func__); + + return ret; +} + +int fb_off_all() +{ + int fp, i; + + for (i = 0; i < TOTAL_FB_NUM; i++) { + fp = fb_open(i); + if (fp < 0) + return -1; + + if (ioctl(fp, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) + LOGE("%s:: FBIOBLANK failed", __func__); + + fb_off(fp); + fb_close(fp); + } + + return 0; +} + +char *fb_init_display(int fp, int width, int height, int left_x, int top_y, + int bpp) +{ + struct fb_var_screeninfo var; + struct s5ptvfb_user_window window; + int fb_size; + char *fb = NULL; + + var.xres = width; + var.yres = height; + var.bits_per_pixel = bpp; + window.x = left_x; + window.y = top_y; + + var.xres_virtual = var.xres; + var.yres_virtual = var.yres; + var.xoffset = 0; + var.yoffset = 0; + var.width = 0; + var.height = 0; + var.transp.length = 0; + var.activate = FB_ACTIVATE_FORCE; + fb_size = var.xres_virtual * var.yres_virtual * bpp / 8; + + /* FBIOPUT_VSCREENINFO should be first */ + put_vscreeninfo(fp, &var); + fb_ioctl(fp, S5PTVFB_WIN_POSITION, &window); + + /* draw image */ + fb = fb_mmap(fb_size, fp); + memset(fb, 0x0, fb_size); + + return fb; +} + +int simple_draw(char *dest, const char *src, int img_width, + struct fb_var_screeninfo *var) +{ + int bytes_per_pixel = get_bytes_per_pixel(var->bits_per_pixel); + unsigned int y; + + for (y = 0; y < var->yres; y++) + memcpy(dest + y * var->xres * bytes_per_pixel, + src + y * img_width * bytes_per_pixel, + var->xres * bytes_per_pixel); + + return 0; +} + +int draw(char *dest, const char *src, int img_width, + struct fb_var_screeninfo *var) +{ + int bytes_per_pixel = get_bytes_per_pixel(var->bits_per_pixel); + unsigned int y; + + if (var->bits_per_pixel == 16) { + memcpy(dest, src, var->xres * var->yres * 2); + } else { + for (y = 0; y < var->yres; y++) + memcpy(dest + y * var->xres * bytes_per_pixel, + src + y * img_width * bytes_per_pixel, + var->xres * bytes_per_pixel); + } + + return 0; +} diff --git a/exynos5/hal/libhdmi/SecHdmi/fimd_api.h b/exynos5/hal/libhdmi/SecHdmi/fimd_api.h new file mode 100644 index 0000000..a8561a4 --- /dev/null +++ b/exynos5/hal/libhdmi/SecHdmi/fimd_api.h @@ -0,0 +1,51 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FIMD_API_H__ +#define __FIMD_API_H__ + +#include +#include "s5p_tvout.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TOTAL_FB_NUM 5 + +int fb_open(int win); +int fb_close(int fp); +int fb_on(int fp); +int fb_off(int fp); +int fb_off_all(void); +char *fb_init_display(int fp, int width, int height,\ + int left_x, int top_y, int bpp); +int fb_ioctl(int fp, __u32 cmd, void *arg); +char *fb_mmap(__u32 size, int fp); +int simple_draw(char *dest, const char *src,\ + int img_width, struct fb_var_screeninfo *var); +int draw(char *dest, const char *src,\ + int img_width, struct fb_var_screeninfo *var); +int get_fscreeninfo(int fp, struct fb_fix_screeninfo *fix); +int get_vscreeninfo(int fp, struct fb_var_screeninfo *var); +int put_vscreeninfo(int fp, struct fb_var_screeninfo *var); +int get_bytes_per_pixel(int bits_per_pixel); + +#ifdef __cplusplus +} +#endif + +#endif /* __FIMD_API_H__ */ diff --git a/exynos5/hal/libhdmi/libhdmiservice/Android.mk b/exynos5/hal/libhdmi/libhdmiservice/Android.mk new file mode 100644 index 0000000..bc0aa0d --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/Android.mk @@ -0,0 +1,95 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) + +# +# libTVOut +# + +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES := \ + SecTVOutService.cpp \ + ISecTVOut.cpp \ + MessageQueue.cpp + +LOCAL_C_INCLUDES := \ + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libcutils + +LOCAL_C_INCLUDES += device/samsung/$(TARGET_BOARD_PLATFORM)/include +LOCAL_C_INCLUDES += device/samsung/$(TARGET_BOARD_PLATFORM)/libhdmi +LOCAL_SHARED_LIBRARIES += libhdmi + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +LOCAL_MODULE := libTVOut + +include $(BUILD_SHARED_LIBRARY) + +# +# libhdmiclient +# + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES:= \ + SecHdmiClient.cpp + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libTVOut + +ifeq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_OS),linux) +ifeq ($(TARGET_ARCH),x86) +LOCAL_LDLIBS += -lpthread -ldl -lrt +endif +endif +endif + +ifeq ($(WITH_MALLOC_LEAK_CHECK),true) + LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK +endif + +ifeq ($(TARGET_SOC),exynos5250) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250 +endif + +LOCAL_CFLAGS += -DBOARD_USES_HDMI + +LOCAL_MODULE:= libhdmiclient + +include $(BUILD_SHARED_LIBRARY) + +endif +endif diff --git a/exynos5/hal/libhdmi/libhdmiservice/Barrier.h b/exynos5/hal/libhdmi/libhdmiservice/Barrier.h new file mode 100644 index 0000000..6f8507e --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/Barrier.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BARRIER_H +#define ANDROID_BARRIER_H + +#include +#include +#include + +namespace android { + +class Barrier +{ +public: + inline Barrier() : state(CLOSED) { } + inline ~Barrier() { } + void open() { + Mutex::Autolock _l(lock); + state = OPENED; + cv.broadcast(); + } + void close() { + Mutex::Autolock _l(lock); + state = CLOSED; + } + void wait() const { + Mutex::Autolock _l(lock); + while (state == CLOSED) { + cv.wait(lock); + } + } +private: + enum { OPENED, CLOSED }; + mutable Mutex lock; + mutable Condition cv; + volatile int state; +}; + +}; // namespace android + +#endif // ANDROID_BARRIER_H diff --git a/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.cpp b/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.cpp new file mode 100644 index 0000000..a013bf1 --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.cpp @@ -0,0 +1,111 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#include +#include +#include +#include +#include "ISecTVOut.h" + +namespace android { + + enum { + SET_HDMI_STATUS = IBinder::FIRST_CALL_TRANSACTION, + SET_HDMI_MODE, + SET_HDMI_RESOLUTION, + SET_HDMI_HDCP, + SET_HDMI_ROTATE, + SET_HDMI_HWCLAYER, + BLIT_2_HDMI + }; + + void BpSecTVOut::setHdmiCableStatus(uint32_t status) + { + Parcel data, reply; + data.writeInt32(status); + remote()->transact(SET_HDMI_STATUS, data, &reply); + } + + void BpSecTVOut::setHdmiMode(uint32_t mode) + { + Parcel data, reply; + data.writeInt32(mode); + remote()->transact(SET_HDMI_MODE, data, &reply); + } + + void BpSecTVOut::setHdmiResolution(uint32_t resolution) + { + Parcel data, reply; + data.writeInt32(resolution); + remote()->transact(SET_HDMI_RESOLUTION, data, &reply); + } + + void BpSecTVOut::setHdmiHdcp(uint32_t resolution) + { + Parcel data, reply; + data.writeInt32(resolution); + remote()->transact(SET_HDMI_HDCP, data, &reply); + } + + void BpSecTVOut::setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) + { + Parcel data, reply; + data.writeInt32(rotVal); + data.writeInt32(hwcLayer); + remote()->transact(SET_HDMI_ROTATE, data, &reply); + } + + void BpSecTVOut::setHdmiHwcLayer(uint32_t hwcLayer) + { + Parcel data, reply; + data.writeInt32(hwcLayer); + remote()->transact(SET_HDMI_HWCLAYER, data, &reply); + } + + void BpSecTVOut::blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) + { + Parcel data, reply; + data.writeInt32(w); + data.writeInt32(h); + data.writeInt32(colorFormat); + data.writeInt32(physYAddr); + data.writeInt32(physCbAddr); + data.writeInt32(physCrAddr); + data.writeInt32(dstX); + data.writeInt32(dstY); + data.writeInt32(hdmiLayer); + data.writeInt32(num_of_hwc_layer); + remote()->transact(BLIT_2_HDMI, data, &reply); + } + + IMPLEMENT_META_INTERFACE(SecTVOut, "android.os.ISecTVOut"); +}; diff --git a/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.h b/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.h new file mode 100644 index 0000000..5506b57 --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/ISecTVOut.h @@ -0,0 +1,74 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef ISECTVOUT_H +#define ISECTVOUT_H +#include +#include +#include + +namespace android { + class ISecTVOut: public IInterface + { + public: + DECLARE_META_INTERFACE(SecTVOut); + virtual void setHdmiCableStatus(uint32_t status) = 0; + virtual void setHdmiMode(uint32_t mode) = 0; + virtual void setHdmiResolution(uint32_t resolution) = 0; + virtual void setHdmiHdcp(uint32_t enHdcp) = 0; + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) = 0; + virtual void setHdmiHwcLayer(uint32_t hwcLayer) = 0; + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) = 0; + }; + //-------------------------------------------------------------- + class BpSecTVOut: public BpInterface + { + public: + BpSecTVOut(const sp& impl): BpInterface(impl){} + virtual void setHdmiCableStatus(uint32_t status); + virtual void setHdmiMode(uint32_t mode); + virtual void setHdmiResolution(uint32_t resolution); + virtual void setHdmiHdcp(uint32_t enHdcp); + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer); + virtual void setHdmiHwcLayer(uint32_t hwcLayer); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer); + }; +}; +#endif diff --git a/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.cpp b/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.cpp new file mode 100644 index 0000000..fb58ef9 --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "MessageQueue.h" + +namespace android { + +void MessageList::insert(const sp& node) +{ + LIST::iterator cur(mList.begin()); + LIST::iterator end(mList.end()); + while (cur != end) { + if (*node < **cur) { + mList.insert(cur, node); + return; + } + ++cur; + } + mList.insert(++end, node); +} + +void MessageList::remove(MessageList::LIST::iterator pos) +{ + mList.erase(pos); +} + +MessageQueue::MessageQueue() + : mInvalidate(false) +{ + mInvalidateMessage = new MessageBase(INVALIDATE); +} + +MessageQueue::~MessageQueue() +{ +} + +sp MessageQueue::waitMessage(nsecs_t timeout) +{ + sp result; + + bool again; + do { + const nsecs_t timeoutTime = systemTime() + timeout; + while (true) { + Mutex::Autolock _l(mLock); + nsecs_t now = systemTime(); + nsecs_t nextEventTime = -1; + + LIST::iterator cur(mMessages.begin()); + if (cur != mMessages.end()) { + result = *cur; + } + + if (result != 0) { + if (result->when <= now) { + // there is a message to deliver + mMessages.remove(cur); + break; + } + nextEventTime = result->when; + result = 0; + } + + // see if we have an invalidate message + if (mInvalidate) { + mInvalidate = false; + mInvalidateMessage->when = now; + result = mInvalidateMessage; + break; + } + + if (timeout >= 0) { + if (timeoutTime < now) { + // we timed-out, return a NULL message + result = 0; + break; + } + if (nextEventTime > 0) { + if (nextEventTime > timeoutTime) { + nextEventTime = timeoutTime; + } + } else { + nextEventTime = timeoutTime; + } + } + + if (nextEventTime >= 0) { + //LOGD("nextEventTime = %lld ms", nextEventTime); + if (nextEventTime > 0) { + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + const nsecs_t reltime = nextEventTime - systemTime(); + if (reltime > 0) { + mCondition.waitRelative(mLock, reltime); + } + } + } else { + //LOGD("going to wait"); + // we're about to wait, flush the binder command buffer + IPCThreadState::self()->flushCommands(); + mCondition.wait(mLock); + } + } + // here we're not holding the lock anymore + + if (result == 0) + break; + + again = result->handler(); + if (again) { + // the message has been processed. release our reference to it + // without holding the lock. + result->notify(); + result = 0; + } + } while (again); + + return result; +} + +status_t MessageQueue::postMessage( + const sp& message, nsecs_t relTime, uint32_t flags) +{ + return queueMessage(message, relTime, flags); +} + +status_t MessageQueue::invalidate() { + Mutex::Autolock _l(mLock); + mInvalidate = true; + mCondition.signal(); + return NO_ERROR; +} + +status_t MessageQueue::queueMessage( + const sp& message, nsecs_t relTime, uint32_t flags) +{ + Mutex::Autolock _l(mLock); + message->when = systemTime() + relTime; + mMessages.insert(message); + + //LOGD("MessageQueue::queueMessage time = %lld ms", message->when); + //dumpLocked(message); + + mCondition.signal(); + return NO_ERROR; +} + +void MessageQueue::dump(const sp& message) +{ + Mutex::Autolock _l(mLock); + dumpLocked(message); +} + +void MessageQueue::dumpLocked(const sp& message) +{ + LIST::const_iterator cur(mMessages.begin()); + LIST::const_iterator end(mMessages.end()); + int c = 0; + while (cur != end) { + const char tick = (*cur == message) ? '>' : ' '; + LOGD("%c %d: msg{.what=%08x, when=%lld}", + tick, c, (*cur)->what, (*cur)->when); + ++cur; + c++; + } +} + +}; // namespace android diff --git a/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.h b/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.h new file mode 100644 index 0000000..4fc752f --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/MessageQueue.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MESSAGE_QUEUE_H +#define ANDROID_MESSAGE_QUEUE_H + +#include +#include +#include + +#include +#include +#include + +#include "Barrier.h" + +namespace android { + +class MessageBase; + +class MessageList +{ + List< sp > mList; + typedef List< sp > LIST; +public: + inline LIST::iterator begin() { return mList.begin(); } + inline LIST::const_iterator begin() const { return mList.begin(); } + inline LIST::iterator end() { return mList.end(); } + inline LIST::const_iterator end() const { return mList.end(); } + inline bool isEmpty() const { return mList.empty(); } + void insert(const sp& node); + void remove(LIST::iterator pos); +}; + +class MessageBase : + public LightRefBase +{ +public: + nsecs_t when; + uint32_t what; + int32_t arg0; + + MessageBase() : when(0), what(0), arg0(0) { } + MessageBase(uint32_t what, int32_t arg0=0) + : when(0), what(what), arg0(arg0) { } + + // return true if message has a handler + virtual bool handler() { return false; } + + // waits for the handler to be processed + void wait() const { barrier.wait(); } + + // releases all waiters. this is done automatically if + // handler returns true + void notify() const { barrier.open(); } + +protected: + virtual ~MessageBase() { } + +private: + mutable Barrier barrier; + friend class LightRefBase; +}; + +inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { + return lhs.when < rhs.when; +} + +class MessageQueue +{ + typedef List< sp > LIST; +public: + + MessageQueue(); + ~MessageQueue(); + + // pre-defined messages + enum { + INVALIDATE = '_upd' + }; + + sp waitMessage(nsecs_t timeout = -1); + + status_t postMessage(const sp& message, + nsecs_t reltime=0, uint32_t flags = 0); + + status_t invalidate(); + + void dump(const sp& message); + +private: + status_t queueMessage(const sp& message, + nsecs_t reltime, uint32_t flags); + void dumpLocked(const sp& message); + + Mutex mLock; + Condition mCondition; + MessageList mMessages; + bool mInvalidate; + sp mInvalidateMessage; +}; + +}; // namespace android + +#endif /* ANDROID_MESSAGE_QUEUE_H */ diff --git a/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp b/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp new file mode 100644 index 0000000..150aadf --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.cpp @@ -0,0 +1,139 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#define LOG_TAG "libhdmiclient" + +#include "SecHdmiClient.h" + +namespace android { + +static sp g_SecTVOutService = 0; + +SecHdmiClient::SecHdmiClient() +{ + g_SecTVOutService = m_getSecTVOutService(); +} + +SecHdmiClient::~SecHdmiClient() +{ +} + +SecHdmiClient * SecHdmiClient::getInstance(void) +{ + static SecHdmiClient singleton; + return &singleton; +} + +void SecHdmiClient::setHdmiCableStatus(int status) +{ + LOGD("%s HDMI status: %d\n", __func__, status); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiCableStatus(status); +} + +void SecHdmiClient::setHdmiMode(int mode) +{ + //LOGD("%s HDMI Mode: %d\n", __func__, mode); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiMode(mode); +} + +void SecHdmiClient::setHdmiResolution(int resolution) +{ + //LOGD("%s HDMI Resolution: %d\n", __func__, resolution); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiResolution(resolution); +} + +void SecHdmiClient::setHdmiHdcp(int enHdcp) +{ + //LOGD("%s HDMI HDCP: %d\n", __func__, enHdcp); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiHdcp(enHdcp); +} + +void SecHdmiClient::setHdmiRotate(int rotVal, uint32_t hwcLayer) +{ + //LOGD("%s HDMI ROTATE: %d\n", __func__, rotVal); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiRotate(rotVal, hwcLayer); +} + +void SecHdmiClient::setHdmiHwcLayer(uint32_t hwcLayer) +{ + //LOGD("%s HDMI HWCLAYER: %d\n", __func__, hwcLayer); + + if (g_SecTVOutService != 0) + g_SecTVOutService->setHdmiHwcLayer(hwcLayer); +} + +void SecHdmiClient::blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer) +{ + if (g_SecTVOutService != 0 ) + g_SecTVOutService->blit2Hdmi(w, h, colorFormat, physYAddr, physCbAddr, physCrAddr, dstX, dstY, hdmiLayer, num_of_hwc_layer); +} + +sp SecHdmiClient::m_getSecTVOutService(void) +{ + int ret = 0; + + if (g_SecTVOutService == 0) { + sp binder; + sp sc; + sp sm = defaultServiceManager(); + int getSvcTimes = 0; + for(getSvcTimes = 0; getSvcTimes < GETSERVICETIMEOUT; getSvcTimes++) { + binder = sm->getService(String16("SecTVOutService")); + if (binder == 0) { + LOGW("SecTVOutService not published, waiting..."); + usleep(500000); // 0.5 s + } else { + break; + } + } + // grab the lock again for updating g_surfaceFlinger + if (getSvcTimes < GETSERVICETIMEOUT) { + sc = interface_cast(binder); + g_SecTVOutService = sc; + } else { + LOGW("Failed to get SecTVOutService... SecHdmiClient will get it later.."); + } + } + return g_SecTVOutService; +} + +} diff --git a/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.h b/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.h new file mode 100644 index 0000000..e94e19a --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/SecHdmiClient.h @@ -0,0 +1,84 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef __SEC_HDMI_CLIENT_H__ +#define __SEC_HDMI_CLIENT_H__ + +#include "utils/Log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ISecTVOut.h" + +#define GETSERVICETIMEOUT (5) + +namespace android { + +class SecHdmiClient +{ +public: + enum HDMI_MODE + { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + +private: + SecHdmiClient(); + virtual ~SecHdmiClient(); + +public: + static SecHdmiClient * getInstance(void); + void setHdmiCableStatus(int status); + void setHdmiMode(int mode); + void setHdmiResolution(int resolution); + void setHdmiHdcp(int enHdcp); + void setHdmiRotate(int rotVal, uint32_t hwcLayer); + void setHdmiHwcLayer(uint32_t hwcLayer); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t physYAddr, + uint32_t physCbAddr, + uint32_t physCrAddr, + uint32_t dstX, + uint32_t dstY, + uint32_t hdmiLayer, + uint32_t num_of_hwc_layer); + +private: + sp m_getSecTVOutService(void); + +}; + +}; + +#endif diff --git a/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.cpp b/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.cpp new file mode 100644 index 0000000..39ef742 --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.cpp @@ -0,0 +1,377 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#define LOG_TAG "SecTVOutService" + +#include +#include +#include +#include +#include +#include "SecTVOutService.h" +#include + +namespace android { +#define DEFAULT_LCD_WIDTH 1280 +#define DEFAULT_LCD_HEIGHT 800 + +#define DIRECT_VIDEO_RENDERING (1) +#define DIRECT_UI_RENDERING (0) + + enum { + SET_HDMI_STATUS = IBinder::FIRST_CALL_TRANSACTION, + SET_HDMI_MODE, + SET_HDMI_RESOLUTION, + SET_HDMI_HDCP, + SET_HDMI_ROTATE, + SET_HDMI_HWCLAYER, + BLIT_2_HDMI + }; + + int SecTVOutService::HdmiFlushThread() + { + while (!mExitHdmiFlushThread) { + nsecs_t timeout = -1; + sp msg = mHdmiEventQueue.waitMessage(timeout); + } + + return 0; + } + + int SecTVOutService::instantiate() + { + LOGD("SecTVOutService instantiate"); + int r = defaultServiceManager()->addService(String16( "SecTVOutService"), new SecTVOutService ()); + LOGD("SecTVOutService r=%d", r); + + return r; + } + + SecTVOutService::SecTVOutService () { + LOGV("SecTVOutService created"); + mHdmiCableInserted = false; +#ifdef SUPPORT_G2D_UI_MODE + mUILayerMode = SecHdmi::HDMI_LAYER_GRAPHIC_1; +#else + mUILayerMode = SecHdmi::HDMI_LAYER_VIDEO; +#endif + mHwcLayer = 0; + mExitHdmiFlushThread = false; + + setLCDsize(); + if (mSecHdmi.create(mLCD_width, mLCD_height) == false) + LOGE("%s::mSecHdmi.create() fail", __func__); + else + setHdmiStatus(1); + + mHdmiFlushThread = new HDMIFlushThread(this); + } + + void SecTVOutService::setLCDsize(void) { + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + 0 }; + + int fd = -1; + int i = 0; + char name[64]; + + while ((fd==-1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + if (fd > 0) { + struct fb_var_screeninfo info; + if (ioctl(fd, FBIOGET_VSCREENINFO, &info) != -1) { + mLCD_width = info.xres; + mLCD_height = info.yres; + } else { + mLCD_width = DEFAULT_LCD_WIDTH; + mLCD_height = DEFAULT_LCD_HEIGHT; + } + close(fd); + } + return; + } + + SecTVOutService::~SecTVOutService () { + LOGV ("SecTVOutService destroyed"); + + if (mHdmiFlushThread != NULL) { + mHdmiFlushThread->requestExit(); + mExitHdmiFlushThread = true; + mHdmiFlushThread->requestExitAndWait(); + mHdmiFlushThread.clear(); + } + } + + status_t SecTVOutService::onTransact(uint32_t code, const Parcel & data, Parcel * reply, uint32_t flags) + { + switch (code) { + case SET_HDMI_STATUS: { + int status = data.readInt32(); + setHdmiStatus(status); + } break; + + case SET_HDMI_MODE: { + int mode = data.readInt32(); + setHdmiMode(mode); + } break; + + case SET_HDMI_RESOLUTION: { + int resolution = data.readInt32(); + setHdmiResolution(resolution); + } break; + + case SET_HDMI_HDCP: { + int enHdcp = data.readInt32(); + setHdmiHdcp(enHdcp); + } break; + + case SET_HDMI_ROTATE: { + int rotVal = data.readInt32(); + int hwcLayer = data.readInt32(); + setHdmiRotate(rotVal, hwcLayer); + } break; + + case SET_HDMI_HWCLAYER: { + int hwcLayer = data.readInt32(); + setHdmiHwcLayer((uint32_t)hwcLayer); + } break; + + case BLIT_2_HDMI: { + uint32_t w = data.readInt32(); + uint32_t h = data.readInt32(); + uint32_t colorFormat = data.readInt32(); + uint32_t physYAddr = data.readInt32(); + uint32_t physCbAddr = data.readInt32(); + uint32_t physCrAddr = data.readInt32(); + uint32_t dstX = data.readInt32(); + uint32_t dstY = data.readInt32(); + uint32_t hdmiLayer = data.readInt32(); + uint32_t num_of_hwc_layer = data.readInt32(); + + blit2Hdmi(w, h, colorFormat, physYAddr, physCbAddr, physCrAddr, dstX, dstY, hdmiLayer, num_of_hwc_layer); + } break; + + default : + LOGE ( "onTransact::default"); + return BBinder::onTransact (code, data, reply, flags); + } + + return NO_ERROR; + } + + void SecTVOutService::setHdmiStatus(uint32_t status) + { + LOGD("%s HDMI cable status = %d", __func__, status); + { + Mutex::Autolock _l(mLock); + + bool hdmiCableInserted = (bool)status; + + if (mHdmiCableInserted == hdmiCableInserted) + return; + + if (hdmiCableInserted == true) { + if (mSecHdmi.connect() == false) { + LOGE("%s::mSecHdmi.connect() fail", __func__); + hdmiCableInserted = false; + } + } else { + if (mSecHdmi.disconnect() == false) + LOGE("%s::mSecHdmi.disconnect() fail", __func__); + } + + mHdmiCableInserted = hdmiCableInserted; + } + + if (hdmiCableInserted() == true) + this->blit2Hdmi(mLCD_width, mLCD_height, HAL_PIXEL_FORMAT_BGRA_8888, 0, 0, 0, 0, 0, HDMI_MODE_UI, 0); + } + + void SecTVOutService::setHdmiMode(uint32_t mode) + { + LOGD("%s TV mode = %d", __func__, mode); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdmiOutputMode(mode)) == false) { + LOGE("%s::mSecHdmi.setHdmiOutputMode() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiResolution(uint32_t resolution) + { + LOGD("%s TV resolution = %d", __func__, resolution); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdmiResolution(resolution)) == false) { + LOGE("%s::mSecHdmi.setHdmiResolution() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiHdcp(uint32_t hdcp_en) + { + LOGD("%s TV HDCP = %d", __func__, hdcp_en); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setHdcpMode(hdcp_en)) == false) { + LOGE("%s::mSecHdmi.setHdcpMode() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer) + { + //LOGD("%s TV ROTATE = %d", __func__, rotVal); + Mutex::Autolock _l(mLock); + + if ((hdmiCableInserted() == true) && (mSecHdmi.setUIRotation(rotVal, hwcLayer)) == false) { + LOGE("%s::mSecHdmi.setUIRotation() fail", __func__); + return; + } + } + + void SecTVOutService::setHdmiHwcLayer(uint32_t hwcLayer) + { + //LOGD("%s TV HWCLAYER = %d", __func__, hwcLayer); + Mutex::Autolock _l(mLock); + + mHwcLayer = hwcLayer; + return; + } + + void SecTVOutService::blit2Hdmi(uint32_t w, uint32_t h, uint32_t colorFormat, + uint32_t pPhyYAddr, uint32_t pPhyCbAddr, uint32_t pPhyCrAddr, + uint32_t dstX, uint32_t dstY, + uint32_t hdmiMode, + uint32_t num_of_hwc_layer) + { + Mutex::Autolock _l(mLock); + + if (hdmiCableInserted() == false) + return; + + int hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; +#if defined(CHECK_UI_TIME) || defined(CHECK_VIDEO_TIME) + nsecs_t start, end; +#endif + + sp msg; + + switch (hdmiMode) { + case HDMI_MODE_UI : + if (mHwcLayer >= 2) + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_0; + else if (mHwcLayer == 1) + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; + else +#ifdef SUPPORT_G2D_UI_MODE + hdmiLayer = SecHdmi::HDMI_LAYER_GRAPHIC_1; +#else + hdmiLayer = SecHdmi::HDMI_LAYER_VIDEO; +#endif + + if (mHwcLayer == 0) { + for (int layer = SecHdmi::HDMI_LAYER_BASE + 1; layer < SecHdmi::HDMI_LAYER_MAX; layer++) { + if (layer != mUILayerMode) { + if (mSecHdmi.clear(layer) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, layer); + } + } + } + + if (mUILayerMode != hdmiLayer) { + if (mSecHdmi.clear(mUILayerMode) == false) + LOGE("%s::mSecHdmi.clear(%d) fail", __func__, mUILayerMode); + } + + mUILayerMode = hdmiLayer; + +#if !defined(BOARD_USES_HDMI_SUBTITLES) + if (mHwcLayer == 0) +#endif +#if (DIRECT_UI_RENDERING == 1) + { +#ifdef CHECK_UI_TIME + start = systemTime(); +#endif + if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, + mUILayerMode, mHwcLayer) == false) + LOGE("%s::mSecHdmi.flush() on HDMI_MODE_UI fail", __func__); +#ifdef CHECK_UI_TIME + end = systemTime(); + LOGD("[UI] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + } +#else + { + msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, + dstX, dstY, mUILayerMode, mHwcLayer, HDMI_MODE_UI); + + /* post to HdmiEventQueue */ + mHdmiEventQueue.postMessage(msg, 0, 0); + } +#endif + break; + + case HDMI_MODE_VIDEO : +#if (DIRECT_VIDEO_RENDERING == 1) +#ifdef CHECK_VIDEO_TIME + start = systemTime(); +#endif + if (mSecHdmi.flush(w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, dstX, dstY, + SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer) == false) + LOGE("%s::mSecHdmi.flush() on HDMI_MODE_VIDEO fail", __func__); +#ifdef CHECK_VIDEO_TIME + end = systemTime(); + LOGD("[Video] mSecHdmi.flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif +#else + msg = new SecHdmiEventMsg(&mSecHdmi, w, h, colorFormat, pPhyYAddr, pPhyCbAddr, pPhyCrAddr, + dstX, dstY, SecHdmi::HDMI_LAYER_VIDEO, mHwcLayer, HDMI_MODE_VIDEO); + + /* post to HdmiEventQueue */ + mHdmiEventQueue.postMessage(msg, 0, 0); +#endif + break; + + default: + LOGE("unmatched HDMI_MODE : %d", hdmiMode); + break; + } + + return; + } + + bool SecTVOutService::hdmiCableInserted(void) + { + return mHdmiCableInserted; + } + +} diff --git a/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.h b/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.h new file mode 100644 index 0000000..caece73 --- /dev/null +++ b/exynos5/hal/libhdmi/libhdmiservice/SecTVOutService.h @@ -0,0 +1,175 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright 2010, Samsung Electronics Co. LTD +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** @author Taikyung, Yu(taikyung.yu@samsung.com) +** @date 2011-07-06 +*/ + +#ifndef SECTVOUTSERVICE_H +#define SECTVOUTSERVICE_H + +#include +#include +#include +#include + +#include "ISecTVOut.h" +#include "SecHdmi.h" +#include "sec_format.h" +#include "sec_utils_v4l2.h" +#include "MessageQueue.h" + +namespace android { +//#define CHECK_VIDEO_TIME +//#define CHECK_UI_TIME + + class SecTVOutService : public BBinder + { + public : + enum { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + + mutable Mutex mLock; + + class HDMIFlushThread : public Thread { + SecTVOutService *mTVOutService; + public: + HDMIFlushThread(SecTVOutService *service): + Thread(false), + mTVOutService(service) { } + virtual void onFirstRef() { + run("HDMIFlushThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + mTVOutService->HdmiFlushThread(); + return false; + } + }; + + sp mHdmiFlushThread; + int HdmiFlushThread(); + + mutable MessageQueue mHdmiEventQueue; + bool mExitHdmiFlushThread; + + SecTVOutService(); + static int instantiate (); + virtual status_t onTransact(uint32_t, const Parcel &, Parcel *, uint32_t); + virtual ~SecTVOutService (); + + virtual void setHdmiStatus(uint32_t status); + virtual void setHdmiMode(uint32_t mode); + virtual void setHdmiResolution(uint32_t resolution); + virtual void setHdmiHdcp(uint32_t enHdcp); + virtual void setHdmiRotate(uint32_t rotVal, uint32_t hwcLayer); + virtual void setHdmiHwcLayer(uint32_t hwcLayer); + virtual void blit2Hdmi(uint32_t w, uint32_t h, + uint32_t colorFormat, + uint32_t pPhyYAddr, uint32_t pPhyCbAddr, uint32_t pPhyCrAddr, + uint32_t dstX, uint32_t dstY, + uint32_t hdmiMode, uint32_t num_of_hwc_layer); + bool hdmiCableInserted(void); + void setLCDsize(void); + + private: + SecHdmi mSecHdmi; + bool mHdmiCableInserted; + int mUILayerMode; + uint32_t mLCD_width, mLCD_height; + uint32_t mHwcLayer; + }; + + class SecHdmiEventMsg : public MessageBase { + public: + enum { + HDMI_MODE_NONE = 0, + HDMI_MODE_UI, + HDMI_MODE_VIDEO, + }; + + mutable Mutex mBlitLock; + + SecHdmi *pSecHdmi; + uint32_t mSrcWidth, mSrcHeight; + uint32_t mSrcColorFormat; + uint32_t mSrcYAddr, mSrcCbAddr, mSrcCrAddr; + uint32_t mDstX, mDstY; + uint32_t mHdmiMode; + uint32_t mHdmiLayer, mHwcLayer; + + SecHdmiEventMsg(SecHdmi *SecHdmi, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcColorFormat, + uint32_t srcYAddr, uint32_t srcCbAddr, uint32_t srcCrAddr, + uint32_t dstX, uint32_t dstY, uint32_t hdmiLayer, uint32_t hwcLayer, uint32_t hdmiMode) + : pSecHdmi(SecHdmi), mSrcWidth(srcWidth), mSrcHeight(srcHeight), mSrcColorFormat(srcColorFormat), + mSrcYAddr(srcYAddr), mSrcCbAddr(srcCbAddr), mSrcCrAddr(srcCrAddr), + mDstX(dstX), mDstY(dstY), mHdmiLayer(hdmiLayer), mHwcLayer(hwcLayer), mHdmiMode(hdmiMode) { + } + + virtual bool handler() { + Mutex::Autolock _l(mBlitLock); + bool ret = true; +#if defined(CHECK_UI_TIME) || defined(CHECK_VIDEO_TIME) + nsecs_t start, end; +#endif + + switch (mHdmiMode) { + case HDMI_MODE_UI: +#ifdef CHECK_UI_TIME + start = systemTime(); +#endif + if (pSecHdmi->flush(mSrcWidth, mSrcHeight, mSrcColorFormat, mSrcYAddr, mSrcCbAddr, mSrcCrAddr, + mDstX, mDstY, mHdmiLayer, mHwcLayer) == false) { + LOGE("%s::pSecHdmi->flush() fail on HDMI_MODE_UI", __func__); + ret = false; + } + +#ifdef CHECK_UI_TIME + end = systemTime(); + LOGD("[UI] pSecHdmi->flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + break; + case HDMI_MODE_VIDEO: +#ifdef CHECK_VIDEO_TIME + start = systemTime(); +#endif + if (pSecHdmi->flush(mSrcWidth, mSrcHeight, mSrcColorFormat, mSrcYAddr, mSrcCbAddr, mSrcCrAddr, + mDstX, mDstY, mHdmiLayer, mHwcLayer) == false) { + LOGE("%s::pSecHdmi->flush() fail on HDMI_MODE_VIDEO", __func__); + ret = false; + } +#ifdef CHECK_VIDEO_TIME + end = systemTime(); + LOGD("[VIDEO] pSecHdmi->flush[end-start] = %ld ms", long(ns2ms(end)) - long(ns2ms(start))); +#endif + break; + default: + LOGE("Undefined HDMI_MODE"); + ret = false; + break; + } + return ret; + } + }; + +}; +#endif diff --git a/exynos5/hal/libhdmi/libsForhdmi/Android.mk b/exynos5/hal/libhdmi/libsForhdmi/Android.mk new file mode 100644 index 0000000..9acbc52 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/Android.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),) +include $(all-subdir-makefiles) +endif diff --git a/exynos5/hal/libhdmi/libsForhdmi/libcec/Android.mk b/exynos5/hal/libhdmi/libsForhdmi/libcec/Android.mk new file mode 100644 index 0000000..9a4b721 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libcec/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := libcec.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +LOCAL_MODULE := libcec +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos5/hal/libhdmi/libsForhdmi/libcec/cec.h b/exynos5/hal/libhdmi/libsForhdmi/libcec/cec.h new file mode 100644 index 0000000..4b0d3af --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libcec/cec.h @@ -0,0 +1,11 @@ +#ifndef _LINUX_CEC_H_ +#define _LINUX_CEC_H_ + +#define CEC_IOC_MAGIC 'c' + +/** + * CEC device request code to set logical address. + */ +#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int) + +#endif /* _LINUX_CEC_H_ */ diff --git a/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.c b/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.c new file mode 100644 index 0000000..e688051 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.c @@ -0,0 +1,386 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* drv. header */ +#include "cec.h" + +#include "libcec.h" + +#define CEC_DEBUG 0 + +/** + * @def CEC_DEVICE_NAME + * Defines simbolic name of the CEC device. + */ +#define CEC_DEVICE_NAME "/dev/CEC" + +static struct { + enum CECDeviceType devtype; + unsigned char laddr; +} laddresses[] = { + { CEC_DEVICE_RECODER, 1 }, + { CEC_DEVICE_RECODER, 2 }, + { CEC_DEVICE_TUNER, 3 }, + { CEC_DEVICE_PLAYER, 4 }, + { CEC_DEVICE_AUDIO, 5 }, + { CEC_DEVICE_TUNER, 6 }, + { CEC_DEVICE_TUNER, 7 }, + { CEC_DEVICE_PLAYER, 8 }, + { CEC_DEVICE_RECODER, 9 }, + { CEC_DEVICE_TUNER, 10 }, + { CEC_DEVICE_PLAYER, 11 }, +}; + +static int CECSetLogicalAddr(unsigned int laddr); + +#ifdef CEC_DEBUG +inline static void CECPrintFrame(unsigned char *buffer, unsigned int size); +#endif + +static int fd = -1; + +/** + * Open device driver and assign CEC file descriptor. + * + * @return If success to assign CEC file descriptor, return 1; otherwise, return 0. + */ +int CECOpen() +{ + int res = 1; + + if (fd != -1) + CECClose(); + + if ((fd = open(CEC_DEVICE_NAME, O_RDWR)) < 0) { + LOGE("Can't open %s!\n", CEC_DEVICE_NAME); + res = 0; + } + + return res; +} + +/** + * Close CEC file descriptor. + * + * @return If success to close CEC file descriptor, return 1; otherwise, return 0. + */ +int CECClose() +{ + int res = 1; + + if (fd != -1) { + if (close(fd) != 0) { + LOGE("close() failed!\n"); + res = 0; + } + fd = -1; + } + + return res; +} + +/** + * Allocate logical address. + * + * @param paddr [in] CEC device physical address. + * @param devtype [in] CEC device type. + * + * @return new logical address, or 0 if an arror occured. + */ +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype) +{ + unsigned char laddr = CEC_LADDR_UNREGISTERED; + int i = 0; + + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + if (CECSetLogicalAddr(laddr) < 0) { + LOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + if (paddr == CEC_NOT_VALID_PHYSICAL_ADDRESS) + return CEC_LADDR_UNREGISTERED; + + /* send "Polling Message" */ + while (i < sizeof(laddresses)/sizeof(laddresses[0])) { + if (laddresses[i].devtype == devtype) { + unsigned char _laddr = laddresses[i].laddr; + unsigned char message = ((_laddr << 4) | _laddr); + if (CECSendMessage(&message, 1) != 1) { + laddr = _laddr; + break; + } + } + i++; + } + + if (laddr == CEC_LADDR_UNREGISTERED) { + LOGE("All LA addresses in use!!!\n"); + return CEC_LADDR_UNREGISTERED; + } + + if (CECSetLogicalAddr(laddr) < 0) { + LOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + /* broadcast "Report Physical Address" */ + unsigned char buffer[5]; + buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS; + buffer[2] = (paddr >> 8) & 0xFF; + buffer[3] = paddr & 0xFF; + buffer[4] = devtype; + + if (CECSendMessage(buffer, 5) != 5) { + LOGE("CECSendMessage() failed!\n"); + return 0; + } + + return laddr; +} + +/** + * Send CEC message. + * + * @param *buffer [in] pointer to buffer address where message located. + * @param size [in] message size. + * + * @return number of bytes written, or 0 if an arror occured. + */ +int CECSendMessage(unsigned char *buffer, int size) +{ + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + if (size > CEC_MAX_FRAME_SIZE) { + LOGE("size should not exceed %d\n", CEC_MAX_FRAME_SIZE); + return 0; + } + +#if CEC_DEBUG + LOGI("CECSendMessage() : "); + CECPrintFrame(buffer, size); +#endif + + return write(fd, buffer, size); +} + +/** + * Receive CEC message. + * + * @param *buffer [in] pointer to buffer address where message will be stored. + * @param size [in] buffer size. + * @param timeout [in] timeout in microseconds. + * + * @return number of bytes received, or 0 if an arror occured. + */ +int CECReceiveMessage(unsigned char *buffer, int size, long timeout) +{ + int bytes = 0; + fd_set rfds; + struct timeval tv; + int retval; + + if (fd == -1) { + LOGE("open device first!\n"); + return 0; + } + + tv.tv_sec = 0; + tv.tv_usec = timeout; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + retval = select(fd + 1, &rfds, NULL, NULL, &tv); + + if (retval == -1) { + return 0; + } else if (retval) { + bytes = read(fd, buffer, size); +#if CEC_DEBUG + LOGI("CECReceiveMessage() : size(%d)", bytes); + if(bytes > 0) + CECPrintFrame(buffer, bytes); +#endif + } + + return bytes; +} + +/** + * Set CEC logical address. + * + * @return 1 if success, otherwise, return 0. + */ +int CECSetLogicalAddr(unsigned int laddr) +{ + if (ioctl(fd, CEC_IOC_SETLADDR, &laddr)) { + LOGE("ioctl(CEC_IOC_SETLA) failed!\n"); + return 0; + } + + return 1; +} + +#if CEC_DEBUG +/** + * Print CEC frame. + */ +void CECPrintFrame(unsigned char *buffer, unsigned int size) +{ + if (size > 0) { + int i; + LOGI("fsize: %d ", size); + LOGI("frame: "); + for (i = 0; i < size; i++) + LOGI("0x%02x ", buffer[i]); + + LOGI("\n"); + } +} +#endif + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param lsrc [in] buffer size. + * + * @return 1 if message should be ignored, otherwise, return 0. + */ +//TODO: not finished +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc) +{ + int retval = 0; + + /* if a message coming from address 15 (unregistered) */ + if (lsrc == CEC_LADDR_UNREGISTERED) { + switch (opcode) { + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + retval = 1; + default: + break; + } + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param size [in] message size. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageSize(unsigned char opcode, int size) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + if (size != 1) + retval = 0; + break; + case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE: + if (size != 2) + retval = 0; + break; + case CEC_OPCODE_PLAY: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + case CEC_OPCODE_ROUTING_INFORMATION: + case CEC_OPCODE_SET_STREAM_PATH: + if (size != 3) + retval = 0; + break; + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_DEVICE_VENDOR_ID: + case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS: + if (size != 4) + retval = 0; + break; + case CEC_OPCODE_ROUTING_CHANGE: + if (size != 5) + retval = 0; + break; + /* CDC - 1.4 */ + case 0xf8: + if (!(size > 5 && size <= 16)) + retval = 0; + break; + default: + break; + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param broadcast [in] broadcast/direct message. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageMode(unsigned char opcode, int broadcast) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + if (!broadcast) + retval = 0; + break; + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_ABORT: + if (broadcast) + retval = 0; + break; + default: + break; + } + + return retval; +} diff --git a/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.h b/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.h new file mode 100644 index 0000000..5bbfc15 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libcec/libcec.h @@ -0,0 +1,209 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBCEC_H_ +#define _LIBCEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Maximum CEC frame size */ +#define CEC_MAX_FRAME_SIZE 16 +/** Not valid CEC physical address */ +#define CEC_NOT_VALID_PHYSICAL_ADDRESS 0xFFFF + +/** CEC broadcast address (as destination address) */ +#define CEC_MSG_BROADCAST 0x0F +/** CEC unregistered address (as initiator address) */ +#define CEC_LADDR_UNREGISTERED 0x0F + +/* + * CEC Messages + */ + +//@{ +/** @name Messages for the One Touch Play Feature */ +#define CEC_OPCODE_ACTIVE_SOURCE 0x82 +#define CEC_OPCODE_IMAGE_VIEW_ON 0x04 +#define CEC_OPCODE_TEXT_VIEW_ON 0x0D +//@} + +//@{ +/** @name Messages for the Routing Control Feature */ +#define CEC_OPCODE_INACTIVE_SOURCE 0x9D +#define CEC_OPCODE_REQUEST_ACTIVE_SOURCE 0x85 +#define CEC_OPCODE_ROUTING_CHANGE 0x80 +#define CEC_OPCODE_ROUTING_INFORMATION 0x81 +#define CEC_OPCODE_SET_STREAM_PATH 0x86 +//@} + +//@{ +/** @name Messages for the Standby Feature */ +#define CEC_OPCODE_STANDBY 0x36 +//@} + +//@{ +/** @name Messages for the One Touch Record Feature */ +#define CEC_OPCODE_RECORD_OFF 0x0B +#define CEC_OPCODE_RECORD_ON 0x09 +#define CEC_OPCODE_RECORD_STATUS 0x0A +#define CEC_OPCODE_RECORD_TV_SCREEN 0x0F +//@} + +//@{ +/** @name Messages for the Timer Programming Feature */ +#define CEC_OPCODE_CLEAR_ANALOGUE_TIMER 0x33 +#define CEC_OPCODE_CLEAR_DIGITAL_TIMER 0x99 +#define CEC_OPCODE_CLEAR_EXTERNAL_TIMER 0xA1 +#define CEC_OPCODE_SET_ANALOGUE_TIMER 0x34 +#define CEC_OPCODE_SET_DIGITAL_TIMER 0x97 +#define CEC_OPCODE_SET_EXTERNAL_TIMER 0xA2 +#define CEC_OPCODE_SET_TIMER_PROGRAM_TITLE 0x67 +#define CEC_OPCODE_TIMER_CLEARED_STATUS 0x43 +#define CEC_OPCODE_TIMER_STATUS 0x35 +//@} + +//@{ +/** @name Messages for the System Information Feature */ +#define CEC_OPCODE_CEC_VERSION 0x9E +#define CEC_OPCODE_GET_CEC_VERSION 0x9F +#define CEC_OPCODE_GIVE_PHYSICAL_ADDRESS 0x83 +#define CEC_OPCODE_GET_MENU_LANGUAGE 0x91 +//#define CEC_OPCODE_POLLING_MESSAGE +#define CEC_OPCODE_REPORT_PHYSICAL_ADDRESS 0x84 +#define CEC_OPCODE_SET_MENU_LANGUAGE 0x32 +//@} + +//@{ +/** @name Messages for the Deck Control Feature */ +#define CEC_OPCODE_DECK_CONTROL 0x42 +#define CEC_OPCODE_DECK_STATUS 0x1B +#define CEC_OPCODE_GIVE_DECK_STATUS 0x1A +#define CEC_OPCODE_PLAY 0x41 +//@} + +//@{ +/** @name Messages for the Tuner Control Feature */ +#define CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS 0x08 +#define CEC_OPCODE_SELECT_ANALOGUE_SERVICE 0x92 +#define CEC_OPCODE_SELECT_DIGITAL_SERVICE 0x93 +#define CEC_OPCODE_TUNER_DEVICE_STATUS 0x07 +#define CEC_OPCODE_TUNER_STEP_DECREMENT 0x06 +#define CEC_OPCODE_TUNER_STEP_INCREMENT 0x05 +//@} + +//@{ +/** @name Messages for the Vendor Specific Commands Feature */ +#define CEC_OPCODE_DEVICE_VENDOR_ID 0x87 +#define CEC_OPCODE_GET_DEVICE_VENDOR_ID 0x8C +#define CEC_OPCODE_VENDOR_COMMAND 0x89 +#define CEC_OPCODE_VENDOR_COMMAND_WITH_ID 0xA0 +#define CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN 0x8A +#define CEC_OPCODE_VENDOR_REMOVE_BUTTON_UP 0x8B +//@} + +//@{ +/** @name Messages for the OSD Display Feature */ +#define CEC_OPCODE_SET_OSD_STRING 0x64 +//@} + +//@{ +/** @name Messages for the Device OSD Transfer Feature */ +#define CEC_OPCODE_GIVE_OSD_NAME 0x46 +#define CEC_OPCODE_SET_OSD_NAME 0x47 +//@} + +//@{ +/** @name Messages for the Device Menu Control Feature */ +#define CEC_OPCODE_MENU_REQUEST 0x8D +#define CEC_OPCODE_MENU_STATUS 0x8E +#define CEC_OPCODE_USER_CONTROL_PRESSED 0x44 +#define CEC_OPCODE_USER_CONTROL_RELEASED 0x45 +//@} + +//@{ +/** @name Messages for the Remote Control Passthrough Feature */ +//@} + +//@{ +/** @name Messages for the Power Status Feature */ +#define CEC_OPCODE_GIVE_DEVICE_POWER_STATUS 0x8F +#define CEC_OPCODE_REPORT_POWER_STATUS 0x90 +//@} + +//@{ +/** @name Messages for General Protocol messages */ +#define CEC_OPCODE_FEATURE_ABORT 0x00 +#define CEC_OPCODE_ABORT 0xFF +//@} + +//@{ +/** @name Messages for the System Audio Control Feature */ +#define CEC_OPCODE_GIVE_AUDIO_STATUS 0x71 +#define CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7D +#define CEC_OPCODE_REPORT_AUDIO_STATUS 0x7A +#define CEC_OPCODE_SET_SYSTEM_AUDIO_MODE 0x72 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST 0x70 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS 0x7E +//@} + +//@{ +/** @name Messages for the Audio Rate Control Feature */ +#define CEC_OPCODE_SET_AUDIO_RATE 0x9A +//@} + +//@{ +/** @name CEC Operands */ + +//TODO: not finished + +#define CEC_DECK_CONTROL_MODE_STOP 0x03 +#define CEC_PLAY_MODE_PLAY_FORWARD 0x24 +//@} + +/** + * @enum CECDeviceType + * Type of CEC device + */ +enum CECDeviceType { + /** TV */ + CEC_DEVICE_TV, + /** Recording Device */ + CEC_DEVICE_RECODER, + /** Tuner */ + CEC_DEVICE_TUNER, + /** Playback Device */ + CEC_DEVICE_PLAYER, + /** Audio System */ + CEC_DEVICE_AUDIO, +}; + +int CECOpen(); +int CECClose(); +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype); +int CECSendMessage(unsigned char *buffer, int size); +int CECReceiveMessage(unsigned char *buffer, int size, long timeout); + +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc); +int CECCheckMessageSize(unsigned char opcode, int size); +int CECCheckMessageMode(unsigned char opcode, int broadcast); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBCEC_H_ */ diff --git a/exynos5/hal/libhdmi/libsForhdmi/libddc/Android.mk b/exynos5/hal/libhdmi/libsForhdmi/libddc/Android.mk new file mode 100644 index 0000000..99af09b --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libddc/Android.mk @@ -0,0 +1,49 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := libddc.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_7) +LOCAL_CFLAGS += -DDDC_CH_I2C_7 +endif + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_1) +LOCAL_CFLAGS += -DDDC_CH_I2C_1 +endif + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_2) +LOCAL_CFLAGS += -DDDC_CH_I2C_2 +endif + +ifeq ($(BOARD_HDMI_DDC_CH), DDC_CH_I2C_8) +LOCAL_CFLAGS += -DDDC_CH_I2C_8 +endif + +LOCAL_MODULE := libddc +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.c b/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.c new file mode 100644 index 0000000..4e6e374 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.c @@ -0,0 +1,289 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "i2c-dev.h" + +#include "libddc.h" + +#define DDC_DEBUG 0 + +/** + * @brief DDC device name. + * User should change this. + */ +#ifdef DDC_CH_I2C_1 +#define DEV_NAME "/dev/i2c-1" +#endif + +#ifdef DDC_CH_I2C_2 +#define DEV_NAME "/dev/i2c-2" +#endif + +#ifdef DDC_CH_I2C_7 +#define DEV_NAME "/dev/i2c-7" +#endif + +#ifdef DDC_CH_I2C_8 +#define DEV_NAME "/dev/i2c-8" +#endif + +/** + * DDC file descriptor + */ +static int ddc_fd = -1; + +/** + * Reference count of DDC file descriptor + */ +static unsigned int ref_cnt = 0; + +/** + * Check if DDC file is already opened or not + * @return If DDC file is already opened, return 1; Otherwise, return 0. + */ +static int DDCFileAvailable() +{ + return (ddc_fd < 0) ? 0 : 1; +} + +/** + * Initialze DDC library. Open DDC device + * @return If succeed in opening DDC device or it is already opened, return 1;@n + * Otherwise, return 0. + */ +int DDCOpen() +{ + int ret = 1; + + // check already open?? + if (ref_cnt > 0) { + ref_cnt++; + return 1; + } + + // open + if ((ddc_fd = open(DEV_NAME,O_RDWR)) < 0) { + LOGE("%s: Cannot open I2C_DDC : %s",__func__, DEV_NAME); + ret = 0; + } + + ref_cnt++; + return ret; +} + +/** + * Finalize DDC library. Close DDC device + * @return If succeed in closing DDC device or it is being used yet, return 1;@n + * Otherwise, return 0. + */ +int DDCClose() +{ + int ret = 1; + // check if fd is available + if (ref_cnt == 0) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 1; + } + + // close + if (ref_cnt > 1) { + ref_cnt--; + return 1; + } + + if (close(ddc_fd) < 0) { +#if DDC_DEBUG + LOGE("%s: Cannot close I2C_DDC : %s",__func__,DEV_NAME); +#endif + ret = 0; + } + + ref_cnt--; + ddc_fd = -1; + + return ret; +} + +/** + * Read data though DDC. For more information of DDC, refer DDC Spec. + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to store data + * @return If succeed in reading, return 1; Otherwise, return 0. + */ +int DDCRead(unsigned char addr, unsigned char offset, + unsigned int size, unsigned char* buffer) +{ + struct i2c_rdwr_ioctl_data msgset; + struct i2c_msg msgs[2]; + int ret = 1; + + if (!DDCFileAvailable()) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 0; + } + + // set offset + msgs[0].addr = addr>>1; + msgs[0].flags = 0; + msgs[0].len = 1; + msgs[0].buf = &offset; + + // read data + msgs[1].addr = addr>>1; + msgs[1].flags = I2C_M_RD; + msgs[1].len = size; + msgs[1].buf = buffer; + + // set rdwr ioctl data + msgset.nmsgs = 2; + msgset.msgs = msgs; + + // i2c fast read + if ((ret = ioctl(ddc_fd, I2C_RDWR, &msgset)) < 0) { + perror("ddc error:"); + ret = 0; + } + + return ret; +} + +/** + * Read data though E-DDC. For more information of E-DDC, refer E-DDC Spec. + * @param segpointer [in] Segment pointer + * @param segment [in] Segment number + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to store data + * @return If succeed in reading, return 1; Otherwise, return 0. + */ + +int EDDCRead(unsigned char segpointer, unsigned char segment, unsigned char addr, + unsigned char offset, unsigned int size, unsigned char* buffer) +{ + struct i2c_rdwr_ioctl_data msgset; + struct i2c_msg msgs[3]; + int ret = 1; + + if (!DDCFileAvailable()) { +#if DDC_DEBUG + LOGE("%s: I2C_DDC is not available!!!!", __func__); +#endif + return 0; + } + + // set segment pointer + msgs[0].addr = segpointer>>1; + // ignore ack only if segment is "0" + if (segment == 0) + msgs[0].flags = I2C_M_IGNORE_NAK; + else + msgs[0].flags = 0; + + msgs[0].len = 1; + msgs[0].buf = &segment; + + // set offset + msgs[1].addr = addr>>1; + msgs[1].flags = 0; + msgs[1].len = 1; + msgs[1].buf = &offset; + + // read data + msgs[2].addr = addr>>1; + msgs[2].flags = I2C_M_RD; + msgs[2].len = size; + msgs[2].buf = buffer; + + msgset.nmsgs = 3; + msgset.msgs = msgs; + + // eddc read + if (ioctl(ddc_fd, I2C_RDWR, &msgset) < 0) { +#if DDC_DEBUG + LOGE("%s: ioctl(I2C_RDWR) failed!!!", __func__); +#endif + ret = 0; + } + return ret; +} + +/** + * Write data though DDC. For more information of DDC, refer DDC Spec. + * @param addr [in] Device address + * @param offset [in] Byte offset + * @param size [in] Sizes of data + * @param buffer [out] Pointer to buffer to write + * @return If succeed in writing, return 1; Otherwise, return 0. + */ +int DDCWrite(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer) +{ + unsigned char* temp; + int bytes; + int retval = 0; + + // allocate temporary buffer + temp = (unsigned char*) malloc((size+1)*sizeof(unsigned char)); + if (!temp) { + LOGE("%s: not enough resources at %s", __FUNCTION__); + goto exit; + } + + temp[0] = offset; + memcpy(temp+1,buffer,size); + + if (!DDCFileAvailable()) { + LOGE("%s: I2C_DDC is not available!!!!", __func__); + goto exit; + } + + if (ioctl(ddc_fd, I2C_SLAVE, addr>>1) < 0) { + LOGE("%s: cannot set slave address 0x%02x", __func__,addr); + goto exit; + } + + // write temp buffer + if ((bytes = write(ddc_fd,temp,size+1)) != (size+1)) { + LOGE("%s: fail to write %d bytes, only write %d bytes",__func__, size, bytes); + goto exit; + } + + retval = 1; + +exit: + // free temp buffer + if (temp) + free(temp); + + return retval; +} diff --git a/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.h b/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.h new file mode 100644 index 0000000..368855b --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libddc/libddc.h @@ -0,0 +1,35 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBDDC_H_ +#define _LIBDDC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int DDCOpen(); +int DDCRead(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer); +int DDCWrite(unsigned char addr, unsigned char offset, unsigned int size, unsigned char* buffer); +int EDDCRead(unsigned char segpointer, unsigned char segment, unsigned char addr, + unsigned char offset, unsigned int size, unsigned char* buffer); +int DDCClose(); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDDC_H_ */ diff --git a/exynos5/hal/libhdmi/libsForhdmi/libedid/Android.mk b/exynos5/hal/libhdmi/libsForhdmi/libedid/Android.mk new file mode 100644 index 0000000..602ae4d --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libedid/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_HDMI),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) +LOCAL_SHARED_LIBRARIES := liblog libddc +LOCAL_SRC_FILES := libedid.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/../../../include + +LOCAL_MODULE := libedid +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/exynos5/hal/libhdmi/libsForhdmi/libedid/edid.h b/exynos5/hal/libhdmi/libsForhdmi/libedid/edid.h new file mode 100644 index 0000000..aea1309 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libedid/edid.h @@ -0,0 +1,181 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _EDID_H_ +#define _EDID_H_ + +//@{ +/** + * @name EDID Addresses + */ +#define EDID_ADDR (0xA0) +#define EDID_SEGMENT_POINTER (0x60) +//@} + +//@{ +/** + * @name EDID offset and bit values + */ +#define SIZEOFBYTE (8) +#define SIZEOFEDIDBLOCK (0x80) +#define EDID_EXTENSION_NUMBER_POS (0x7E) + +#define EDID_TIMING_EXT_TAG_ADDR_POS (0) +#define EDID_TIMING_EXT_REV_NUMBER_POS (1) +#define EDID_DETAILED_TIMING_OFFSET_POS (2) +#define EDID_DATA_BLOCK_START_POS (4) + +// for Extension Data Block +#define EDID_TIMING_EXT_TAG_VAL (0x02) +#define EDID_BLOCK_MAP_EXT_TAG_VAL (0xF0) + +#define EDID_SHORT_AUD_DEC_TAG_VAL (1<<5) +#define EDID_SHORT_VID_DEC_TAG_VAL (2<<5) +#define EDID_VSDB_TAG_VAL (3<<5) +#define EDID_SPEAKER_ALLOCATION_TAG_VAL (4<<5) +#define EDID_VESA_DTC_TAG_VAL (5<<5) +#define EDID_RESERVED_TAG_VAL (6<<5) + +#define EDID_EXTENDED_TAG_VAL (7<<5) +#define EDID_EXTENDED_COLORIMETRY_VAL (5) +#define EDID_EXTENDED_COLORIMETRY_BLOCK_LEN (3) + +#define EDID_TAG_CODE_MASK (1<<7 | 1<<6 | 1<<5) +#define EDID_DATA_BLOCK_SIZE_MASK (1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0) + +#define EDID_VSDB_MIN_LENGTH_VAL (5) + +// for Established Timings +#define EDID_ET_POS (0x23) +#define EDID_ET_640x480p_VAL (0x20) + +// for DTD +#define EDID_DTD_START_ADDR (0x36) +#define EDID_DTD_BYTE_LENGTH (18) +#define EDID_DTD_TOTAL_LENGTH (EDID_DTD_BYTE_LENGTH*4) + +#define EDID_DTD_PIXELCLOCK_POS1 (0) +#define EDID_DTD_PIXELCLOCK_POS2 (1) + +#define EDID_DTD_HBLANK_POS1 (3) +#define EDID_DTD_HBLANK_POS2 (4) +#define EDID_DTD_HBLANK_POS2_MASK (0xF) + +#define EDID_DTD_HACTIVE_POS1 (2) +#define EDID_DTD_HACTIVE_POS2 (4) +#define EDID_DTD_HACTIVE_POS2_MASK (0xF0) + +#define EDID_DTD_VBLANK_POS1 (6) +#define EDID_DTD_VBLANK_POS2 (7) +#define EDID_DTD_VBLANK_POS2_MASK (0x0F) + +#define EDID_DTD_VACTIVE_POS1 (5) +#define EDID_DTD_VACTIVE_POS2 (7) +#define EDID_DTD_VACTIVE_POS2_MASK (0xF0) + +#define EDID_DTD_INTERLACE_POS (17) +#define EDID_DTD_INTERLACE_MASK (1<<7) + +// for SVD +#define EDID_SVD_VIC_MASK (0x7F) + +// for CS +#define EDID_COLOR_SPACE_POS (3) +#define EDID_YCBCR444_CS_MASK (1<<5) +#define EDID_YCBCR422_CS_MASK (1<<4) + +// for Color Depth +#define EDID_DC_48_VAL (1<<6) +#define EDID_DC_36_VAL (1<<5) +#define EDID_DC_30_VAL (1<<4) +#define EDID_DC_YCBCR_VAL (1<<3) + +#define EDID_DC_POS (6) +#define EDID_DC_MASK (EDID_DC_48_VAL | EDID_DC_36_VAL| EDID_DC_30_VAL | EDID_DC_YCBCR_VAL) + +// for colorimetry +#define EDID_XVYCC601_MASK (1<<0) +#define EDID_XVYCC709_MASK (1<<1) +#define EDID_EXTENDED_MASK (1<<0|1<<1|1<<2) + +// for SAD +#define SHORT_AUD_DESCRIPTOR_LPCM (1<<0) +#define SHORT_AUD_DESCRIPTOR_AC3 (1<<1) +#define SHORT_AUD_DESCRIPTOR_MPEG1 (1<<2) +#define SHORT_AUD_DESCRIPTOR_MP3 (1<<3) +#define SHORT_AUD_DESCRIPTOR_MPEG2 (1<<4) +#define SHORT_AUD_DESCRIPTOR_AAC (1<<5) +#define SHORT_AUD_DESCRIPTOR_DTS (1<<6) +#define SHORT_AUD_DESCRIPTOR_ATRAC (1<<7) + +#define EDID_SAD_CODE_MASK (1<<6 | 1<<5 | 1<<4 | 1<<3) +#define EDID_SAD_CHANNEL_MASK (1<<2 | 1<<1 | 1<<0) +#define EDID_SAD_192KHZ_MASK (1<<6) +#define EDID_SAD_176KHZ_MASK (1<<5) +#define EDID_SAD_96KHZ_MASK (1<<4) +#define EDID_SAD_88KHZ_MASK (1<<3) +#define EDID_SAD_48KHZ_MASK (1<<2) +#define EDID_SAD_44KHZ_MASK (1<<1) +#define EDID_SAD_32KHZ_MASK (1<<0) + +#define EDID_SAD_WORD_24_MASK (1<<2) +#define EDID_SAD_WORD_20_MASK (1<<1) +#define EDID_SAD_WORD_16_MASK (1<<0) + +// for CEC +#define EDID_CEC_PHYICAL_ADDR (4) + +// for 3D +#define EDID_HDMI_EXT_POS (8) +#define EDID_HDMI_VIDEO_PRESENT_MASK (1<<5) + +// latency +#define EDID_HDMI_LATENCY_MASK (1<<7|1<<6) +#define EDID_HDMI_LATENCY_POS (6) + +#define EDID_HDMI_3D_PRESENT_POS (13) +#define EDID_HDMI_3D_PRESENT_MASK (1<<7) +#define EDID_HDMI_3D_MULTI_PRESENT_MASK (1<<6 | 1<<5) +#define EDID_HDMI_3D_MULTI_PRESENT_BIT 5 + +#define EDID_3D_STRUCTURE_ONLY_EXIST (1<<5) +#define EDID_3D_STRUCTURE_MASK_EXIST (1<<6) + +#define EDID_3D_STRUCTURE_FP (0) +#define EDID_3D_STRUCTURE_FA (1) +#define EDID_3D_STRUCTURE_LA (2) +#define EDID_3D_STRUCTURE_SSF (3) +#define EDID_3D_STRUCTURE_LD (4) +#define EDID_3D_STRUCTURE_LDGFX (5) +#define EDID_3D_STRUCTURE_TB (6) +#define EDID_3D_STRUCTURE_SSH (8) + +#define EDID_HDMI_EXT_LENGTH_POS (14) +#define EDID_HDMI_VSDB_VIC_LEN_BIT (5) +#define EDID_HDMI_VSDB_VIC_LEN_MASK (1<<7|1<<6|1<<5) +#define EDID_HDMI_VSDB_3D_LEN_MASK (1<<4|1<<3|1<<2|1<<1|1<<0) + +#define EDID_HDMI_2D_VIC_ORDER_MASK (1<<7|1<<6|1<<5|1<<4) +#define EDID_HDMI_3D_STRUCTURE_MASK (1<<3|1<<2|1<<1|1<<0) + +// for MAX TMDS +#define EDID_MAX_TMDS_POS (7) + +// for 3D Structure +#define NUM_OF_VIC_FOR_3D 16 +//@} + +#endif /* _EDID_H_ */ diff --git a/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.c b/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.c new file mode 100644 index 0000000..c6bed50 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.c @@ -0,0 +1,1265 @@ +/* +* Copyright@ Samsung Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include + +#include + +#include "edid.h" +#include "libedid.h" +#include "../libddc/libddc.h" + +//#define EDID_DEBUG 1 + +#ifdef EDID_DEBUG +#define DPRINTF(args...) LOGI(args) +#else +#define DPRINTF(args...) +#endif + +#define NUM_OF_VIC_FOR_3D 16 + +/** + * @var gEdidData + * Pointer to EDID data + */ +static unsigned char* gEdidData; + +/** + * @var gExtensions + * Number of EDID extensions + */ +static int gExtensions; + + +/** + * @var aVIC + * This contains first 16 VIC in EDID + */ +static unsigned char aVIC[NUM_OF_VIC_FOR_3D]; + +//! Structure for parsing video timing parameter in EDID +static const struct edid_params { + /** H Total */ + unsigned int HTotal; + + /** H Blank */ + unsigned int HBlank; + + /** V Total */ + unsigned int VTotal; + + /** V Blank */ + unsigned int VBlank; + + /** CEA VIC */ + unsigned char VIC; + + /** CEA VIC for 16:9 aspect ratio */ + unsigned char VIC16_9; + + /** 0 if progressive, 1 if interlaced */ + unsigned char interlaced; + + /** Pixel frequency */ + enum PixelFreq PixelClock; +} aVideoParams[] = +{ + { 800 , 160 , 525 , 45, 1 , 1 , 0, PIXEL_FREQ_25_200 ,}, // v640x480p_60Hz + { 858 , 138 , 525 , 45, 2 , 3 , 0, PIXEL_FREQ_27_027 ,}, // v720x480p_60Hz + { 1650, 370 , 750 , 30, 4 , 4 , 0, PIXEL_FREQ_74_250 ,}, // v1280x720p_60Hz + { 2200, 280 , 1125, 22, 5 , 5 , 1, PIXEL_FREQ_74_250 ,}, // v1920x1080i_60H + { 1716, 276 , 525 , 22, 6 , 7 , 1, PIXEL_FREQ_74_250 ,}, // v720x480i_60Hz + { 1716, 276 , 262 , 22, 8 , 9 , 0, PIXEL_FREQ_27_027 ,}, // v720x240p_60Hz + //{ 1716, 276 , 263 , 23, 8 , 9 , 0, PIXEL_FREQ_27_027 , }, // v720x240p_60Hz(mode 2) + { 3432, 552 , 525 , 22, 10, 11, 1, PIXEL_FREQ_54_054 , }, // v2880x480i_60Hz + { 3432, 552 , 262 , 22, 12, 13, 0, PIXEL_FREQ_54_054 , }, // v2880x240p_60Hz + //{ 3432, 552 , 263 , 23, 12, 13, 0, PIXEL_FREQ_54_054 , }, // v2880x240p_60Hz(mode 2) + { 1716, 276 , 525 , 45, 14, 15, 0, PIXEL_FREQ_54_054 , }, // v1440x480p_60Hz + { 2200, 280 , 1125, 45, 16, 16, 0, PIXEL_FREQ_148_500, }, // v1920x1080p_60H + { 864 , 144 , 625 , 49, 17, 18, 0, PIXEL_FREQ_27 , }, // v720x576p_50Hz + { 1980, 700 , 750 , 30, 19, 19, 0, PIXEL_FREQ_74_250 , }, // v1280x720p_50Hz + { 2640, 720 , 1125, 22, 20, 20, 1, PIXEL_FREQ_74_250 , }, // v1920x1080i_50H + { 1728, 288 , 625 , 24, 21, 22, 1, PIXEL_FREQ_27 , }, // v720x576i_50Hz + { 1728, 288 , 312 , 24, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz + //{ 1728, 288 , 313 , 25, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz(mode 2) + //{ 1728, 288 , 314 , 26, 23, 24, 0, PIXEL_FREQ_27 , }, // v720x288p_50Hz(mode 3) + { 3456, 576 , 625 , 24, 25, 26, 1, PIXEL_FREQ_54 , }, // v2880x576i_50Hz + { 3456, 576 , 312 , 24, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz + //{ 3456, 576 , 313 , 25, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz(mode 2) + //{ 3456, 576 , 314 , 26, 27, 28, 0, PIXEL_FREQ_54 , }, // v2880x288p_50Hz(mode 3) + { 1728, 288 , 625 , 49, 29, 30, 0, PIXEL_FREQ_54 , }, // v1440x576p_50Hz + { 2640, 720 , 1125, 45, 31, 31, 0, PIXEL_FREQ_148_500,}, // v1920x1080p_50Hz + { 2750, 830 , 1125, 45, 32, 32, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_24Hz + { 2640, 720 , 1125, 45, 33, 33, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_25Hz + { 2200, 280 , 1125, 45, 34, 34, 0, PIXEL_FREQ_74_250 ,}, // v1920x1080p_30Hz + { 3432, 552 , 525 , 45, 35, 36, 0, PIXEL_FREQ_108_108,}, // v2880x480p_60Hz + { 3456, 576 , 625 , 49, 37, 38, 0, PIXEL_FREQ_108 ,}, // v2880x576p_50Hz + { 2304, 384 , 1250, 85, 39, 39, 1, PIXEL_FREQ_72 ,}, // v1920x1080i_50Hz(1250) + { 2640, 720 , 1125, 22, 40, 40, 1, PIXEL_FREQ_148_500, }, // v1920x1080i_100Hz + { 1980, 700 , 750 , 30, 41, 41, 0, PIXEL_FREQ_148_500, }, // v1280x720p_100Hz + { 864 , 144 , 625 , 49, 42, 43, 0, PIXEL_FREQ_54 , }, // v720x576p_100Hz + { 1728, 288 , 625 , 24, 44, 45, 1, PIXEL_FREQ_54 , }, // v720x576i_100Hz + { 2200, 280 , 1125, 22, 46, 46, 1, PIXEL_FREQ_148_500, }, // v1920x1080i_120Hz + { 1650, 370 , 750 , 30, 47, 47, 0, PIXEL_FREQ_148_500, }, // v1280x720p_120Hz + { 858 , 138 , 525 , 54, 48, 49, 0, PIXEL_FREQ_54_054 , }, // v720x480p_120Hz + { 1716, 276 , 525 , 22, 50, 51, 1, PIXEL_FREQ_54_054 , }, // v720x480i_120Hz + { 864 , 144 , 625 , 49, 52, 53, 0, PIXEL_FREQ_108 , }, // v720x576p_200Hz + { 1728, 288 , 625 , 24, 54, 55, 1, PIXEL_FREQ_108 , }, // v720x576i_200Hz + { 858 , 138 , 525 , 45, 56, 57, 0, PIXEL_FREQ_108_108, }, // v720x480p_240Hz + { 1716, 276 , 525 , 22, 58, 59, 1, PIXEL_FREQ_108_108, }, // v720x480i_240Hz + // PHY Freq is not available yet + //{ 3300, 2020, 750 , 30, 60, 60, 0, PIXEL_FREQ_59_400 ,}, // v1280x720p24Hz + { 3960, 2680, 750 , 30, 61, 61, 0, PIXEL_FREQ_74_250 , }, // v1280x720p25Hz + { 3300, 2020, 750 , 30, 62, 62, 0, PIXEL_FREQ_74_250 ,}, // v1280x720p30Hz + // PHY Freq is not available yet + //{ 2200, 280 , 1125, 45, 63, 63, 0, PIXEL_FREQ_297, }, // v1920x1080p120Hz + //{ 2640, 720 , 1125, 45, 64, 64, 0, PIXEL_FREQ_297, }, // v1920x1080p100Hz + //{ 4400, 560 , 2250, 90, 1, 1, 0, 0, PIXEL_FREQ_297, }, // v4Kx2K30Hz +}; + +//! Structure for Checking 3D Mandatory Format in EDID +static const struct edid_3d_mandatory { + /** video Format */ + enum VideoFormat resolution; + + /** 3D Structure */ + enum HDMI3DVideoStructure hdmi_3d_format; +} edid_3d [] = +{ + { v1920x1080p_24Hz, HDMI_3D_FP_FORMAT }, // 1920x1080p @ 23.98/24Hz + { v1280x720p_60Hz, HDMI_3D_FP_FORMAT }, // 1280x720p @ 59.94/60Hz + { v1920x1080i_60Hz, HDMI_3D_SSH_FORMAT }, // 1920x1080i @ 59.94/60Hz + { v1920x1080p_24Hz, HDMI_3D_TB_FORMAT }, // 1920x1080p @ 23.98/24Hz + { v1280x720p_60Hz, HDMI_3D_TB_FORMAT }, // 1280x720p @ 59.94/60Hz + { v1280x720p_50Hz, HDMI_3D_FP_FORMAT }, // 1280x720p @ 50Hz + { v1920x1080i_50Hz, HDMI_3D_SSH_FORMAT }, // 1920x1080i @ 50Hz + { v1280x720p_50Hz, HDMI_3D_TB_FORMAT }, // 1280x720p @ 50Hz +}; + +/** + * Calculate a checksum. + * + * @param buffer [in] Pointer to data to calculate a checksum + * @param size [in] Sizes of data + * + * @return If checksum result is 0, return 1; Otherwise, return 0. + */ +static int CalcChecksum(const unsigned char* const buffer, const int size) +{ + unsigned char i,sum; + int ret = 1; + + // check parameter + if (buffer == NULL ) { + DPRINTF("invalid parameter : buffer\n"); + return 0; + } + for (sum = 0, i = 0 ; i < size; i++) + sum += buffer[i]; + + // check checksum + if (sum != 0) + ret = 0; + + return ret; +} + +/** + * Read EDID Block(128 bytes) + * + * @param blockNum [in] Number of block to read @n + * For example, EDID block = 0, EDID first Extension = 1, and so on. + * @param outBuffer [out] Pointer to buffer to store EDID data + * + * @return If fail to read, return 0; Otherwise, return 1. + */ +static int ReadEDIDBlock(const unsigned int blockNum, unsigned char* const outBuffer) +{ + int segNum, offset, dataPtr; + + // check parameter + if (outBuffer == NULL) { + DPRINTF("invalid parameter : outBuffer\n"); + return 0; + } + + // calculate + segNum = blockNum / 2; + offset = (blockNum % 2) * SIZEOFEDIDBLOCK; + dataPtr = (blockNum) * SIZEOFEDIDBLOCK; + + // read block + if (!EDDCRead(EDID_SEGMENT_POINTER, segNum, EDID_ADDR, offset, SIZEOFEDIDBLOCK, outBuffer)) { + DPRINTF("Fail to Read %dth EDID Block\n", blockNum); + return 0; + } + + if (!CalcChecksum(outBuffer, SIZEOFEDIDBLOCK)) { + DPRINTF("CheckSum fail : %dth EDID Block\n", blockNum); + return 0; + } + + // print data +#ifdef EDID_DEBUG + offset = 0; + do { + LOGI("0x%02X", outBuffer[offset++]); + if (offset % 16) + LOGI(" "); + else + LOGI("\n"); + } while (SIZEOFEDIDBLOCK > offset); +#endif // EDID_DEBUG + return 1; +} + +/** + * Check if EDID data is valid or not. + * + * @return if EDID data is valid, return 1; Otherwise, return 0. + */ +static inline int EDIDValid(void) +{ + return (gEdidData == NULL) ? 0 : 1; +} + +/** + * Search HDMI Vender Specific Data Block(VSDB) in EDID extension block. + * + * @param extension [in] the number of EDID extension block to check + * + * @return if there is a HDMI VSDB, return the offset from start of @n + * EDID extension block. if there is no VSDB, return 0. + */ +static int GetVSDBOffset(const int extension) +{ + unsigned int BlockOffset = extension*SIZEOFEDIDBLOCK; + unsigned int offset = BlockOffset + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen,DTDOffset; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + DTDOffset = gEdidData[BlockOffset + EDID_DETAILED_TIMING_OFFSET_POS]; + + // check if there is HDMI VSDB + while (offset < BlockOffset + DTDOffset) { + // find the block tag and length + // tag + tag = gEdidData[offset] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[offset] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is HDMI VSDB + // if so, check identifier value, if it's hdmi vsbd - return offset + if (tag == EDID_VSDB_TAG_VAL && + gEdidData[offset+1] == 0x03 && + gEdidData[offset+2] == 0x0C && + gEdidData[offset+3] == 0x0 && + blockLen > EDID_VSDB_MIN_LENGTH_VAL ) + return offset; + + // else find next block + offset += blockLen; + } + + // return error + return 0; +} + +/** + * Check if Sink supports the HDMI mode. + * @return If Sink supports HDMI mode, return 1; Otherwise, return 0. + */ +static int CheckHDMIMode(void) +{ + int i; + + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) + if (GetVSDBOffset(i) > 0) // if there is a VSDB, it means RX support HDMI mode + return 1; + + return 0; +} + +/** + * Check if EDID extension block is timing extension block or not. + * @param extension [in] The number of EDID extension block to check + * @return If the block is timing extension, return 1; Otherwise, return 0. + */ +static int IsTimingExtension(const int extension) +{ + int ret = 0; + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return ret; + } + + if (gEdidData[extension*SIZEOFEDIDBLOCK] == EDID_TIMING_EXT_TAG_VAL) { + // check extension revsion number + // revision num == 3 + if (gEdidData[extension*SIZEOFEDIDBLOCK + EDID_TIMING_EXT_REV_NUMBER_POS] == 3) + ret = 1; + // revison num != 3 && DVI mode + else if (!CheckHDMIMode() && + gEdidData[extension*SIZEOFEDIDBLOCK + EDID_TIMING_EXT_REV_NUMBER_POS] != 2) + ret = 1; + } + return ret; +} + +/** + * Check if the video format is contained in - @n + * Detailed Timing Descriptor(DTD) of EDID extension block. + * @param extension [in] Number of EDID extension block to check + * @param videoFormat [in] Video format to check + * @return If the video format is contained in DTD of EDID extension block, -@n + * return 1; Otherwise, return 0. + */ +static int IsContainVideoDTD(const int extension,const enum VideoFormat videoFormat) +{ + int i, StartOffset, EndOffset; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + // if edid block( 0th block ) + if (extension == 0) { + StartOffset = EDID_DTD_START_ADDR; + EndOffset = StartOffset + EDID_DTD_TOTAL_LENGTH; + } else { // if edid extension block + StartOffset = extension*SIZEOFEDIDBLOCK + gEdidData[extension*SIZEOFEDIDBLOCK + EDID_DETAILED_TIMING_OFFSET_POS]; + EndOffset = (extension+1)*SIZEOFEDIDBLOCK; + } + + // check DTD(Detailed Timing Description) + for (i = StartOffset; i < EndOffset; i+= EDID_DTD_BYTE_LENGTH) { + unsigned int hblank = 0, hactive = 0, vblank = 0, vactive = 0, interlaced = 0, pixelclock = 0; + unsigned int vHActive = 0, vVActive = 0, vVBlank = 0; + + // get pixel clock + pixelclock = (gEdidData[i+EDID_DTD_PIXELCLOCK_POS2] << SIZEOFBYTE); + pixelclock |= gEdidData[i+EDID_DTD_PIXELCLOCK_POS1]; + + if (!pixelclock) + continue; + + // get HBLANK value in pixels + hblank = gEdidData[i+EDID_DTD_HBLANK_POS2] & EDID_DTD_HBLANK_POS2_MASK; + hblank <<= SIZEOFBYTE; // lower 4 bits + hblank |= gEdidData[i+EDID_DTD_HBLANK_POS1]; + + // get HACTIVE value in pixels + hactive = gEdidData[i+EDID_DTD_HACTIVE_POS2] & EDID_DTD_HACTIVE_POS2_MASK; + hactive <<= (SIZEOFBYTE/2); // upper 4 bits + hactive |= gEdidData[i+EDID_DTD_HACTIVE_POS1]; + + // get VBLANK value in pixels + vblank = gEdidData[i+EDID_DTD_VBLANK_POS2] & EDID_DTD_VBLANK_POS2_MASK; + vblank <<= SIZEOFBYTE; // lower 4 bits + vblank |= gEdidData[i+EDID_DTD_VBLANK_POS1]; + + // get VACTIVE value in pixels + vactive = gEdidData[i+EDID_DTD_VACTIVE_POS2] & EDID_DTD_VACTIVE_POS2_MASK; + vactive <<= (SIZEOFBYTE/2); // upper 4 bits + vactive |= gEdidData[i+EDID_DTD_VACTIVE_POS1]; + + vHActive = aVideoParams[videoFormat].HTotal - aVideoParams[videoFormat].HBlank; + if (aVideoParams[videoFormat].interlaced == 1) { + if (aVideoParams[videoFormat].VIC == v1920x1080i_50Hz_1250) { // VTOP and VBOT are same + vVActive = (aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank*2)/2; + vVBlank = aVideoParams[videoFormat].VBlank; + } else { + vVActive = (aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank*2 - 1)/2; + vVBlank = aVideoParams[videoFormat].VBlank; + } + } else { + vVActive = aVideoParams[videoFormat].VTotal - aVideoParams[videoFormat].VBlank; + vVBlank = aVideoParams[videoFormat].VBlank; + } + + // get Interlaced Mode Value + interlaced = (int)(gEdidData[i+EDID_DTD_INTERLACE_POS] & EDID_DTD_INTERLACE_MASK); + if (interlaced) + interlaced = 1; + + DPRINTF("EDID: hblank = %d,vblank = %d, hactive = %d, vactive = %d\n" + ,hblank,vblank,hactive,vactive); + DPRINTF("REQ: hblank = %d,vblank = %d, hactive = %d, vactive = %d\n" + ,aVideoParams[videoFormat].HBlank + ,vVBlank,vHActive,vVActive); + + if (hblank == aVideoParams[videoFormat].HBlank && vblank == vVBlank // blank + && hactive == vHActive && vactive == vVActive) { //line + unsigned int EDIDpixelclock = aVideoParams[videoFormat].PixelClock; + EDIDpixelclock /= 100; pixelclock /= 100; + + if (pixelclock == EDIDpixelclock) { + DPRINTF("Sink Support the Video mode\n"); + return 1; + } + } + } + return 0; +} + +/** + * Check if a VIC(Video Identification Code) is contained in -@n + * EDID extension block. + * @param extension [in] Number of EDID extension block to check + * @param VIC [in] VIC to check + * @return If the VIC is contained in contained in EDID extension block, -@n + * return 1; Otherwise, return 0. + */ +static int IsContainVIC(const int extension, const int VIC) +{ + unsigned int StartAddr = extension*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + if (!EDIDValid() || (extension > gExtensions)) { + DPRINTF("EDID Data is not available\n"); + return 0; + } + + // while + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + DPRINTF("tag = %d\n",tag); + DPRINTF("blockLen = %d\n",blockLen-1); + + // check if it is short video description + if (tag == EDID_SHORT_VID_DEC_TAG_VAL) { + // if so, check SVD + unsigned int i; + for (i = 1; i < blockLen; i++) { + DPRINTF("EDIDVIC = %d\n",gEdidData[ExtAddr+i] & EDID_SVD_VIC_MASK); + DPRINTF("VIC = %d\n",VIC); + + // check VIC with SVDB + if (VIC == (gEdidData[ExtAddr+i] & EDID_SVD_VIC_MASK)) { + DPRINTF("Sink Device supports requested video mode\n"); + return 1; + } + } + } + // else find next block + ExtAddr += blockLen; + } + + return 0; +} + +/** + * Check if EDID contains the video format. + * @param videoFormat [in] Video format to check + * @param pixelRatio [in] Pixel aspect ratio of video format to check + * @return if EDID contains the video format, return 1; Otherwise, return 0. + */ +static int CheckResolution(const enum VideoFormat videoFormat, + const enum PixelAspectRatio pixelRatio) +{ + int i, vic; + + // read EDID + if (!EDIDRead()) + return 0; + + // check ET(Established Timings) for 640x480p@60Hz + if (videoFormat == v640x480p_60Hz // if it's 640x480p@60Hz + && (gEdidData[EDID_ET_POS] & EDID_ET_640x480p_VAL)) // it support + return 1; + + // check STI(Standard Timing Identification) + // do not need + + // check DTD(Detailed Timing Description) of EDID block(0th) + if (IsContainVideoDTD(0,videoFormat)) + return 1; + + // check EDID Extension + vic = (pixelRatio == HDMI_PIXEL_RATIO_16_9) ? + aVideoParams[videoFormat].VIC16_9 : aVideoParams[videoFormat].VIC; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) // if it's timing block + if (IsContainVIC(i, vic) || IsContainVideoDTD(i, videoFormat)) + return 1; + } + + return 0; +} + +/** + * Check if EDID supports the color depth. + * @param depth [in] Color depth + * @param space [in] Color space + * @return If EDID supports the color depth, return 1; Otherwise, return 0. + */ +static int CheckColorDepth(const enum ColorDepth depth,const enum ColorSpace space) +{ + int i; + unsigned int StartAddr; + + // if color depth == 24 bit, no need to check + if (depth == HDMI_CD_24) + return 1; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && ((StartAddr = GetVSDBOffset(i)) > 0)) { // check block + int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + if (blockLength >= EDID_DC_POS) { + // get supported DC value + int deepColor = gEdidData[StartAddr + EDID_DC_POS] & EDID_DC_MASK; + DPRINTF("EDID deepColor = %x\n",deepColor); + // check supported DeepColor + // if YCBCR444 + if (space == HDMI_CS_YCBCR444) { + if ( !(deepColor & EDID_DC_YCBCR_VAL)) + return 0; + } + + // check colorDepth + switch (depth) { + case HDMI_CD_36: + deepColor &= EDID_DC_36_VAL; + break; + case HDMI_CD_30: + deepColor &= EDID_DC_30_VAL; + break; + case HDMI_CD_24: + deepColor = 1; + break; + default : + deepColor = 0; + } + if (deepColor) + return 1; + else + return 0; + } + } + } + + return 0; +} + +/** + * Check if EDID supports the color space. + * @param space [in] Color space + * @return If EDID supports the color space, return 1; Otherwise, return 0. + */ +static int CheckColorSpace(const enum ColorSpace space) +{ + int i; + + // RGB is default + if (space == HDMI_CS_RGB) + return 1; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // read Color Space + int CS = gEdidData[i*SIZEOFEDIDBLOCK + EDID_COLOR_SPACE_POS]; + + if ((space == HDMI_CS_YCBCR444 && (CS & EDID_YCBCR444_CS_MASK)) || // YCBCR444 + (space == HDMI_CS_YCBCR422 && (CS & EDID_YCBCR422_CS_MASK))) // YCBCR422 + return 1; + } + } + return 0; +} + +/** + * Check if EDID supports the colorimetry. + * @param color [in] Colorimetry + * @return If EDID supports the colorimetry, return 1; Otherwise, return 0. + */ +static int CheckColorimetry(const enum HDMIColorimetry color) +{ + int i; + + // do not need to parse if not extended colorimetry + if (color == HDMI_COLORIMETRY_NO_DATA || + color == HDMI_COLORIMETRY_ITU601 || + color == HDMI_COLORIMETRY_ITU709) + return 1; + + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // check address + unsigned int ExtAddr = i*SIZEOFEDIDBLOCK + EDID_DATA_BLOCK_START_POS; + unsigned int EndAddr = i*SIZEOFEDIDBLOCK + gEdidData[i*SIZEOFEDIDBLOCK + EDID_DETAILED_TIMING_OFFSET_POS]; + unsigned int tag,blockLen; + + while (ExtAddr < EndAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is colorimetry block + if (tag == EDID_EXTENDED_TAG_VAL && // extended tag + gEdidData[ExtAddr+1] == EDID_EXTENDED_COLORIMETRY_VAL && // colorimetry block + (blockLen-1) == EDID_EXTENDED_COLORIMETRY_BLOCK_LEN) { // check length + // get supported DC value + int colorimetry = (gEdidData[ExtAddr + 2]); + int metadata = (gEdidData[ExtAddr + 3]); + + DPRINTF("EDID extened colorimetry = %x\n",colorimetry); + DPRINTF("EDID gamut metadata profile = %x\n",metadata); + + // check colorDepth + switch (color) { + case HDMI_COLORIMETRY_EXTENDED_xvYCC601: + if (colorimetry & EDID_XVYCC601_MASK && metadata) + return 1; + break; + case HDMI_COLORIMETRY_EXTENDED_xvYCC709: + if (colorimetry & EDID_XVYCC709_MASK && metadata) + return 1; + break; + default: + break; + } + return 0; + } + // else find next block + ExtAddr += blockLen; + } + } + } + + return 0; +} + +/** + * Get Max TMDS clock that HDMI Rx can receive. + * @return If available, return MaxTMDS clock; Otherwise, return 0. + */ +static unsigned int GetMaxTMDS(void) +{ + int i; + unsigned int StartAddr; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && ((StartAddr = GetVSDBOffset(i)) > 0)) { // check block + int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + if (blockLength >= EDID_MAX_TMDS_POS) { + // get supported DC value + return gEdidData[StartAddr + EDID_MAX_TMDS_POS]; + } + } + } + + return 0; +} + +/** + * Save first 16 VIC of EDID + */ +static void SaveVIC(void) +{ + int extension; + int vic_count = 0; + for (extension = 1; extension <= gExtensions && vic_count < NUM_OF_VIC_FOR_3D; extension++) { + unsigned int StartAddr = extension*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + // check if it is short video description + if (tag == EDID_SHORT_VID_DEC_TAG_VAL) { + // if so, check SVD + unsigned int edid_index; + for (edid_index = 1; edid_index < blockLen && vic_count < NUM_OF_VIC_FOR_3D; edid_index++) { + DPRINTF("EDIDVIC = %d\r\n", gEdidData[ExtAddr+edid_index] & EDID_SVD_VIC_MASK); + + // check VIC with SVDB + aVIC[vic_count++] = (gEdidData[ExtAddr+edid_index] & EDID_SVD_VIC_MASK); + } + } + // else find next block + ExtAddr += blockLen; + } + } +} + +/** + * Check if Rx supports requested 3D format. + * @param pVideo [in] HDMI Video Parameter + * @return If Rx supports requested 3D format, return 1; Otherwise, return 0. + */ +static int EDID3DFormatSupport(const struct HDMIVideoParameter * const pVideo) +{ + int edid_index; + unsigned int StartAddr; + unsigned int vic; + vic = (pVideo->pixelAspectRatio == HDMI_PIXEL_RATIO_16_9) ? + aVideoParams[pVideo->resolution].VIC16_9 : aVideoParams[pVideo->resolution].VIC; + + // if format == 2D, no need to check + if (pVideo->hdmi_3d_format == HDMI_2D_VIDEO_FORMAT) + return 1; + + // check EDID data is valid or not + if (!EDIDRead()) + return 0; + + // save first 16 VIC to check + SaveVIC(); + + // find VSDB + for (edid_index = 1; edid_index <= gExtensions; edid_index++) { + if (IsTimingExtension(edid_index) // if it's timing block + && ((StartAddr = GetVSDBOffset(edid_index)) > 0)) { // check block + unsigned int blockLength = gEdidData[StartAddr] & EDID_DATA_BLOCK_SIZE_MASK; + unsigned int VSDBHdmiVideoPre = 0; + unsigned int VSDB3DPresent = 0; + unsigned int VSDB3DMultiPresent = 0; + unsigned int HDMIVICLen; + unsigned int HDMI3DLen; + int Hdmi3DStructure = 0; + unsigned int Hdmi3DMask = 0xFFFF; + unsigned int latency_offset = 0; + + DPRINTF("VSDB Block length[0x%x] = 0x%x\r\n",StartAddr,blockLength); + + // get HDMI Video Present value + if (blockLength >= EDID_HDMI_EXT_POS) { + VSDBHdmiVideoPre = gEdidData[StartAddr + EDID_HDMI_EXT_POS] + & EDID_HDMI_VIDEO_PRESENT_MASK; + DPRINTF("EDID HDMI Video Present = 0x%x\n",VSDBHdmiVideoPre); + } else { // data related to 3D format is not available + return 0; + } + + // check if latency field is available + latency_offset = (gEdidData[StartAddr + EDID_HDMI_EXT_POS] + & EDID_HDMI_LATENCY_MASK) >> EDID_HDMI_LATENCY_POS; + if (latency_offset == 0) + latency_offset = 4; + else if (latency_offset == 3) + latency_offset = 0; + else + latency_offset = 2; + + StartAddr -= latency_offset; + + // HDMI_VIC_LEN + HDMIVICLen = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS] + & EDID_HDMI_VSDB_VIC_LEN_MASK) >> EDID_HDMI_VSDB_VIC_LEN_BIT; + + if (pVideo->hdmi_3d_format == HDMI_VIC_FORMAT) { + if (HDMIVICLen) { + for (edid_index = 0; edid_index < (int)HDMIVICLen; edid_index++) { + if (vic == gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + edid_index]) + return 1; + } + return 0; + } else { + return 0; + } + } + + // HDMI_3D_LEN + HDMI3DLen = gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS] + & EDID_HDMI_VSDB_3D_LEN_MASK; + + DPRINTF("HDMI VIC LENGTH[%x] = %x\r\n", + StartAddr + EDID_HDMI_EXT_LENGTH_POS, HDMIVICLen); + DPRINTF("HDMI 3D LENGTH[%x] = %x\r\n", + StartAddr + EDID_HDMI_EXT_LENGTH_POS, HDMI3DLen); + + // check 3D_Present bit + if (blockLength >= (EDID_HDMI_3D_PRESENT_POS - latency_offset)) { + VSDB3DPresent = gEdidData[StartAddr + EDID_HDMI_3D_PRESENT_POS] + & EDID_HDMI_3D_PRESENT_MASK; + VSDB3DMultiPresent = gEdidData[StartAddr + EDID_HDMI_3D_PRESENT_POS] + & EDID_HDMI_3D_MULTI_PRESENT_MASK; + } + + if (VSDB3DPresent) { + DPRINTF("VSDB 3D Present!!!\r\n"); + // check with 3D madatory format + if (CheckResolution(pVideo->resolution, pVideo->pixelAspectRatio)) { + int size = sizeof(edid_3d)/sizeof(struct edid_3d_mandatory); + for (edid_index = 0; edid_index < size; edid_index++) { + if (edid_3d[edid_index].resolution == pVideo->resolution && + edid_3d[edid_index].hdmi_3d_format == pVideo->hdmi_3d_format ) + return 1; + } + } + } + + // check 3D_Multi_Present bit + if (VSDB3DMultiPresent) { + DPRINTF("VSDB 3D Multi Present!!! = 0x%02x\r\n",VSDB3DMultiPresent); + // 3D Structure only + if (VSDB3DMultiPresent == EDID_3D_STRUCTURE_ONLY_EXIST) { + // 3D Structure All + Hdmi3DStructure = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 1] << 8); + Hdmi3DStructure |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 2]; + DPRINTF("VSDB 3D Structure!!! = [0x%02x]\r\n",Hdmi3DStructure); + } + + // 3D Structure and Mask + if (VSDB3DMultiPresent == EDID_3D_STRUCTURE_MASK_EXIST) { + // 3D Structure All + Hdmi3DStructure = (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 1] << 8); + Hdmi3DStructure |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 2]; + // 3D Structure Mask + Hdmi3DMask |= (gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 3] << 8); + Hdmi3DMask |= gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + 4]; + DPRINTF("VSDB 3D Structure!!! = [0x%02x]\r\n",Hdmi3DStructure); + DPRINTF("VSDB 3D Mask!!! = [0x%02x]\r\n",Hdmi3DMask); + DPRINTF("Current 3D Video format!!! = [%d]\r\n",pVideo->hdmi_3d_format); + DPRINTF("Current 3D Video format!!! = [0x%02x]\r\n",1<hdmi_3d_format); + } + + // check 3D Structure and Mask + if (Hdmi3DStructure & (1<hdmi_3d_format)) { + DPRINTF("VSDB 3D Structure Contains Current Video Structure!!!\r\n"); + // check first 16 EDID + for (edid_index = 0; edid_index < NUM_OF_VIC_FOR_3D; edid_index++) { + DPRINTF("VIC = %d, EDID Vic = %d!!!\r\n",vic,aVIC[edid_index]); + if (Hdmi3DMask & (1<= (EDID_HDMI_EXT_LENGTH_POS - latency_offset)) { + unsigned int HDMI3DExtLen = HDMI3DLen - (VSDB3DMultiPresent>>EDID_HDMI_3D_MULTI_PRESENT_BIT)*2; + unsigned int VICOrder; + + // check if there is 3D extra data ? + //TODO: check 3D_Detail in case of SSH + if (HDMI3DExtLen) { + // check HDMI 3D Extra Data + for (edid_index = 0; edid_index < (int)(HDMI3DExtLen / 2); edid_index++) { + VICOrder = gEdidData[StartAddr + EDID_HDMI_EXT_LENGTH_POS + HDMIVICLen + + (VSDB3DMultiPresent>>EDID_HDMI_3D_MULTI_PRESENT_BIT) * 2 + edid_index * 2] + & EDID_HDMI_2D_VIC_ORDER_MASK; + VICOrder = (1<>EDID_HDMI_3D_MULTI_PRESENT_BIT) * 2 + edid_index * 2] + & EDID_HDMI_3D_STRUCTURE_MASK; + Hdmi3DStructure = (1<hdmi_3d_format && vic == aVIC[VICOrder]) + return 1; + } + } + } + } + } + + return 0; +} + +/** + * Initialize EDID library. This will intialize DDC library. + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDOpen(void) +{ + // init DDC + return DDCOpen(); +} + +/** + * Finalize EDID library. This will finalize DDC library. + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDClose(void) +{ + // reset EDID + EDIDReset(); + + // close EDDC + return DDCClose(); +} + +/** + * Read EDID data of Rx. + * @return If success, return 1; Otherwise, return 0; + */ +int EDIDRead(void) +{ + int block,dataPtr; + unsigned char temp[SIZEOFEDIDBLOCK]; + + // if already read?? + if (EDIDValid()) + return 1; + + // read EDID Extension Number + // read EDID + if (!ReadEDIDBlock(0,temp)) + return 0; + + // get extension + gExtensions = temp[EDID_EXTENSION_NUMBER_POS]; + + // prepare buffer + gEdidData = (unsigned char*)malloc((gExtensions+1)*SIZEOFEDIDBLOCK); + if (!gEdidData) + return 0; + + // copy EDID Block 0 + memcpy(gEdidData,temp,SIZEOFEDIDBLOCK); + + // read EDID Extension + for (block = 1,dataPtr = SIZEOFEDIDBLOCK; block <= gExtensions; block++,dataPtr+=SIZEOFEDIDBLOCK) { + // read extension 1~gExtensions + if (!ReadEDIDBlock(block, gEdidData+dataPtr)) { + // reset buffer + EDIDReset(); + return 0; + } + } + + // check if extension is more than 1, and first extension block is not block map. + if (gExtensions > 1 && gEdidData[SIZEOFEDIDBLOCK] != EDID_BLOCK_MAP_EXT_TAG_VAL) { + // reset buffer + DPRINTF("EDID has more than 1 extension but, first extension block is not block map\n"); + EDIDReset(); + return 0; + } + + return 1; +} + +/** + * Reset stored EDID data. + */ +void EDIDReset(void) +{ + if (gEdidData) { + free(gEdidData); + gEdidData = NULL; + DPRINTF("\t\t\t\tEDID is reset!!!\n"); + } +} + +/** + * Get CEC physical address. + * @param outAddr [out] CEC physical address. LSB 2 bytes is available. [0:0:AB:CD] + * @return If success, return 1; Otherwise, return 0. + */ +int EDIDGetCECPhysicalAddress(int* const outAddr) +{ + int i; + unsigned int StartAddr; + + // check EDID data is valid or not + // read EDID + if (!EDIDRead()) + return 0; + + // find VSDB + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i) // if it's timing block + && (StartAddr = GetVSDBOffset(i)) > 0) { // check block + // get supported DC value + // int tempDC1 = (int)(gEdidData[tempAddr+EDID_DC_POS]); + int phyAddr = gEdidData[StartAddr + EDID_CEC_PHYICAL_ADDR] << 8; + phyAddr |= gEdidData[StartAddr + EDID_CEC_PHYICAL_ADDR+1]; + + DPRINTF("phyAddr = %x\n",phyAddr); + + *outAddr = phyAddr; + + return 1; + } + } + + return 0; +} + +/** + * Check if Rx supports HDMI/DVI mode or not. + * @param video [in] HDMI or DVI mode to check + * @return If Rx supports requested mode, return 1; Otherwise, return 0. + */ +int EDIDHDMIModeSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check hdmi mode + if (video->mode == HDMI) { + if (!CheckHDMIMode()) { + DPRINTF("HDMI mode Not Supported\n"); + return 0; + } + } + return 1; +} + +/** + * Check if Rx supports requested video resoultion or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDVideoResolutionSupport(struct HDMIVideoParameter * const video) +{ + unsigned int TMDSClock; + unsigned int MaxTMDS = 0; + + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // get max tmds + MaxTMDS = GetMaxTMDS()*5; + + // Check MAX TMDS + TMDSClock = aVideoParams[video->resolution].PixelClock/100; + if (video->colorDepth == HDMI_CD_36) + TMDSClock *= 1.5; + else if (video->colorDepth == HDMI_CD_30) + TMDSClock *=1.25; + + DPRINTF("MAX TMDS = %d, Current TMDS = %d\n",MaxTMDS, TMDSClock); + if (MaxTMDS != 0 && MaxTMDS < TMDSClock) { + DPRINTF("Pixel clock is beyond Maximun TMDS in EDID\n"); + return 0; + } + + // check resolution + if (!CheckResolution(video->resolution,video->pixelAspectRatio)) { + DPRINTF("Video Resolution Not Supported\n"); + return 0; + } + + // check 3D format + if (!EDID3DFormatSupport(video)) { + DPRINTF("3D Format Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested color depth or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorDepthSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check resolution + if (!CheckColorDepth(video->colorDepth,video->colorSpace)) { + DPRINTF("Color Depth Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested color space or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorSpaceSupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + // check color space + if (!CheckColorSpace(video->colorSpace)) { + DPRINTF("Color Space Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested colorimetry or not. + * @param video [in] Video parameters to check + * @return If Rx supports video parameters, return 1; Otherwise, return 0. + */ +int EDIDColorimetrySupport(struct HDMIVideoParameter * const video) +{ + // check if read edid? + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check colorimetry + if (!CheckColorimetry(video->colorimetry)) { + DPRINTF("Colorimetry Not Supported\n"); + return 0; + } + + return 1; +} + +/** + * Check if Rx supports requested audio parameters or not. + * @param audio [in] Audio parameters to check + * @return If Rx supports audio parameters, return 1; Otherwise, return 0. + */ +int EDIDAudioModeSupport(struct HDMIAudioParameter * const audio) +{ + int i; + + // read EDID + if (!EDIDRead()) { + DPRINTF("EDID Read Fail!!!\n"); + return 0; + } + + // check EDID Extension + // find timing block + for (i = 1; i <= gExtensions; i++) { + if (IsTimingExtension(i)) { // if it's timing block + // find Short Audio Description + unsigned int StartAddr = i*SIZEOFEDIDBLOCK; + unsigned int ExtAddr = StartAddr + EDID_DATA_BLOCK_START_POS; + unsigned int tag,blockLen; + unsigned int DTDStartAddr = gEdidData[StartAddr + EDID_DETAILED_TIMING_OFFSET_POS]; + + while (ExtAddr < StartAddr + DTDStartAddr) { + // find the block tag and length + // tag + tag = gEdidData[ExtAddr] & EDID_TAG_CODE_MASK; + // block len + blockLen = (gEdidData[ExtAddr] & EDID_DATA_BLOCK_SIZE_MASK) + 1; + + DPRINTF("tag = %d\n",tag); + DPRINTF("blockLen = %d\n",blockLen-1); + + // check if it is short video description + if (tag == EDID_SHORT_AUD_DEC_TAG_VAL) { + // if so, check SAD + unsigned int j, channelNum; + int audioFormat,sampleFreq,wordLen; + for (j = 1; j < blockLen; j += 3) { + audioFormat = gEdidData[ExtAddr+j] & EDID_SAD_CODE_MASK; + channelNum = gEdidData[ExtAddr+j] & EDID_SAD_CHANNEL_MASK; + sampleFreq = gEdidData[ExtAddr+j+1]; + wordLen = gEdidData[ExtAddr+j+2]; + + DPRINTF("request = %d, EDIDAudioFormatCode = %d\n",(audio->formatCode)<<3, audioFormat); + DPRINTF("request = %d, EDIDChannelNumber= %d\n",(audio->channelNum)-1, channelNum); + DPRINTF("request = %d, EDIDSampleFreq= %d\n",1<<(audio->sampleFreq), sampleFreq); + DPRINTF("request = %d, EDIDWordLeng= %d\n",1<<(audio->wordLength), wordLen); + + // check parameter + // check audioFormat + if (audioFormat & ( (audio->formatCode) << 3) && // format code + channelNum >= ( (audio->channelNum) -1) && // channel number + (sampleFreq & (1<<(audio->sampleFreq)))) { // sample frequency + if (audioFormat == LPCM_FORMAT) { // check wordLen + int ret = 0; + switch (audio->wordLength) { + case WORD_16: + case WORD_17: + case WORD_18: + case WORD_19: + case WORD_20: + ret = wordLen & (1<<1); + break; + case WORD_21: + case WORD_22: + case WORD_23: + case WORD_24: + ret = wordLen & (1<<2); + break; + } + return ret; + } + return 1; // if not LPCM + } + } + } + // else find next block + ExtAddr += blockLen; + } + } + } + + return 0; +} diff --git a/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.h b/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.h new file mode 100644 index 0000000..dfd3096 --- /dev/null +++ b/exynos5/hal/libhdmi/libsForhdmi/libedid/libedid.h @@ -0,0 +1,42 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBEDID_H_ +#define _LIBEDID_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "video.h" +#include "audio.h" + +int EDIDOpen(void); +int EDIDRead(void); +void EDIDReset(void); +int EDIDHDMIModeSupport(struct HDMIVideoParameter *video); +int EDIDVideoResolutionSupport(struct HDMIVideoParameter *video); +int EDIDColorDepthSupport(struct HDMIVideoParameter *video); +int EDIDColorSpaceSupport(struct HDMIVideoParameter *video); +int EDIDColorimetrySupport(struct HDMIVideoParameter *video); +int EDIDAudioModeSupport(struct HDMIAudioParameter *audio); +int EDIDGetCECPhysicalAddress(int* outAddr); +int EDIDClose(void); + +#ifdef __cplusplus +} +#endif +#endif /* _LIBEDID_H_ */ diff --git a/exynos5/hal/libhwcomposer/Android.mk b/exynos5/hal/libhwcomposer/Android.mk new file mode 100644 index 0000000..982d1be --- /dev/null +++ b/exynos5/hal/libhwcomposer/Android.mk @@ -0,0 +1,82 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation, not prelinked and stored in +# hw/..so + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL \ + libGLESv1_CM + +LOCAL_SHARED_LIBRARIES += libion + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := SecHWCLog.cpp SecHWCUtils.cpp SecHWC.cpp + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libfimg + +ifeq ($(TARGET_SOC),exynos4210) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210 +endif + +ifeq ($(TARGET_SOC),exynos4212) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4212 +endif + +ifeq ($(TARGET_SOC),exynos5250) +LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250 +endif + +ifeq ($(BOARD_USES_HDMI),true) +LOCAL_C_INCLUDES += \ + device/samsung/$(TARGET_BOARD_PLATFORM)/libhwcomposer \ + device/samsung/$(TARGET_BOARD_PLATFORM)/include \ + device/samsung/$(TARGET_BOARD_PLATFORM)/libhdmi/libhdmiservice + +LOCAL_SHARED_LIBRARIES += libhdmiclient libTVOut + +LOCAL_CFLAGS += -DBOARD_USES_HDMI +LOCAL_CFLAGS += -DBOARD_HDMI_STD=$(BOARD_HDMI_STD) +LOCAL_CFLAGS += -DVIDEO_DUAL_DISPLAY + +ifeq ($(BOARD_USES_HDMI_SUBTITLES),true) + LOCAL_CFLAGS += -DBOARD_USES_HDMI_SUBTITLES +endif + +ifeq ($(BOARD_HDMI_STD), STD_NTSC_M) +LOCAL_CFLAGS += -DSTD_NTSC_M +endif + +ifeq ($(BOARD_HDMI_STD),STD_480P) +LOCAL_CFLAGS += -DSTD_480P +endif + +ifeq ($(BOARD_HDMI_STD),STD_720P) +LOCAL_CFLAGS += -DSTD_720P +endif + +ifeq ($(BOARD_HDMI_STD),STD_1080P) +LOCAL_CFLAGS += -DSTD_1080P +endif +endif + +LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos5/hal/libhwcomposer/SecHWC.cpp b/exynos5/hal/libhwcomposer/SecHWC.cpp new file mode 100644 index 0000000..31ea1b5 --- /dev/null +++ b/exynos5/hal/libhwcomposer/SecHWC.cpp @@ -0,0 +1,901 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#include +#include +#include + +#include "SecHWCUtils.h" +#include "gralloc_priv.h" + +#ifdef HWC_HWOVERLAY +#include +#endif + +//#define CHECK_EGL_FPS +#ifdef CHECK_EGL_FPS +extern void check_fps(); +#endif + +#if defined(BOARD_USES_HDMI) +#include "SecHdmiClient.h" +#include "SecTVOutService.h" +#include "SecHdmi.h" + +static int lcd_width, lcd_height; +static int prev_format = 0; + +#define CHECK_TIME_DEBUG 0 +#define SUPPORT_AUTO_UI_ROTATE +#endif + +static int hwc_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device); + +static struct hw_module_methods_t hwc_module_methods = { + open: hwc_device_open +}; + +hwc_module_t HAL_MODULE_INFO_SYM = { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: HWC_HARDWARE_MODULE_ID, + name: "Samsung S5PC21X hwcomposer module", + author: "SAMSUNG", + methods: &hwc_module_methods, + } +}; + +/*****************************************************************************/ + +static void dump_layer(hwc_layer_t const* l) { + LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, " + "{%d,%d,%d,%d}, {%d,%d,%d,%d}", + l->compositionType, l->flags, l->handle, l->transform, l->blending, + l->sourceCrop.left, + l->sourceCrop.top, + l->sourceCrop.right, + l->sourceCrop.bottom, + l->displayFrame.left, + l->displayFrame.top, + l->displayFrame.right, + l->displayFrame.bottom); +} + +void calculate_rect(struct hwc_win_info_t *win, hwc_layer_t *cur, + sec_rect *rect) +{ + rect->x = cur->displayFrame.left; + rect->y = cur->displayFrame.top; + rect->w = cur->displayFrame.right - cur->displayFrame.left; + rect->h = cur->displayFrame.bottom - cur->displayFrame.top; + + if (rect->x < 0) { + if (rect->w + rect->x > win->lcd_info.xres) + rect->w = win->lcd_info.xres; + else + rect->w = rect->w + rect->x; + rect->x = 0; + } else { + if (rect->w + rect->x > win->lcd_info.xres) + rect->w = win->lcd_info.xres - rect->x; + } + if (rect->y < 0) { + if (rect->h + rect->y > win->lcd_info.yres) + rect->h = win->lcd_info.yres; + else + rect->h = rect->h + rect->y; + rect->y = 0; + } else { + if (rect->h + rect->y > win->lcd_info.yres) + rect->h = win->lcd_info.yres - rect->y; + } +} + +static int set_src_dst_img_rect(hwc_layer_t *cur, + struct hwc_win_info_t *win, + struct sec_img *src_img, + struct sec_img *dst_img, + struct sec_rect *src_rect, + struct sec_rect *dst_rect, + int win_idx) +{ + private_handle_t *prev_handle = (private_handle_t *)(cur->handle); + sec_rect rect; + + /* 1. Set src_img from prev_handle */ + src_img->f_w = prev_handle->width; + src_img->f_h = prev_handle->height; + src_img->w = prev_handle->width; + src_img->h = prev_handle->height; + src_img->format = prev_handle->format; + src_img->base = (uint32_t)prev_handle->base; + src_img->offset = prev_handle->offset; + src_img->mem_id = prev_handle->fd; + src_img->paddr = prev_handle->paddr; + src_img->usage = prev_handle->usage; + src_img->uoffset = prev_handle->uoffset; + src_img->voffset = prev_handle->voffset; + + switch (src_img->format) { + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + src_img->f_w = (src_img->f_w + 15) & ~15; + src_img->f_h = (src_img->f_h + 15) & ~15; + break; + default: + src_img->f_w = src_img->w; + src_img->f_h = src_img->h; + break; + } + + /* 2. Set dst_img from window(lcd) */ + calculate_rect(win, cur, &rect); + dst_img->f_w = win->lcd_info.xres; + dst_img->f_h = win->lcd_info.yres; + dst_img->w = rect.w; + dst_img->h = rect.h; + + switch (win->lcd_info.bits_per_pixel) { + case 32: + dst_img->format = HAL_PIXEL_FORMAT_RGBX_8888; + break; + default: + dst_img->format = HAL_PIXEL_FORMAT_RGB_565; + break; + } + + dst_img->base = win->addr[win->buf_index]; + dst_img->offset = 0; + dst_img->mem_id = 0; + + /* 3. Set src_rect(crop rect) */ + if (cur->displayFrame.left < 0) { + src_rect->x = + (0 - cur->displayFrame.left) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + if (cur->displayFrame.right + 1 > win->lcd_info.xres) { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x - + (cur->displayFrame.right - win->lcd_info.xres) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + } else { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x; + } + } else { + src_rect->x = cur->sourceCrop.left; + if (cur->displayFrame.right + 1 > win->lcd_info.xres) { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1) - + src_rect->x - + (cur->displayFrame.right - win->lcd_info.xres) + *(src_img->w) + /(cur->displayFrame.right - cur->displayFrame.left + 1); + } else { + src_rect->w = + (cur->sourceCrop.right - cur->sourceCrop.left + 1); + } + } + if (cur->displayFrame.top < 0) { + src_rect->y = + (0 - cur->displayFrame.top) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y - + (cur->displayFrame.bottom - win->lcd_info.yres) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + } else { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y; + } + } else { + src_rect->y = cur->sourceCrop.top; + if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) - + src_rect->y - + (cur->displayFrame.bottom - win->lcd_info.yres) + *(src_img->h) + /(cur->displayFrame.bottom - cur->displayFrame.top + 1); + } else { + src_rect->h = + (cur->sourceCrop.bottom - cur->sourceCrop.top + 1); + } + } + + SEC_HWC_Log(HWC_LOG_DEBUG, + "crop information()::" + "sourceCrop left(%d),top(%d),right(%d),bottom(%d)," + "src_rect x(%d),y(%d),w(%d),h(%d)," + "prev_handle w(%d),h(%d)", + cur->sourceCrop.left, + cur->sourceCrop.top, + cur->sourceCrop.right, + cur->sourceCrop.bottom, + src_rect->x, src_rect->y, src_rect->w, src_rect->h, + prev_handle->width, prev_handle->height); + + src_rect->x = SEC_MAX(src_rect->x, 0); + src_rect->y = SEC_MAX(src_rect->y, 0); + src_rect->w = SEC_MAX(src_rect->w, 0); + src_rect->w = SEC_MIN(src_rect->w, prev_handle->width); + src_rect->h = SEC_MAX(src_rect->h, 0); + src_rect->h = SEC_MIN(src_rect->h, prev_handle->height); + + /* 4. Set dst_rect(fb or lcd) + * fimc dst image will be stored from left top corner + */ + dst_rect->x = 0; + dst_rect->y = 0; + dst_rect->w = win->rect_info.w; + dst_rect->h = win->rect_info.h; + + /* Summery */ + SEC_HWC_Log(HWC_LOG_DEBUG, + "set_src_dst_img_rect()::" + "SRC w(%d),h(%d),f_w(%d),f_h(%d),fmt(0x%x)," + "base(0x%x),offset(%d),paddr(0x%X)=>\r\n" + " DST w(%d),h(%d),f(0x%x),base(0x%x)," + "offset(%d),mem_id(%d)," + "rot(%d),win_idx(%d)" + " SRC_RECT x(%d),y(%d),w(%d),h(%d)=>" + "DST_RECT x(%d),y(%d),w(%d),h(%d)", + src_img->w, src_img->h, src_img->f_w, src_img->f_h, src_img->format, + src_img->base, src_img->offset, src_img->paddr, + dst_img->w, dst_img->h, dst_img->format, dst_img->base, + dst_img->offset, dst_img->mem_id, + cur->transform, win_idx, + src_rect->x, src_rect->y, src_rect->w, src_rect->h, + dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h); + + return 0; +} + +static int get_hwc_compos_decision(hwc_layer_t* cur, int iter, int win_cnt) +{ + if(cur->flags & HWC_SKIP_LAYER || !cur->handle) { + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::is_skip_layer %d cur->handle %x ", + __func__, cur->flags & HWC_SKIP_LAYER, cur->handle); + + return HWC_FRAMEBUFFER; + } + + private_handle_t *prev_handle = (private_handle_t *)(cur->handle); + int compositionType = HWC_FRAMEBUFFER; + + if (iter == 0) { + /* check here....if we have any resolution constraints */ + if (((cur->sourceCrop.right - cur->sourceCrop.left + 1) < 16) || + ((cur->sourceCrop.bottom - cur->sourceCrop.top + 1) < 8)) + return compositionType; + + if ((cur->transform == HAL_TRANSFORM_ROT_90) || + (cur->transform == HAL_TRANSFORM_ROT_270)) { + if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 4) || + ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 8)) + return compositionType; + } else if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 8) || + ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 4)) { + return compositionType; + } + + switch (prev_handle->format) { + case HAL_PIXEL_FORMAT_YV12: /* YCrCb_420_P */ + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL: + if ((prev_handle->usage & GRALLOC_USAGE_HWC_HWOVERLAY) && + (cur->blending == HWC_BLENDING_NONE)) + compositionType = HWC_OVERLAY; + else + compositionType = HWC_FRAMEBUFFER; + break; + default: + compositionType = HWC_FRAMEBUFFER; + break; + } + } + +#ifdef SUB_TITLES_HWC + else if ((win_cnt > 0) && + (prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP)) { + switch (prev_handle->format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + compositionType = HWC_OVERLAY; + break; + default: + compositionType = HWC_FRAMEBUFFER; + break; + } + + SEC_HWC_Log(HWC_LOG_DEBUG, "2nd iter###%s:: compositionType %d bpp %d" + " format %x src[%d %d %d %d] dst[%d %d %d %d] srcImg[%d %d]", + __func__, compositionType, prev_handle->bpp, + prev_handle->format, + cur->sourceCrop.left, cur->sourceCrop.right, + cur->sourceCrop.top, cur->sourceCrop.bottom, + cur->displayFrame.left, cur->displayFrame.right, + cur->displayFrame.top, cur->displayFrame.bottom, + prev_handle->width, prev_handle->height); + } +#endif + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s::compositionType(%d)=>0:FB,1:OVERLAY \r\n" + " format(0x%x),magic(0x%x),flags(%d),size(%d),offset(%d)" + "b_addr(0x%x),usage(%d),w(%d),h(%d),bpp(%d)", + "get_hwc_compos_decision()", compositionType, + prev_handle->format, prev_handle->magic, prev_handle->flags, + prev_handle->size, prev_handle->offset, prev_handle->base, + prev_handle->usage, prev_handle->width, prev_handle->height, + prev_handle->bpp); + + return compositionType; +} + +static void reset_win_rect_info(hwc_win_info_t *win) +{ + win->rect_info.x = 0; + win->rect_info.y = 0; + win->rect_info.w = 0; + win->rect_info.h = 0; + return; +} + + +static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_t *cur, + int win_idx, int layer_idx) +{ + struct hwc_win_info_t *win; + sec_rect rect; + int ret = 0; + + if (NUM_OF_WIN <= win_idx) + return -1; + + win = &ctx->win[win_idx]; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: left(%d),top(%d),right(%d),bottom(%d),transform(%d)" + "lcd_info.xres(%d),lcd_info.yres(%d)", + "++assign_overlay_window()", + cur->displayFrame.left, cur->displayFrame.top, + cur->displayFrame.right, cur->displayFrame.bottom, cur->transform, + win->lcd_info.xres, win->lcd_info.yres); + + calculate_rect(win, cur, &rect); + + if ((rect.x != win->rect_info.x) || (rect.y != win->rect_info.y) || + (rect.w != win->rect_info.w) || (rect.h != win->rect_info.h)){ + win->rect_info.x = rect.x; + win->rect_info.y = rect.y; + win->rect_info.w = rect.w; + win->rect_info.h = rect.h; + //turnoff the window and set the window position with new conf... + if (window_set_pos(win) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s", + __func__, strerror(errno)); + ret = -1; + } + ctx->layer_prev_buf[win_idx] = 0; + } + + win->layer_index = layer_idx; + win->status = HWC_WIN_RESERVED; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: win_x %d win_y %d win_w %d win_h %d lay_idx %d win_idx %d\n", + "--assign_overlay_window()", + win->rect_info.x, win->rect_info.y, win->rect_info.w, + win->rect_info.h, win->layer_index, win_idx ); + + return 0; +} + +static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) +{ + struct hwc_context_t* ctx = (struct hwc_context_t*)dev; + int overlay_win_cnt = 0; + int compositionType = 0; + int ret; + + //if geometry is not changed, there is no need to do any work here + if (!list || (!(list->flags & HWC_GEOMETRY_CHANGED))) + return 0; + + //all the windows are free here.... + for (int i = 0 ; i < NUM_OF_WIN; i++) { + ctx->win[i].status = HWC_WIN_FREE; + ctx->win[i].buf_index = 0; + } + + ctx->num_of_hwc_layer = 0; + ctx->num_of_fb_layer = 0; + ctx->num_2d_blit_layer = 0; + + for (int i = 0; i < list->numHwLayers ; i++) { + hwc_layer_t* cur = &list->hwLayers[i]; + + if (overlay_win_cnt < NUM_OF_WIN) { + compositionType = get_hwc_compos_decision(cur, 0, overlay_win_cnt); + + if (compositionType == HWC_FRAMEBUFFER) { + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + } else { + ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i); + if (ret != 0) { + LOGE("assign_overlay_window fail, change to frambuffer"); + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + continue; + } + + cur->compositionType = HWC_OVERLAY; + cur->hints = HWC_HINT_CLEAR_FB; + overlay_win_cnt++; + ctx->num_of_hwc_layer++; + } + } else { + cur->compositionType = HWC_FRAMEBUFFER; + ctx->num_of_fb_layer++; + } + } + +#ifdef SUB_TITLES_HWC + for (int i = 0; i < list->numHwLayers ; i++) { + if (overlay_win_cnt < NUM_OF_WIN) { + hwc_layer_t* cur = &list->hwLayers[i]; + if (get_hwc_compos_decision(cur, 1, overlay_win_cnt) == HWC_OVERLAY) { + ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i); + if (ret == 0) { + cur->compositionType = HWC_OVERLAY; + cur->hints = HWC_HINT_CLEAR_FB; + overlay_win_cnt++; + ctx->num_of_hwc_layer++; + ctx->num_of_fb_layer--; + ctx->num_2d_blit_layer = 1; + } + } + } + else + break; + } +#endif + +#if defined(BOARD_USES_HDMI) + android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance(); + mHdmiClient->setHdmiHwcLayer(ctx->num_of_hwc_layer); +#endif + + if (list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer)) + SEC_HWC_Log(HWC_LOG_DEBUG, + "%s:: numHwLayers %d num_of_fb_layer %d num_of_hwc_layer %d ", + __func__, list->numHwLayers, ctx->num_of_fb_layer, + ctx->num_of_hwc_layer); + + if (overlay_win_cnt < NUM_OF_WIN) { + //turn off the free windows + for (int i = overlay_win_cnt; i < NUM_OF_WIN; i++) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + } + } + + return 0; +} + +static int hwc_set(hwc_composer_device_t *dev, + hwc_display_t dpy, + hwc_surface_t sur, + hwc_layer_list_t* list) +{ + struct hwc_context_t *ctx = (struct hwc_context_t *)dev; + int skipped_window_mask = 0; + hwc_layer_t* cur; + struct hwc_win_info_t *win; + int ret; + int pmem_phyaddr; + struct sec_img src_img; + struct sec_img dst_img; + struct sec_rect src_work_rect; + struct sec_rect dst_work_rect; +#if defined(BOARD_USES_HDMI) + int skip_hdmi_rendering = 0; + int rotVal = 0; +#endif + if (!list) { + //turn off the all windows + for (int i = 0; i < NUM_OF_WIN; i++) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + ctx->win[i].status = HWC_WIN_FREE; + } + ctx->num_of_hwc_layer = 0; + } + + if(ctx->num_of_hwc_layer > NUM_OF_WIN) + ctx->num_of_hwc_layer = NUM_OF_WIN; + + //compose hardware layers here + for (int i = 0; i < ctx->num_of_hwc_layer - ctx->num_2d_blit_layer; i++) { + win = &ctx->win[i]; + if (win->status == HWC_WIN_RESERVED) { + cur = &list->hwLayers[win->layer_index]; + + if (cur->compositionType == HWC_OVERLAY) { + if (ctx->layer_prev_buf[i] == (uint32_t)cur->handle) { + /* + * In android platform, all the graphic buffer are at least + * double buffered (2 or more) this buffer is already rendered. + * It is the redundant src buffer for FIMC rendering. + */ + LOGD("SKIP FIMC rendering for Layer%d", win->layer_index); +#if defined(BOARD_USES_HDMI) + skip_hdmi_rendering = 1; +#endif + continue; + } + ctx->layer_prev_buf[i] = (uint32_t)cur->handle; + // initialize the src & dist context for fimc + set_src_dst_img_rect(cur, win, &src_img, &dst_img, + &src_work_rect, &dst_work_rect, i); + + ret = runFimc(ctx, + &src_img, &src_work_rect, + &dst_img, &dst_work_rect, + cur->transform); + + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::runFimc fail : ret=%d\n", + __func__, ret); + skipped_window_mask |= (1 << i); + continue; + } + + window_pan_display(win); + + win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF; + if (win->power_state == 0) + window_show(win); + } else { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s:: error : layer %d compositionType should have been" + " HWC_OVERLAY ", __func__, win->layer_index); + skipped_window_mask |= (1 << i); + continue; + } + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s:: error : window status should have " + "been HWC_WIN_RESERVED by now... ", __func__); + skipped_window_mask |= (1 << i); + continue; + } + } + +#ifdef SUB_TITLES_HWC + if (ctx->num_2d_blit_layer) { + g2d_rect srcRect; + g2d_rect dstRect; + + win = &ctx->win[ctx->num_of_hwc_layer - 1]; + cur = &list->hwLayers[win->layer_index]; + set_src_dst_g2d_rect(cur, win, &srcRect, &dstRect); + ret = runG2d(ctx, &srcRect, &dstRect, + cur->transform); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::runG2d fail : ret=%d\n", + __func__, ret); + skipped_window_mask |= (1 << (ctx->num_of_hwc_layer - 1)); + goto g2d_error; + } + + window_pan_display(win); + + win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF; + if (win->power_state == 0) + window_show(win); + } + +g2d_error: +#endif + + if (skipped_window_mask) { + //turn off the free windows + for (int i = 0; i < NUM_OF_WIN; i++) { + if (skipped_window_mask & (1 << i)) { + window_hide(&ctx->win[i]); + reset_win_rect_info(&ctx->win[i]); + } + } + } + + if (0 < ctx->num_of_fb_layer) { +#ifdef CHECK_EGL_FPS + check_fps(); +#endif +#ifdef HWC_HWOVERLAY + glFinish(); +#endif + EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur); + if (!sucess) + return HWC_EGL_ERROR; + } + +#if defined(BOARD_USES_HDMI) + if (list == NULL || skip_hdmi_rendering == 1) + return 0; + + android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance(); + +#ifdef SUPPORT_AUTO_UI_ROTATE + cur = &list->hwLayers[0]; + + if (cur->transform == HAL_TRANSFORM_ROT_90 || cur->transform == HAL_TRANSFORM_ROT_270) + mHdmiClient->setHdmiRotate(270, ctx->num_of_hwc_layer); + else + mHdmiClient->setHdmiRotate(0, ctx->num_of_hwc_layer); +#endif + + if (src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_LR) + src_img.format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR; + else if (src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_RL) + src_img.format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL; + else if (src_img.usage & GRALLOC_USAGE_PRIVATE_TB_LR) + src_img.format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR; + else if (src_img.usage & GRALLOC_USAGE_PRIVATE_TB_RL) + src_img.format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL; + + // To support S3D video playback (automatic TV mode change to 3D mode) + if (ctx->num_of_hwc_layer == 1) { + if (src_img.format != prev_format) { + if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL)) + mHdmiClient->setHdmiResolution(7209601); // V4L2_STD_TVOUT_720P_60_SBS_HALF + else if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL)) + mHdmiClient->setHdmiResolution(1080924); // V4L2_STD_TVOUT_1080P_24_TB + else + mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60 + } + prev_format = src_img.format; + } else { + if ((prev_format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR) || + (prev_format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL) || + (prev_format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR) || + (prev_format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL)) + mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60 + prev_format = HAL_PIXEL_FORMAT_BGRA_8888; + } + + if (ctx->num_of_hwc_layer == 1) { + if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)|| + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP) || + (src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_SP) || + (src_img.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) || + (src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_P) || + (src_img.format == HAL_PIXEL_FORMAT_YV12) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR) || + (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL)) { + mHdmiClient->blit2Hdmi(src_img.w, src_img.h, + src_img.format, + src_img.base, + src_img.base + src_img.uoffset, + src_img.base + src_img.uoffset + src_img.voffset, + 0, 0, + android::SecHdmiClient::HDMI_MODE_VIDEO, + ctx->num_of_hwc_layer); + } else { + LOGE("%s: Unsupported format = %d", __func__, src_img.format); + } + } +#endif + return 0; +} + +static int hwc_device_close(struct hw_device_t *dev) +{ + struct hwc_context_t* ctx = (struct hwc_context_t*)dev; + int ret = 0; + int i; + if (ctx) { + if (destroyVideoDev(&ctx->fimc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyVideoDev fail", __func__); + ret = -1; + } +#ifdef SUB_TITLES_HWC + if (destroyG2d(&ctx->g2d) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__); + ret = -1; + } +#endif + for (i = 0; i < NUM_OF_WIN; i++) { + if (window_close(&ctx->win[i]) < 0) + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__); + } + + free(ctx); + } + return ret; +} + +static int hwc_device_open(const struct hw_module_t* module, const char* name, + struct hw_device_t** device) +{ + int status = 0; + struct hwc_win_info_t *win; + + if (strcmp(name, HWC_HARDWARE_COMPOSER)) + return -EINVAL; + + struct hwc_context_t *dev; + dev = (hwc_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = hwc_device_close; + + dev->device.prepare = hwc_prepare; + dev->device.set = hwc_set; + + *device = &dev->device.common; + + //initializing + memset(&(dev->fimc), 0, sizeof(s5p_fimc_t)); + memset(&(dev->s3c_mem), 0, sizeof(struct s3c_mem_t)); +#ifdef USE_HW_PMEM + memset(&(dev->sec_pmem), 0, sizeof(sec_pmem_t)); +#endif + /* open WIN0 & WIN1 here */ + for (int i = 0; i < NUM_OF_WIN; i++) { + if (window_open(&(dev->win[i]), i) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s:: Failed to open window %d device ", __func__, i); + status = -EINVAL; + goto err; + } + } + + if (window_get_global_lcd_info(dev->win[0].fd, &dev->lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::window_get_global_lcd_info is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + +#if defined(BOARD_USES_HDMI) + lcd_width = dev->lcd_info.xres; + lcd_height = dev->lcd_info.yres; +#endif + + /* initialize the window context */ + for (int i = 0; i < NUM_OF_WIN; i++) { + win = &dev->win[i]; + memcpy(&win->lcd_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo)); + memcpy(&win->var_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo)); + + win->rect_info.x = 0; + win->rect_info.y = 0; + win->rect_info.w = win->var_info.xres; + win->rect_info.h = win->var_info.yres; + + if (window_set_pos(win) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + + if (window_get_info(win, i) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_get_info is failed : %s", + __func__, strerror(errno)); + status = -EINVAL; + goto err; + } + + } + +#ifdef USE_HW_PMEM + if (createPmem(&dev->sec_pmem, PMEM_SIZE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::initPmem(%d) fail", __func__, PMEM_SIZE); + } +#endif + + //create PP + if (createVideoDev(&dev->fimc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::creatFimc() fail", __func__); + status = -EINVAL; + goto err; + } + +#ifdef SUB_TITLES_HWC + if (createG2d(&dev->g2d) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::createG2d() fail", __func__); + status = -EINVAL; + goto err; + } +#endif + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: hwc_device_open: SUCCESS", __func__); + return 0; + +err: + if (destroyVideoDev(&dev->fimc) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyVideoDev() fail", __func__); +#ifdef SUB_TITLES_HWC + if (destroyG2d(&dev->g2d) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__); +#endif + if (destroyMem(&dev->s3c_mem) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem() fail", __func__); + +#ifdef USE_HW_PMEM + if (destroyPmem(&dev->sec_pmem) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem() fail", __func__); +#endif + + for (int i = 0; i < NUM_OF_WIN; i++) { + if (window_close(&dev->win[i]) < 0) + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__); + } + + return status; +} diff --git a/exynos5/hal/libhwcomposer/SecHWCLog.cpp b/exynos5/hal/libhwcomposer/SecHWCLog.cpp new file mode 100644 index 0000000..6ad4283 --- /dev/null +++ b/exynos5/hal/libhwcomposer/SecHWCLog.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#include + +#include "SecHWCUtils.h" + +void _SEC_HWC_Log(HWC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) +{ + va_list argptr; + + va_start(argptr, msg); + + switch (logLevel) { + case HWC_LOG_DEBUG: + __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); + break; + case HWC_LOG_WARNING: + __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); + break; + case HWC_LOG_ERROR: + __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr); + break; + default: + __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr); + } + + va_end(argptr); +} diff --git a/exynos5/hal/libhwcomposer/SecHWCUtils.cpp b/exynos5/hal/libhwcomposer/SecHWCUtils.cpp new file mode 100644 index 0000000..9a03ed2 --- /dev/null +++ b/exynos5/hal/libhwcomposer/SecHWCUtils.cpp @@ -0,0 +1,1703 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#include "SecHWCUtils.h" + +#define V4L2_BUF_TYPE_OUTPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE +#define V4L2_BUF_TYPE_CAPTURE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE +#define EXYNOS4_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) + +//#define CHECK_FPS +#ifdef CHECK_FPS +#include +#include +#define CHK_FRAME_CNT 30 + +void check_fps() +{ + static struct timeval tick, tick_old; + static int total = 0; + static int cnt = 0; + int FPS; + cnt++; + gettimeofday(&tick, NULL); + if (cnt > 10) { + if (tick.tv_sec > tick_old.tv_sec) + total += ((tick.tv_usec/1000) + (tick.tv_sec - tick_old.tv_sec)*1000 - (tick_old.tv_usec/1000)); + else + total += ((tick.tv_usec - tick_old.tv_usec)/1000); + + memcpy(&tick_old, &tick, sizeof(timeval)); + if (cnt == (10 + CHK_FRAME_CNT)) { + FPS = 1000*CHK_FRAME_CNT/total; + LOGE("[FPS]:%d\n", FPS); + total = 0; + cnt = 10; + } + } else { + memcpy(&tick_old, &tick, sizeof(timeval)); + total = 0; + } +} +#endif + +struct yuv_fmt_list yuv_list[] = { + { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 2 }, + { "V4L2_PIX_FMT_NV12T", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12T, 12, 2 }, + { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 2 }, + { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 }, + { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 }, + { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 }, + { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 }, + { "V4L2_PIX_FMT_YVU420M", "YVU420/3P", V4L2_PIX_FMT_YVU420M, 12, 3 }, + { "V4L2_PIX_FMT_NV12M", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12M, 12, 2 }, + { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 }, + { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 }, + { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 }, + { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 }, + { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 }, + { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 }, + { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 }, + { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 }, + { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 }, +}; + +int window_open(struct hwc_win_info_t *win, int id) +{ + int fd = 0; + char name[64]; + int vsync = 1; + int real_id = id; + + char const * const device_template = "/dev/graphics/fb%u"; + // window & FB maping + // fb0 -> win-id : 2 + // fb1 -> win-id : 1 + // fb2 -> win-id : 0 + // fb3 -> no device node + // fb4 -> no device node + // it is pre assumed that ...win0 or win1 is used here.. + + switch (id) { + case 0: + real_id = 2; + break; + case 1: + real_id = 1; + break; + default: + SEC_HWC_Log(HWC_LOG_ERROR, "%s::id(%d) is weird", __func__, id); + goto error; +} + + snprintf(name, 64, device_template, real_id); + + win->fd = open(name, O_RDWR); + if (win->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Failed to open window device (%s) : %s", + __func__, strerror(errno), name); + goto error; + } + +#ifdef ENABLE_FIMD_VSYNC + vsync = 1; + if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__); + goto error; + } +#endif + + return 0; + +error: + if (0 < win->fd) + close(win->fd); + win->fd = 0; + + return -1; +} + +int window_close(struct hwc_win_info_t *win) +{ + int ret = 0; + + if (0 < win->fd) { + ion_unmap((void *)win->addr[0], ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE)); + ion_free(win->ion_fd); + +#ifdef ENABLE_FIMD_VSYNC + /* Set using VSYNC Interrupt for FIMD_0 */ + int vsync = 0; + if (ioctl(win->fd, S3CFB_SET_VSYNC_INT, &vsync) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_SET_VSYNC_INT fail", __func__); +#endif + ret = close(win->fd); + } + win->fd = 0; + + return ret; +} + +int window_set_pos(struct hwc_win_info_t *win) +{ + struct s3cfb_user_window window; + + //before changing the screen configuration...powerdown the window + if (window_hide(win) != 0) + return -1; + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: x(%d), y(%d)", + __func__, win->rect_info.x, win->rect_info.y); + + win->var_info.xres_virtual = (win->lcd_info.xres + 15) & ~ 15; + win->var_info.yres_virtual = win->lcd_info.yres * NUM_OF_WIN_BUF; + win->var_info.xres = win->rect_info.w; + win->var_info.yres = win->rect_info.h; + win->var_info.activate &= ~FB_ACTIVATE_MASK; + win->var_info.activate |= FB_ACTIVATE_FORCE; + if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPUT_VSCREENINFO(%d, %d) fail", + __func__, win->rect_info.w, win->rect_info.h); + return -1; + } + + window.x = win->rect_info.x; + window.y = win->rect_info.y; + if (ioctl(win->fd, S3CFB_WIN_POSITION, &window) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3CFB_WIN_POSITION(%d, %d) fail", + __func__, window.x, window.y); + return -1; + } + + return 0; +} + +int window_get_info(struct hwc_win_info_t *win, int win_num) +{ + int temp_size = 0; + + if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_FSCREENINFO failed : %s", + strerror(errno)); + goto error; + } + + win->size = win->fix_info.line_length * win->var_info.yres; + + struct s3c_fb_user_ion_client ion_handle; + void *ion_start_addr; + if (ioctl(win->fd, S3CFB_GET_ION_USER_HANDLE, &ion_handle) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Get fb ion client is failed\n"); + return -1; + } + + win->ion_fd = ion_handle.fd; + ion_start_addr = ion_map(win->ion_fd, ALIGN(win->size * NUM_OF_WIN_BUF, PAGE_SIZE), 0); + + for (int j = 0; j < NUM_OF_WIN_BUF; j++) { + temp_size = win->size * j; + win->addr[j] = (uint32_t)ion_start_addr + temp_size; + SEC_HWC_Log(HWC_LOG_DEBUG, "%s::win-%d add[%d] %x ", + __func__, win_num, j, win->addr[j]); + } + return 0; + +error: + win->fix_info.smem_start = 0; + + return -1; +} + +int window_pan_display(struct hwc_win_info_t *win) +{ + struct fb_var_screeninfo *lcd_info = &(win->lcd_info); + +#ifdef ENABLE_FIMD_VSYNC + int pan_num = 0; + if (ioctl(win->fd, FBIO_WAITFORVSYNC, &pan_num) < 0) + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIO_WAITFORVSYNC fail(%s)", + __func__, strerror(errno)); +#endif + + lcd_info->yoffset = lcd_info->yres * win->buf_index; + + if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)", + __func__, + lcd_info->yres, + win->buf_index, lcd_info->yres_virtual, + strerror(errno)); + return -1; + } + return 0; +} + +int window_show(struct hwc_win_info_t *win) +{ + if (win->power_state == 0) { + if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)", + __func__, win->fd, strerror(errno)); + return -1; + } + win->power_state = 1; + } + return 0; +} + +int window_hide(struct hwc_win_info_t *win) +{ + if (win->power_state == 1) { + if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FBIOBLANK failed : (%d:%s)", + __func__, win->fd, strerror(errno)); + return -1; + } + win->power_state = 0; + } + return 0; +} + +int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info) +{ + if (ioctl(fd, FBIOGET_VSCREENINFO, lcd_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "FBIOGET_VSCREENINFO failed : %s", + strerror(errno)); + return -1; + } + + SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: Default LCD x(%d),y(%d)", + __func__, lcd_info->xres, lcd_info->yres); + return 0; +} + +int fimc_v4l2_set_src(int fd, s5p_fimc_img_info *src) +{ + struct v4l2_format fmt; + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + struct v4l2_requestbuffers req; + + /* You MUST initialize structure for v4l2 */ + memset(&fmt, 0, sizeof(fmt)); + memset(&cropcap, 0, sizeof(cropcap)); + memset(&crop, 0, sizeof(crop)); + memset(&req, 0, sizeof(req)); + + /************** To set size & format for source image (DMA-INPUT) **************/ + fmt.fmt.pix_mp.num_planes = src->planes; + fmt.fmt.pix_mp.width = src->full_width; + fmt.fmt.pix_mp.height = src->full_height; + fmt.fmt.pix_mp.pixelformat = src->color_space; + fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; + fmt.type = V4L2_BUF_TYPE_OUTPUT; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_src-VIDIOC_S_FMT, type(%d), field(%d), plane(%d)" + "pixelformat(0x%X), width(%d), height(%d)", + fmt.type, fmt.fmt.pix.field, fmt.fmt.pix_mp.num_planes, + fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); + + if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::VIDIOC_S_FMT failed : errno=%d (%s)" + " : fd=%d\n", __func__, errno, strerror(errno), fd); + return -1; + } + + /************** crop input size **************/ + crop.type = V4L2_BUF_TYPE_OUTPUT; + crop.c.width = src->width; + crop.c.height = src->height; + crop.c.left = src->start_x; + crop.c.top = src->start_y; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_src-VIDIOC_S_CROP, type(%d), XY(%d,%d), WH(%d,%d)", + crop.type, crop.c.left, crop.c.top, crop.c.width, crop.c.height); + + if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP :" + "crop.c.left : (%d), crop.c.top : (%d), crop.c.width : (%d), crop.c.height : (%d)", + __func__, crop.c.left, crop.c.top, crop.c.width, crop.c.height); + return -1; + } + + /************** input buffer type **************/ + req.count = 1; + req.memory = V4L2_MEMORY_USERPTR; + req.type = V4L2_BUF_TYPE_OUTPUT; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_src-VIDIOC_REQBUFS, count(%d), type(%d), memory(%d)", + req.count, req.type, req.memory); + + if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS", __func__); + return -1; + } + + return 0; +} + +int fimc_v4l2_set_dst(int fd, s5p_fimc_img_info *dst, + int rotation, int hflip, int vflip, unsigned int addr) +{ + struct v4l2_format sFormat; + struct v4l2_control vc; + struct v4l2_framebuffer fbuf; + struct v4l2_crop crop; + struct v4l2_requestbuffers req; + int ret; + + /* You MUST initialize structure for v4l2 */ + memset(&sFormat, 0, sizeof(sFormat)); + memset(&vc, 0, sizeof(vc)); + memset(&fbuf, 0, sizeof(fbuf)); + memset(&crop, 0, sizeof(crop)); + memset(&req, 0, sizeof(req)); + + /************** set rotation configuration **************/ + vc.id = V4L2_CID_ROTATE; + vc.value = rotation; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-V4L2_CID_ROTATE, rot(%d)",vc.value); + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - rotation (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + + /************** set hflip configuration **************/ + vc.id = V4L2_CID_HFLIP; + vc.value = hflip; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-V4L2_CID_HFLIP, hflip(%d)",vc.value); + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - hflip (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + + /************** set vflip configuration **************/ + vc.id = V4L2_CID_VFLIP; + vc.value = vflip; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-V4L2_CID_VFLIP, vflip(%d)",vc.value); + + ret = ioctl(fd, VIDIOC_S_CTRL, &vc); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s::Error in video VIDIOC_S_CTRL - vflip (%d)" + "vc.id : (%d), vc.value : (%d)", __func__, ret, vc.id, vc.value); + return -1; + } + + /************** set destination **************/ + sFormat.type = V4L2_BUF_TYPE_CAPTURE; + sFormat.fmt.pix_mp.width = dst->full_width; + sFormat.fmt.pix_mp.height = dst->full_height; + sFormat.fmt.pix_mp.pixelformat = dst->color_space; + sFormat.fmt.pix_mp.num_planes = dst->planes; + sFormat.fmt.pix.field = V4L2_FIELD_ANY; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-VIDIOC_S_FMT, type(%d), field(%d), plane(%d)" + "pixelformat(0x%X), width(%d), height(%d)", + sFormat.type, sFormat.fmt.pix.field, sFormat.fmt.pix_mp.num_planes, + sFormat.fmt.pix_mp.pixelformat, sFormat.fmt.pix_mp.width, sFormat.fmt.pix_mp.height); + + ret = ioctl(fd, VIDIOC_S_FMT, &sFormat); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_FMT (%d)", __func__, ret); + return -1; + } + + /************** set destination window**************/ + crop.type = V4L2_BUF_TYPE_CAPTURE; + crop.c.left = dst->start_x; + crop.c.top = dst->start_y; + crop.c.width = dst->width; + crop.c.height = dst->height; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-VIDIOC_S_CROP, type(%d), XY(%d,%d), WH(%d,%d)", + crop.type, crop.c.left, crop.c.top, crop.c.width, crop.c.height); + + ret = ioctl(fd, VIDIOC_S_CROP, &crop); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_S_CROP (%d)", __func__, ret); + return -1; + } + + /************** input buffer type **************/ + req.count = 1; + req.type = V4L2_BUF_TYPE_CAPTURE; + req.memory = V4L2_MEMORY_USERPTR; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "fimc_v4l2_set_dst-VIDIOC_REQBUFS, count(%d), type(%d), memory(%d)", + req.count, req.type, req.memory); + + ret = ioctl (fd, VIDIOC_REQBUFS, &req); + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in VIDIOC_REQBUFS (%d)", __func__, ret); + return -1; + } + + return 0; +} + +int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type) +{ + SEC_HWC_Log(HWC_LOG_DEBUG,"fimc_v4l2_stream_on-VIDIOC_STREAMON, type(%d)",type); + + if (-1 == ioctl(fd, VIDIOC_STREAMON, &type)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMON\n"); + return -1; + } + + return 0; +} + +int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type, int index) +{ + struct v4l2_plane plane[3]; + struct v4l2_buffer buf; + int i; + int ret; + + buf.length = fimc_buf->planes; + buf.memory = V4L2_MEMORY_USERPTR; + buf.index = index; + buf.type = type; + + if (buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + for (i = 0; i < buf.length; i++) { + plane[i].m.userptr = fimc_buf->base[i]; + plane[i].length = fimc_buf->size[i]; + } + } + buf.m.planes = plane; + + SEC_HWC_Log(HWC_LOG_DEBUG,"fimc_v4l2_queue-VIDIOC_QBUF, type(%d)," + "length(%d), memory(%d), index(%d)", + buf.type, buf.length, buf.memory, buf.index); + + ret = ioctl(fd, VIDIOC_QBUF, &buf); + if (0 > ret) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_QBUF : (%d)", ret); + return -1; + } + + return 0; +} + +int fimc_v4l2_dequeue(int fd, struct fimc_buf *fimc_buf, enum v4l2_buf_type type) +{ + struct v4l2_buffer buf; + struct v4l2_plane plane[3]; + + buf.m.planes = plane; + buf.length = fimc_buf->planes; + buf.memory = V4L2_MEMORY_USERPTR; + buf.type = type; + + if (-1 == ioctl(fd, VIDIOC_DQBUF, &buf)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_DQBUF\n"); + return -1; + } + + return buf.index; +} + +int fimc_v4l2_stream_off(int fd, enum v4l2_buf_type type) +{ + SEC_HWC_Log(HWC_LOG_DEBUG,"fimc_v4l2_stream_off-VIDIOC_STREAMOFF, type(%d),",type); + + if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_STREAMOFF\n"); + return -1; + } + + return 0; +} + +int fimc_v4l2_clr_buf(int fd, enum v4l2_buf_type type) +{ + struct v4l2_requestbuffers req; + + req.count = 0; + req.memory = V4L2_MEMORY_USERPTR; + req.type = type; + + SEC_HWC_Log(HWC_LOG_DEBUG,"fimc_v4l2_clr_buf-VIDIOC_REQBUFS," + "count(%d), memory(%d), type(%d)", + req.count, req.memory, req.type); + + if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_REQBUFS"); + } + + return 0; +} + +int fimc_v4l2_S_ctrl(int fd) +{ + struct v4l2_control vc; + + vc.id = V4L2_CID_CACHEABLE; + vc.value = 1; + + SEC_HWC_Log(HWC_LOG_DEBUG,"fimc_v4l2_S_ctrl-VIDIOC_S_CTRL," + "id(%d), value(%d)",vc.id , vc.value); + + if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Error in VIDIOC_S_CTRL"); + return -1; + } + + return 0; +} + +int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_src_buf, struct fimc_buf *fimc_dst_buf) +{ +#ifdef CHECK_FPS + check_fps(); +#endif + + if (fimc_v4l2_queue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_queue()"); + return -1; + } + + if (fimc_v4l2_queue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE, 0) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_queue()"); + return -2; + } + + if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_on()"); + return -3; + } + + if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_on()"); + return -4; + } + + if (fimc_v4l2_dequeue(fd, fimc_src_buf, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_dequeue()"); + return -6; + } + + if (fimc_v4l2_dequeue(fd, fimc_dst_buf, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_dequeue()"); + return -7; + } + +STREAM_OFF: + if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_stream_off()"); + return -8; + } + + if (fimc_v4l2_stream_off(fd, V4L2_BUF_TYPE_CAPTURE) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_stream_off()"); + return -9; + } + + if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_OUTPUT) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : SRC v4l2_clr_buf()"); + return -10; + } + + if (fimc_v4l2_clr_buf(fd, V4L2_BUF_TYPE_CAPTURE)< 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "Fail : DST v4l2_clr_buf()"); + return -11; + } + + return 0; +} + +static int memcpy_rect(void *dst, void *src, int fullW, int fullH, int realW, int realH, int format) +{ + unsigned char *srcCb, *srcCr; + unsigned char *dstCb, *dstCr; + unsigned char *srcY, *dstY; + int srcCbOffset, srcCrOffset; + int dstCbOffset, dstFrameOffset, dstCrOffset; + int cbFullW, cbRealW, cbFullH, cbRealH; + int ySrcFW, ySrcFH, ySrcRW, ySrcRH; + int planes; + int i; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "++memcpy_rect()::" + "dst(0x%x),src(0x%x),f.w(%d),f.h(%d),r.w(%d),r.h(%d),format(0x%x)", + (unsigned int)dst, (unsigned int)src, fullW, fullH, realW, realH, format); + +// Set dst Y, Cb, Cr address for FIMC + { + cbFullW = fullW >> 1; + cbRealW = realW >> 1; + cbFullH = fullH >> 1; + cbRealH = realH >> 1; + dstFrameOffset = fullW * fullH; + dstCrOffset = cbFullW * cbFullH; + dstY = (unsigned char *)dst; + dstCb = (unsigned char *)dst + dstFrameOffset; + dstCr = (unsigned char *)dstCb + dstCrOffset; + } + +// Get src Y, Cb, Cr address for source buffer. +// Each address is aligned by 16's multiple for GPU both width and height. + { + ySrcFW = fullW; + ySrcFH = fullH; + ySrcRW = realW; + ySrcRH = realH; + srcCbOffset = EXYNOS4_ALIGN(ySrcRW,16)* EXYNOS4_ALIGN(ySrcRH,16); + srcCrOffset = EXYNOS4_ALIGN(cbRealW,16)* EXYNOS4_ALIGN(cbRealH,16); + srcY = (unsigned char *)src; + srcCb = (unsigned char *)src + srcCbOffset; + srcCr = (unsigned char *)srcCb + srcCrOffset; + } + SEC_HWC_Log(HWC_LOG_DEBUG, + "--memcpy_rect()::\n" + "dstY(0x%x),dstCb(0x%x),dstCr(0x%x) \n" + "srcY(0x%x),srcCb(0x%x),srcCr(0x%x) \n" + "cbRealW(%d),cbRealH(%d)", + (unsigned int)dstY,(unsigned int)dstCb,(unsigned int)dstCr, + (unsigned int)srcY,(unsigned int)srcCb,(unsigned int)srcCr, + cbRealW, cbRealH); + + if (format == HAL_PIXEL_FORMAT_YV12) { //YV12(Y,Cr,Cv) + planes = 3; +//This is code for VE, deleted temporory by SSONG 2011.09.22 +// This will be enabled later. +/* + //as defined in hardware.h, cb & cr full_width should be aligned to 16. ALIGN(y_stride/2, 16). + ////Alignment is hard coded to 16. + ////for example...check frameworks/media/libvideoeditor/lvpp/VideoEditorTools.cpp file for UV stride cal + cbSrcFW = (cbSrcFW + 15) & (~15); + srcCbOffset = ySrcFW * fullH; + srcCrOffset = srcCbOffset + ((cbSrcFW * fullH) >> 1); + srcY = (unsigned char *)src; + srcCb = (unsigned char *)src + srcCbOffset; + srcCr = (unsigned char *)src + srcCrOffset; +*/ + } else if ((format == HAL_PIXEL_FORMAT_YCbCr_420_P) || + (format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_LR) || + (format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_SBS_RL) || + (format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_LR) || + (format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_P_TB_RL)) { + planes = 3; + } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { + planes = 2; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "use default memcpy instead of memcpy_rect"); + return -1; + } +//#define CHECK_PERF +#ifdef CHECK_PERF + struct timeval start, end; + gettimeofday(&start, NULL); +#endif + for (i = 0; i < realH; i++) + memcpy(dstY + fullW * i, srcY + ySrcFW * i, ySrcRW); + if (planes == 2) { + for (i = 0; i < cbRealH; i++) + memcpy(dstCb + ySrcFW * i, srcCb + ySrcFW * i, ySrcRW); + } else if (planes == 3) { + for (i = 0; i < cbRealH; i++) + memcpy(dstCb + cbFullW * i, srcCb + cbFullW * i, cbRealW); + for (i = 0; i < cbRealH; i++) + memcpy(dstCr + cbFullW * i, srcCr + cbFullW * i, cbRealW); + } +#ifdef CHECK_PERF + gettimeofday(&end, NULL); + SEC_HWC_Log(HWC_LOG_ERROR, "[COPY]=%d,",(end.tv_sec - start.tv_sec)*1000+(end.tv_usec - start.tv_usec)/1000); +#endif + + return 0; +} + +/*****************************************************************************/ +static int get_src_phys_addr(struct hwc_context_t *ctx, + sec_img *src_img, sec_rect *src_rect) +{ + s5p_fimc_t *fimc = &ctx->fimc; + struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[0]; + struct s3c_mem_dma_param s3c_mem_dma; + + unsigned int src_virt_addr = 0; + unsigned int src_phys_addr = 0; + unsigned int src_frame_size = 0; + + // error check routine + if (0 == src_img->base) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s invalid src image base\n", __func__); + return 0; + } + + fimc->params.src.buf_addr_phy_rgb_y = src_img->base; + fimc->params.src.buf_addr_phy_cb = src_img->base + src_img->uoffset; + fimc->params.src.buf_addr_phy_cr = src_img->base + src_img->uoffset + src_img->voffset; + src_phys_addr = fimc->params.src.buf_addr_phy_rgb_y; + + return src_phys_addr; +} + +static int get_dst_phys_addr(struct hwc_context_t *ctx, sec_img *dst_img, + sec_rect *dst_rect, int *dst_memcpy_flag) +{ + unsigned int dst_phys_addr = 0; + + dst_phys_addr = dst_img->base; + + return dst_phys_addr; +} + +static inline int rotateValueHAL2PP(unsigned char transform) +{ + int rotate_flag = transform & 0x7; + + switch (rotate_flag) { + case HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_ROT_180: return 180; + case HAL_TRANSFORM_ROT_270: return 270; + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: return 90; + case HAL_TRANSFORM_FLIP_H: return 0; + case HAL_TRANSFORM_FLIP_V: return 0; + } + return 0; +} + +static inline int hflipValueHAL2PP(unsigned char transform) +{ + int flip_flag = transform & 0x7; + switch (flip_flag) { + case HAL_TRANSFORM_FLIP_H: + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: + return 1; + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_180: + case HAL_TRANSFORM_ROT_270: + case HAL_TRANSFORM_FLIP_V: + break; + } + return 0; +} + +static inline int vflipValueHAL2PP(unsigned char transform) +{ + int flip_flag = transform & 0x7; + switch (flip_flag) { + case HAL_TRANSFORM_FLIP_V: + case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: + return 1; + case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_90: + case HAL_TRANSFORM_ROT_180: + case HAL_TRANSFORM_ROT_270: + case HAL_TRANSFORM_FLIP_H: + break; + } + return 0; +} + +static inline int multipleOf2(int number) +{ + if (number % 2 == 1) + return (number - 1); + else + return number; +} + +static inline int multipleOf4(int number) +{ + int remain_number = number % 4; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int multipleOf8(int number) +{ + int remain_number = number % 8; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int multipleOf16(int number) +{ + int remain_number = number % 16; + + if (remain_number != 0) + return (number - remain_number); + else + return number; +} + +static inline int widthOfPP( int pp_color_format, int number) +{ + switch (pp_color_format) { + /* 422 1/2/3 plane */ + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_YUV422P: + + /* 420 2/3 plane */ + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + return multipleOf2(number); + + default : + return number; + } + +} + +static inline int heightOfPP(int pp_color_format, int number) +{ + switch (pp_color_format) { + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + return multipleOf2(number); + + default : + return number; + break; + } + return number; +} + +static unsigned int get_yuv_bpp(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].bpp; +} + +static unsigned int get_yuv_planes(unsigned int fmt) +{ + int i, sel = -1; + + for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) { + if (yuv_list[i].fmt == fmt) { + sel = i; + break; + } + } + + if (sel == -1) + return sel; + else + return yuv_list[sel].planes; +} + +static int runFimcCore(struct hwc_context_t *ctx, + unsigned int src_phys_addr, sec_img *src_img, sec_rect *src_rect, + uint32_t src_color_space, + unsigned int dst_phys_addr, sec_img *dst_img, sec_rect *dst_rect, + uint32_t dst_color_space, int transform) +{ + s5p_fimc_t * fimc = &ctx->fimc; + s5p_fimc_params_t * params = &(fimc->params); + + struct fimc_buf fimc_src_buf; + int src_bpp, src_planes; + + struct fimc_buf fimc_dst_buf; + int dst_bpp, dst_planes; + unsigned int src_frame_size = 0; + unsigned int dst_frame_size = 0; + unsigned int frame_size = 0; + + bool src_cbcr_order = true; + int rotate_value = rotateValueHAL2PP(transform); + int hflip = hflipValueHAL2PP(transform); + int vflip = vflipValueHAL2PP(transform); + + /* 1. param(fimc config)->src information + * - src_img,src_rect => s_fw,s_fh,s_w,s_h,s_x,s_y + */ + params->src.full_width = src_img->f_w; + params->src.full_height = src_img->f_h; + params->src.width = src_rect->w; + params->src.height = src_rect->h; + params->src.start_x = src_rect->x; + params->src.start_y = src_rect->y; + params->src.color_space = src_color_space; + params->src.buf_addr_phy_rgb_y = src_phys_addr; + + params->dst.buf_addr_phy_rgb_y = dst_phys_addr; + + /* check src minimum */ + if (src_rect->w < 64 || src_rect->h < 32) { + SEC_HWC_Log(HWC_LOG_ERROR, + "%s src size is not supported by fimc : f_w=%d f_h=%d " + "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__, + params->src.full_width, params->src.full_height, + params->src.start_x, params->src.start_y, + params->src.width, params->src.height, + src_rect->w, src_rect->h, + params->src.color_space); + return -1; + } + + params->dst.full_width = dst_img->f_w; + params->dst.full_height = dst_img->f_h; + params->dst.start_x = dst_rect->x; + params->dst.start_y = dst_rect->y; + params->dst.width = widthOfPP(dst_color_space, dst_rect->w); + params->dst.height = heightOfPP(dst_color_space, dst_rect->h); + params->dst.color_space = dst_color_space; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore()::" + "SRC f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)=>" + "DST f.w(%d),f.h(%d),x(%d),y(%d),w(%d),h(%d)", + params->src.full_width, params->src.full_height, + params->src.start_x, params->src.start_y, + params->src.width, params->src.height, + params->dst.full_width, params->dst.full_height, + params->dst.start_x, params->dst.start_y, + params->dst.width, params->dst.height); + + /* check dst minimum */ +#if (GSC_VERSION == GSC_EVT0) + if (dst_rect->w < 64 || dst_rect->h < 32) { +#else + if (dst_rect->w < 32 || dst_rect->h < 8) { +#endif + + SEC_HWC_Log(HWC_LOG_ERROR, + "%s dst size is not supported by fimc : f_w=%d f_h=%d " + "x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__, + params->dst.full_width, params->dst.full_height, + params->dst.start_x, params->dst.start_y, + params->dst.width, params->dst.height, + dst_rect->w, dst_rect->h, params->dst.color_space); + return -1; + } + + /* 2. Set configuration related to destination (DMA-OUT) + * - set input format & size + * - crop input size + * - set input buffer + * - set buffer type (V4L2_MEMORY_USERPTR) + */ + switch (dst_img->format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_BGRA_8888: + dst_planes = 1; + dst_bpp = 32; + break; + + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + dst_planes = 1; + dst_bpp = 16; + break; + } + + dst_frame_size = params->dst.width * params->dst.height ; + params->dst.planes = dst_planes; + + if (dst_planes == 1) { + fimc_dst_buf.base[0] = params->dst.buf_addr_phy_rgb_y; + if (dst_bpp == 32) + fimc_dst_buf.size[0] = dst_frame_size * 4; + else if (dst_bpp == 16) + fimc_dst_buf.size[0] = dst_frame_size * 2; + } + + if (fimc_v4l2_set_dst(fimc->dev_fd, ¶ms->dst, rotate_value, hflip, vflip, dst_phys_addr) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_dst is failed\n"); + return -1; + } + + /* 3. Set input dma address (Y/RGB, Cb, Cr) + * set source frame size + */ + src_frame_size = params->src.full_width * params->src.full_height; + fimc_src_buf.size[0] = src_frame_size; + fimc_src_buf.size[1] = src_frame_size >> 2; + fimc_src_buf.size[2] = src_frame_size >> 2; + + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore - Y_length=%d, U_length=%d, V_length=%d\n", + fimc_src_buf.size[0], fimc_src_buf.size[1],fimc_src_buf.size[2]); + + /* set source Y image */ + fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y; + /* set source Cb,Cr images for 2 or 3 planes */ + src_bpp = get_yuv_bpp(src_color_space); + src_planes = get_yuv_planes(src_color_space); + if (2 == src_planes) { /* 2 planes */ + frame_size = params->src.full_width * params->src.full_height; + params->src.buf_addr_phy_cb = + params->src.buf_addr_phy_rgb_y + frame_size; + /* CbCr */ + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + } else if (3 == src_planes) { /* 3 planes */ + frame_size = params->src.full_width * params->src.full_height; + params->src.buf_addr_phy_cb = + params->src.buf_addr_phy_rgb_y + frame_size; + if (12 == src_bpp) + params->src.buf_addr_phy_cr = + params->src.buf_addr_phy_cb + (frame_size >> 2); + else + params->src.buf_addr_phy_cr = + params->src.buf_addr_phy_cb + (frame_size >> 1); + /* Cb, Cr */ + if (src_cbcr_order == true) { + fimc_src_buf.base[1] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[2] = params->src.buf_addr_phy_cr; + } + else { + fimc_src_buf.base[2] = params->src.buf_addr_phy_cb; + fimc_src_buf.base[1] = params->src.buf_addr_phy_cr; + } + } + + SEC_HWC_Log(HWC_LOG_DEBUG, + "runFimcCore - Y=0x%X, U=0x%X, V=0x%X\n", + fimc_src_buf.base[0], fimc_src_buf.base[1],fimc_src_buf.base[2]); + + int ret = 0; + params->src.planes = src_planes; + + /* 4. Set configuration related to source (DMA-INPUT) + * - set input format & size + * - crop input size + * - set input buffer + * - set buffer type (V4L2_MEMORY_USERPTR) + */ + if (fimc_v4l2_set_src(fimc->dev_fd, ¶ms->src) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "fimc_v4l2_set_src is failed\n"); + return -1; + } + + fimc_src_buf.planes = src_planes; + fimc_dst_buf.planes = dst_planes; + + /* 5. Run FIMC + * - stream on => queue => dequeue => stream off => clear buf + */ + ret = fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf, &fimc_dst_buf); + + if (ret < 0) { + SEC_HWC_Log(HWC_LOG_ERROR,"fimc_handle_oneshot = %d\n",ret); + if (ret == -2) { + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT); + } else if (ret == -3) { + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_OUTPUT); + fimc_v4l2_clr_buf(fimc->dev_fd, V4L2_BUF_TYPE_CAPTURE); + } + return ret; + } + + return 0; +} + +#ifdef SUB_TITLES_HWC +int createG2d(sec_g2d_t *g2d) +{ + g2d->dev_fd = open(SEC_G2D_DEV_NAME, O_RDWR); + + if (g2d->dev_fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::G2d open error (%d)", __func__, errno); + goto err; + } + + return 0; +err: + if (0 < g2d->dev_fd) + close(g2d->dev_fd); + g2d->dev_fd =0; + + return -1; +} + +int destroyG2d(sec_g2d_t *g2d) +{ + // close + if (0 < g2d->dev_fd) + close(g2d->dev_fd); + g2d->dev_fd = 0; + + return 0; +} +#endif + +int createVideoDev(s5p_fimc_t *fimc) +{ + struct v4l2_capability cap; + struct v4l2_format fmt; + struct v4l2_control vc; + + // open device file + if (fimc->dev_fd <= 0) + fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR); + + if (fimc->dev_fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Post processor open error (%d)", + __func__, errno); + goto err; + } + + /* Initial debug log level for video driver. + User can use command below to change log level. + # echo 7 > /sys/module/gsc/parameters/gsc_dbg + # echo 8 > /proc/sys/kernel/printk + Each number for gsc_dgb means, + 3: error + 4: waring + 6: info + 7: debug + */ + system("echo 3 > /sys/module/gsc/parameters/gsc_dbg"); + + // check capability + if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "VIDIOC_QUERYCAP failed"); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + SEC_HWC_Log(HWC_LOG_ERROR, "%d has no streaming support", fimc->dev_fd); + goto err; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { + SEC_HWC_Log(HWC_LOG_ERROR, "%d is no video output", fimc->dev_fd); + goto err; + } + + /* + * malloc fimc_outinfo structure + */ + fmt.type = V4L2_BUF_TYPE_OUTPUT; + if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::Error in video VIDIOC_G_FMT", __func__); + goto err; + } + + return 0; + +err: + if (0 < fimc->dev_fd) + close(fimc->dev_fd); + fimc->dev_fd =0; + + return -1; +} + +int destroyVideoDev(s5p_fimc_t *fimc) +{ + if (fimc->out_buf.virt_addr != NULL) { + fimc->out_buf.virt_addr = NULL; + fimc->out_buf.length = 0; + } + + // close + if (0 < fimc->dev_fd) + close(fimc->dev_fd); + fimc->dev_fd = 0; + + return 0; +} + +int runFimc(struct hwc_context_t *ctx, + struct sec_img *src_img, struct sec_rect *src_rect, + struct sec_img *dst_img, struct sec_rect *dst_rect, + uint32_t transform) +{ + s5p_fimc_t * fimc = &ctx->fimc; + + unsigned int src_phys_addr = 0; + unsigned int dst_phys_addr = 0; + int rotate_value = 0; + int flag_force_memcpy = 0; + int32_t src_color_space; + int32_t dst_color_space; + + /* 1. source address and size */ + src_phys_addr = get_src_phys_addr(ctx, src_img, src_rect); + if (0 == src_phys_addr) + return -1; + + /* 2. destination address and size */ + dst_phys_addr = get_dst_phys_addr(ctx, dst_img, dst_rect, &flag_force_memcpy); + if (0 == dst_phys_addr) + return -2; + + /* 3. check whether fimc supports the src format */ + src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); + if (0 > src_color_space) + return -3; + dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); + if (0 > dst_color_space) + return -4; + + /* 4. FIMC: src_rect of src_img => dst_rect of dst_img */ + if (runFimcCore(ctx, src_phys_addr, src_img, src_rect, + (uint32_t)src_color_space, dst_phys_addr, dst_img, dst_rect, + (uint32_t)dst_color_space, transform) < 0) + return -5; + + return 0; +} + +#ifdef SUB_TITLES_HWC +static int get_g2d_src_phys_addr(struct hwc_context_t *ctx, g2d_rect *src_rect) +{ + sec_g2d_t *g2d = &ctx->g2d; + struct s3c_mem_alloc *ptr_mem_alloc = &ctx->s3c_mem.mem_alloc[0]; +#ifdef USE_HW_PMEM + sec_pmem_alloc_t *pm_alloc = &ctx->sec_pmem.sec_pmem_alloc[0]; +#endif + + unsigned int src_virt_addr = 0; + unsigned int src_phys_addr = 0; + unsigned int src_frame_size = 0; + + struct pmem_region region; + + // error check routine + if (0 == src_rect->virt_addr) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s invalid src address\n", __func__); + return 0; + } + + src_frame_size = FRAME_SIZE(src_rect->color_format, + src_rect->full_w, src_rect->full_h); + if (src_frame_size == 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::FRAME_SIZE fail", __func__); + return 0; + } + +#ifdef USE_HW_PMEM + if (0 <= checkPmem(&ctx->sec_pmem, 0, src_frame_size)) { + src_virt_addr = pm_alloc->virt_addr; + src_phys_addr = pm_alloc->phys_addr; + pm_alloc->size = src_frame_size; + } else +#endif + if (0 <= checkMem(&ctx->s3c_mem, 0, src_frame_size)) { + src_virt_addr = ptr_mem_alloc->vir_addr; + src_phys_addr = ptr_mem_alloc->phy_addr; + ptr_mem_alloc->size = src_frame_size; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::check_mem fail", __func__); + return 0; + } + memcpy((void *)src_virt_addr, (void*)((unsigned int)src_rect->virt_addr), src_frame_size); + + return src_phys_addr; +} + +int get_HAL_2_G2D_FORMAT(int format) +{ + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: return G2D_ABGR_8888; + case HAL_PIXEL_FORMAT_RGBX_8888: return G2D_XBGR_8888; + case HAL_PIXEL_FORMAT_BGRA_8888: return G2D_ARGB_8888; + case HAL_PIXEL_FORMAT_RGB_888: return G2D_PACKED_BGR_888; + case HAL_PIXEL_FORMAT_RGB_565: return G2D_RGB_565; + case HAL_PIXEL_FORMAT_RGBA_5551: return G2D_RGBA_5551; + case HAL_PIXEL_FORMAT_RGBA_4444: return G2D_RGBA_4444; + default: + return -1; + } +} + +static inline int rotateValueHAL2G2D(unsigned char transform) +{ + int rotate_flag = transform & 0x7; + + switch (rotate_flag) { + case HAL_TRANSFORM_ROT_90: return G2D_ROT_90; + case HAL_TRANSFORM_ROT_180: return G2D_ROT_180; + case HAL_TRANSFORM_ROT_270: return G2D_ROT_270; + default: + return G2D_ROT_0; + } +} + +int runG2d(struct hwc_context_t *ctx, g2d_rect *src_rect, g2d_rect *dst_rect, + uint32_t transform) +{ + sec_g2d_t * g2d = &ctx->g2d; + g2d_flag flag = {G2D_ROT_0, G2D_ALPHA_BLENDING_OPAQUE, 0, 0, 0, 0, 0, 0}; + int rotate_value = 0; + + // 1 : source address and size + src_rect->phys_addr = get_g2d_src_phys_addr(ctx, src_rect); + if (0 == src_rect->phys_addr) + return -1; + + // 2 : destination address and size + if (0 == dst_rect->phys_addr) + return -2; + + // check whether g2d supports the src format + src_rect->color_format = get_HAL_2_G2D_FORMAT(src_rect->color_format); + if (0 > src_rect->color_format) + return -3; + + dst_rect->color_format = get_HAL_2_G2D_FORMAT(dst_rect->color_format); + if (0 > dst_rect->color_format) + return -4; + + flag.rotate_val = rotateValueHAL2G2D(transform); + + // scale and rotate and alpha with FIMG + if(stretchSecFimg(src_rect, dst_rect, &flag) < 0) + return -5; + + return 0; +} +#endif + +int createMem(struct s3c_mem_t *mem, unsigned int index, unsigned int size) +{ + struct s3c_mem_alloc *ptr_mem_alloc; + struct s3c_mem_alloc mem_alloc_info; + + if (index >= NUM_OF_MEM_OBJ) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalid index (%d >= %d)", + __func__, index, NUM_OF_MEM_OBJ); + goto err; + } + + ptr_mem_alloc = &mem->mem_alloc[index]; + + if (mem->fd <= 0) { + mem->fd = open(S3C_MEM_DEV_NAME, O_RDWR); + if (mem->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::open(%s) fail(%s)", + __func__, S3C_MEM_DEV_NAME, strerror(errno)); + goto err; + } + } + + // kcoolsw : what the hell of this line?? + if (0 == size) + return 0; + + mem_alloc_info.size = size; + + if (ioctl(mem->fd, S3C_MEM_CACHEABLE_ALLOC, &mem_alloc_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_ALLOC(size : %d) fail", + __func__, mem_alloc_info.size); + goto err; + } + + ptr_mem_alloc->phy_addr = mem_alloc_info.phy_addr; + ptr_mem_alloc->vir_addr = mem_alloc_info.vir_addr; + ptr_mem_alloc->size = mem_alloc_info.size; + + return 0; + +err: + if (0 < mem->fd) + close(mem->fd); + mem->fd = 0; + + return 0; +} + +int destroyMem(struct s3c_mem_t *mem) +{ + int i; + struct s3c_mem_alloc *ptr_mem_alloc; + + if (mem->fd <= 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalied fd(%d) fail", __func__, mem->fd); + return -1; + } + + for (i = 0; i < NUM_OF_MEM_OBJ; i++) { + ptr_mem_alloc = &mem->mem_alloc[i]; + + if (0 != ptr_mem_alloc->vir_addr) { + if (ioctl(mem->fd, S3C_MEM_FREE, ptr_mem_alloc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_FREE fail", __func__); + return -1; + } + + ptr_mem_alloc->phy_addr = 0; + ptr_mem_alloc->vir_addr = 0; + ptr_mem_alloc->size = 0; + } + } + + close(mem->fd); + mem->fd = 0; + + return 0; +} + +int checkMem(struct s3c_mem_t *mem, unsigned int index, unsigned int size) +{ + int ret; + struct s3c_mem_alloc *ptr_mem_alloc; + struct s3c_mem_alloc mem_alloc_info; + + if (index >= NUM_OF_MEM_OBJ) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::invalid index (%d >= %d)", __func__, + index, NUM_OF_MEM_OBJ); + return -1; + } + + if (mem->fd <= 0) { + ret = createMem(mem, index, size); + return ret; + } + + ptr_mem_alloc = &mem->mem_alloc[index]; + + if (ptr_mem_alloc->size < (int)size) { + if (0 < ptr_mem_alloc->size) { + // free allocated mem + if (ioctl(mem->fd, S3C_MEM_FREE, ptr_mem_alloc) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_FREE fail", __func__); + return -1; + } + } + + // allocate mem with requested size + mem_alloc_info.size = size; + if (ioctl(mem->fd, S3C_MEM_CACHEABLE_ALLOC, &mem_alloc_info) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::S3C_MEM_ALLOC(size : %d) fail", + __func__, mem_alloc_info.size); + return -1; + } + + ptr_mem_alloc->phy_addr = mem_alloc_info.phy_addr; + ptr_mem_alloc->vir_addr = mem_alloc_info.vir_addr; + ptr_mem_alloc->size = mem_alloc_info.size; + } + + return 0; +} + +#ifdef USE_HW_PMEM +int createPmem(sec_pmem_t *pm, unsigned int buf_size) +{ + int master_fd, err = 0, i; + void *base; + unsigned int phys_base; + size_t size, sub_size[NUM_OF_MEM_OBJ]; + struct pmem_region region; + + master_fd = open(PMEM_DEVICE_DEV_NAME, O_RDWR, 0); + if (master_fd < 0) { + pm->pmem_master_fd = -1; + if (EACCES == errno) { + return 0; + } else { + SEC_HWC_Log(HWC_LOG_ERROR, "%s::open(%s) fail(%s)", + __func__, PMEM_DEVICE_DEV_NAME, strerror(errno)); + return -errno; + } + } + + if (ioctl(master_fd, PMEM_GET_TOTAL_SIZE, ®ion) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "PMEM_GET_TOTAL_SIZE failed, default mode"); + size = 8<<20; // 8 MiB + } else { + size = region.len; + } + + base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0); + if (base == MAP_FAILED) { + SEC_HWC_Log(HWC_LOG_ERROR, "[%s] mmap failed : %d (%s)", __func__, + errno, strerror(errno)); + base = 0; + close(master_fd); + master_fd = -1; + return -errno; + } + + if (ioctl(master_fd, PMEM_GET_PHYS, ®ion) < 0) { + SEC_HWC_Log(HWC_LOG_ERROR, "PMEM_GET_PHYS failed, limp mode"); + region.offset = 0; + } + + pm->pmem_master_fd = master_fd; + pm->pmem_master_base = base; + pm->pmem_total_size = size; + //pm->pmem_master_phys_base = region.offset; + phys_base = region.offset; + + // sec_pmem_alloc[0] for temporary buffer for source + sub_size[0] = buf_size; + sub_size[0] = roundUpToPageSize(sub_size[0]); + + for (i = 0; i < NUM_OF_MEM_OBJ; i++) { + sec_pmem_alloc_t *pm_alloc = &(pm->sec_pmem_alloc[i]); + int fd, ret; + int offset = i ? sub_size[i-1] : 0; + struct pmem_region sub = { offset, sub_size[i] }; + + // create the "sub-heap" + if (0 > (fd = open(PMEM_DEVICE_DEV_NAME, O_RDWR, 0))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] open failed (%dL) : %d (%s)", + __func__, i, __LINE__, errno, strerror(errno)); + return -errno; + } + + // connect to it + if (0 != (ret = ioctl(fd, PMEM_CONNECT, pm->pmem_master_fd))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_CONNECT) failed : %d (%s)", + __func__, i, errno, strerror(errno)); + close(fd); + return -errno; + } + + // make it available to the client process + if (0 != (ret = ioctl(fd, PMEM_MAP, &sub))) { + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_MAP) failed : %d (%s)", + __func__, i, errno, strerror(errno)); + close(fd); + return -errno; + } + + pm_alloc->fd = fd; + pm_alloc->total_size = sub_size[i]; + pm_alloc->offset = offset; + pm_alloc->virt_addr = (unsigned int)base + (unsigned int)offset; + pm_alloc->phys_addr = (unsigned int)phys_base + (unsigned int)offset; + +#if defined (PMEM_DEBUG) + SEC_HWC_Log(HWC_LOG_DEBUG, "[%s] pm_alloc[%d] fd=%d total_size=%d " + "offset=0x%x virt_addr=0x%x phys_addr=0x%x", + __func__, i, pm_alloc->fd, pm_alloc->total_size, + pm_alloc->offset, pm_alloc->virt_addr, pm_alloc->phys_addr); +#endif + } + + return err; +} + +int destroyPmem(sec_pmem_t *pm) +{ + int i, err; + + for (i=0; isec_pmem_alloc[i]); + + if (0 <= pm_alloc->fd) { + struct pmem_region sub = { pm_alloc->offset, pm_alloc->total_size }; + + if (0 > (err = ioctl(pm_alloc->fd, PMEM_UNMAP, &sub))) + SEC_HWC_Log(HWC_LOG_ERROR, + "[%s][index=%d] ioctl(PMEM_UNMAP) failed : %d (%s)", + __func__, i, errno, strerror(errno)); +#if defined (PMEM_DEBUG) + else + SEC_HWC_Log(HWC_LOG_DEBUG, + "[%s] pm_alloc[%d] unmap fd=%d total_size=%d offset=0x%x", + __func__, i, pm_alloc->fd, pm_alloc->total_size, + pm_alloc->offset); +#endif + close(pm_alloc->fd); + + pm_alloc->fd = -1; + pm_alloc->total_size = 0; + pm_alloc->offset = 0; + pm_alloc->virt_addr = 0; + pm_alloc->phys_addr = 0; + } + } + + if (0 <= pm->pmem_master_fd) { + munmap(pm->pmem_master_base, pm->pmem_total_size); + close(pm->pmem_master_fd); + pm->pmem_master_fd = -1; + } + + pm->pmem_master_base = 0; + pm->pmem_total_size = 0; + + return 0; +} + +int checkPmem(sec_pmem_t *pm, unsigned int index, unsigned int requested_size) +{ + sec_pmem_alloc_t *pm_alloc = &(pm->sec_pmem_alloc[index]); + + if (0 < pm_alloc->virt_addr && + requested_size <= (unsigned int)(pm_alloc->total_size)) + return 0; + + pm_alloc->size = 0; + return -1; +} + +#endif diff --git a/exynos5/hal/libhwcomposer/SecHWCUtils.h b/exynos5/hal/libhwcomposer/SecHWCUtils.h new file mode 100644 index 0000000..799fc65 --- /dev/null +++ b/exynos5/hal/libhwcomposer/SecHWCUtils.h @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * @author Rama, Meka(v.meka@samsung.com) + Sangwoo, Park(sw5771.park@samsung.com) + Jamie, Oh (jung-min.oh@samsung.com) + * @date 2011-03-11 + * + */ + +#ifndef ANDROID_SEC_HWC_UTILS_H_ +#define ANDROID_SEC_HWC_UTILS_H_ + +#include +#include +#include + +#include +#include +#include + +#include +#include "s5p_fimc_v4l2.h" +#include "sec_utils_v4l2.h" + +#include +#include +#include +#include + +#include "linux/fb.h" + +#include "s3c_lcd.h" +#include "s3c_mem.h" +#include "sec_format.h" + +//#define HWC_DEBUG +#if defined(BOARD_USES_FIMGAPI) +#include "sec_g2d.h" +//#define SUB_TITLES_HWC +#endif + +#define NUM_OF_WIN (2) +#define NUM_OF_WIN_BUF (2) +#define NUM_OF_MEM_OBJ (1) + +#if (NUM_OF_WIN_BUF < 2) + #define ENABLE_FIMD_VSYNC +#endif + +#ifdef SAMSUNG_EXYNOS5250 +#define PP_DEVICE_DEV_NAME "/dev/video29" +#endif + +#define S3C_MEM_DEV_NAME "/dev/s3c-mem" +#define PMEM_DEVICE_DEV_NAME "/dev/pmem_gpu1" + +#define GSC_VERSION GSC_EVT1 +//#define USE_HW_PMEM + +#define PMEM_SIZE (1920 * 1280 * 2) + +struct sec_rect { + int32_t x; + int32_t y; + int32_t w; + int32_t h; +}; + +struct sec_img { + uint32_t f_w; + uint32_t f_h; + uint32_t w; + uint32_t h; + uint32_t format; + uint32_t base; + uint32_t offset; + uint32_t paddr; + uint32_t uoffset; + uint32_t voffset; + int usage; + int mem_id; +}; + +inline int SEC_MIN(int x, int y) +{ + return ((x < y) ? x : y); +} + +inline int SEC_MAX(int x, int y) +{ + return ((x > y) ? x : y); +} + +struct s3c_mem_t { + int fd; + struct s3c_mem_alloc mem_alloc[NUM_OF_MEM_OBJ]; +}; + +#ifdef USE_HW_PMEM +typedef struct __sec_pmem_alloc { + int fd; + int total_size; + int offset; + int size; + unsigned int virt_addr; + unsigned int phys_addr; +} sec_pmem_alloc_t; + +typedef struct __sec_pmem { + int pmem_master_fd; + void *pmem_master_base; + int pmem_total_size; + sec_pmem_alloc_t sec_pmem_alloc[NUM_OF_MEM_OBJ]; +} sec_pmem_t; + +inline size_t roundUpToPageSize(size_t x) +{ + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} +#endif + +struct hwc_win_info_t { + int fd; + int size; + sec_rect rect_info; + uint32_t addr[NUM_OF_WIN_BUF]; + int buf_index; + + int power_state; + int blending; + int layer_index; + int status; + int vsync; + int ion_fd; + + struct fb_fix_screeninfo fix_info; + struct fb_var_screeninfo var_info; + struct fb_var_screeninfo lcd_info; +}; + +enum { + HWC_WIN_FREE = 0, + HWC_WIN_RESERVED, +}; + +enum { + HWC_UNKNOWN_MEM_TYPE = 0, + HWC_PHYS_MEM_TYPE, + HWC_VIRT_MEM_TYPE, +}; + +struct hwc_context_t { + hwc_composer_device_t device; + + /* our private state goes below here */ + struct hwc_win_info_t win[NUM_OF_WIN]; + struct fb_var_screeninfo lcd_info; + s5p_fimc_t fimc; +#ifdef SUB_TITLES_HWC + sec_g2d_t g2d; +#endif + struct s3c_mem_t s3c_mem; +#ifdef USE_HW_PMEM + sec_pmem_t sec_pmem; +#endif + int num_of_fb_layer; + int num_of_hwc_layer; + int num_2d_blit_layer; + uint32_t layer_prev_buf[NUM_OF_WIN]; +}; + +typedef enum _LOG_LEVEL { + HWC_LOG_DEBUG, + HWC_LOG_WARNING, + HWC_LOG_ERROR, +} HWC_LOG_LEVEL; + +#define SEC_HWC_LOG_TAG "SECHWC_LOG" + +#ifdef HWC_DEBUG +#define SEC_HWC_Log(a, ...) ((void)_SEC_HWC_Log(a, SEC_HWC_LOG_TAG, __VA_ARGS__)) +#else +#define SEC_HWC_Log(a, ...) \ + do { \ + if (a == HWC_LOG_ERROR) \ + ((void)_SEC_HWC_Log(a, SEC_HWC_LOG_TAG, __VA_ARGS__)); \ + } while (0) +#endif + +extern void _SEC_HWC_Log(HWC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); + +/* copied from gralloc module ..*/ +typedef struct { + native_handle_t base; + + /* These fields can be sent cross process. They are also valid + * to duplicate within the same process. + * + * A table is stored within psPrivateData on gralloc_module_t (this + * is obviously per-process) which maps stamps to a mapped + * PVRSRV_CLIENT_MEM_INFO in that process. Each map entry has a lock + * count associated with it, satisfying the requirements of the + * Android API. This also prevents us from leaking maps/allocations. + * + * This table has entries inserted either by alloc() + * (alloc_device_t) or map() (gralloc_module_t). Entries are removed + * by free() (alloc_device_t) and unmap() (gralloc_module_t). + * + * As a special case for framebuffer_device_t, framebuffer_open() + * will add and framebuffer_close() will remove from this table. + */ + +#define IMG_NATIVE_HANDLE_NUMFDS 1 + /* The `fd' field is used to "export" a meminfo to another process. + * Therefore, it is allocated by alloc_device_t, and consumed by + * gralloc_module_t. The framebuffer_device_t does not need a handle, + * and the special value IMG_FRAMEBUFFER_FD is used instead. + */ + int fd; + +#if 1 + int format; + int magic; + int flags; + int size; + int offset; + int base_addr; +#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(uint64_t) / sizeof(int)) + 4 + 6) +#else +#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(IMG_UINT64) / sizeof(int)) + 4) +#endif + /* A KERNEL unique identifier for any exported kernel meminfo. Each + * exported kernel meminfo will have a unique stamp, but note that in + * userspace, several meminfos across multiple processes could have + * the same stamp. As the native_handle can be dup(2)'d, there could be + * multiple handles with the same stamp but different file descriptors. + */ + uint64_t ui64Stamp; + + /* We could live without this, but it lets us perform some additional + * validation on the client side. Normally, we'd have no visibility + * of the allocated usage, just the lock usage. + */ + int usage; + + /* In order to do efficient cache flushes we need the buffer dimensions + * and format. These are available on the android_native_buffer_t, + * but the platform doesn't pass them down to the graphics HAL. + * + * TODO: Ideally the platform would be modified to not require this. + */ + int width; + int height; + int bpp; +} +__attribute__((aligned(sizeof(int)),packed)) sec_native_handle_t; + +int window_open (struct hwc_win_info_t *win, int id); +int window_close (struct hwc_win_info_t *win); +int window_set_pos (struct hwc_win_info_t *win); +int window_get_info (struct hwc_win_info_t *win, int win_num); +int window_pan_display(struct hwc_win_info_t *win); +int window_show (struct hwc_win_info_t *win); +int window_hide (struct hwc_win_info_t *win); +int window_get_global_lcd_info(int fd, struct fb_var_screeninfo *lcd_info); + +int createVideoDev (s5p_fimc_t *fimc); +int destroyVideoDev(s5p_fimc_t *fimc); +int runFimc(struct hwc_context_t *ctx, + struct sec_img *src_img, struct sec_rect *src_rect, + struct sec_img *dst_img, struct sec_rect *dst_rect, + uint32_t transform); + +#ifdef SUB_TITLES_HWC +int runG2d(struct hwc_context_t *ctx, + g2d_rect *src_rect, g2d_rect *dst_rect, + uint32_t transform); + +int destroyG2d(sec_g2d_t *g2d); +int createG2d(sec_g2d_t *g2d); +#endif + +int createMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size); +int destroyMem(struct s3c_mem_t *mem); +int checkMem (struct s3c_mem_t *mem, unsigned int index, unsigned int size); + +#ifdef USE_HW_PMEM +int createPmem (sec_pmem_t *pm, unsigned int size); +int destroyPmem(sec_pmem_t *pm); +int checkPmem (sec_pmem_t *pm, unsigned int index, unsigned int size); +#endif + +#endif /* ANDROID_SEC_HWC_UTILS_H_*/ diff --git a/exynos5/hal/libhwjpeg/Android.mk b/exynos5/hal/libhwjpeg/Android.mk new file mode 100644 index 0000000..70e25fe --- /dev/null +++ b/exynos5/hal/libhwjpeg/Android.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES := $(LOCAL_PATH) \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES:= \ + SecJpegCodecHal.cpp \ + SecJpegEncoderHal.cpp \ + SecJpegEncoder.cpp \ + SecJpegDecoderHal.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libion + +#LOCAL_STATIC_LIBRARIES := \ + +LOCAL_MODULE:= libhwjpeg + +LOCAL_MODULE_TAGS := eng + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos5/hal/libhwjpeg/SecJpegCodecHal.cpp b/exynos5/hal/libhwjpeg/SecJpegCodecHal.cpp new file mode 100644 index 0000000..b78212b --- /dev/null +++ b/exynos5/hal/libhwjpeg/SecJpegCodecHal.cpp @@ -0,0 +1,338 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "SecJpegCodecHal.h" + +#define JPEG_ERROR_LOG(fmt,...) + +SecJpegCodecHal::SecJpegCodecHal() +{ +} + +SecJpegCodecHal::~SecJpegCodecHal() +{ +} + +int SecJpegCodecHal::t_v4l2Querycap(int iFd) +{ + struct v4l2_capability cap; + int iRet = ERROR_NONE; + + iRet = ioctl(iFd, VIDIOC_QUERYCAP, &cap); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYCAP failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2SetJpegcomp(int iFd, int iQuality) +{ + struct v4l2_jpegcompression arg; + int iRet = ERROR_NONE; + + arg.quality = iQuality; + + iRet = ioctl(iFd, VIDIOC_S_JPEGCOMP, &arg); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_JPEGCOMP failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2SetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig) +{ + struct v4l2_format fmt; + int iRet = ERROR_NONE; + + fmt.type = eType; + fmt.fmt.pix_mp.width = pstConfig->width; + fmt.fmt.pix_mp.height = pstConfig->height; + fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; + fmt.fmt.pix_mp.num_planes = pstConfig->numOfPlanes; + + if (pstConfig->mode == MODE_ENCODE) + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (pstConfig->mode == MODE_ENCODE) { + fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.in_fmt; + } else { + fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.in_fmt; + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = pstConfig->sizeJpeg; + } + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (pstConfig->mode == MODE_ENCODE) { + fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.out_fmt; + } else { + fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.out_fmt; + fmt.fmt.pix_mp.width = pstConfig->scaled_width; + fmt.fmt.pix_mp.height = pstConfig->scaled_height; + } + break; + default: + return -ERROR_INVALID_V4l2_BUF_TYPE; + break; + } + + iRet = ioctl(iFd, VIDIOC_S_FMT, &fmt); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_FMT failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2GetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig) +{ + struct v4l2_format fmt; + int iRet = ERROR_NONE; + + fmt.type = eType; + iRet = ioctl(iFd, VIDIOC_G_FMT, &fmt); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_G_FMT failed", __func__, iRet); + return iRet; + } + + switch (fmt.type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + pstConfig->width = fmt.fmt.pix.width; + pstConfig->height = fmt.fmt.pix.height; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + pstConfig->width = fmt.fmt.pix_mp.width; + pstConfig->height = fmt.fmt.pix_mp.height; + if (pstConfig->mode == MODE_ENCODE) + pstConfig->pix.enc_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; + else + pstConfig->pix.dec_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + pstConfig->width = fmt.fmt.pix_mp.width; + pstConfig->height = fmt.fmt.pix_mp.height; + if (pstConfig->mode == MODE_ENCODE) + pstConfig->pix.enc_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; + else + pstConfig->pix.dec_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; + break; + default: + return -ERROR_INVALID_V4l2_BUF_TYPE; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo) +{ + struct v4l2_requestbuffers req; + int iRet = ERROR_NONE; + + memset(&req, 0, sizeof(req)); + + req.type = pstBufInfo->buf_type; + req.memory = pstBufInfo->memory; + + //if (pstBufInfo->memory == V4L2_MEMORY_MMAP) + req.count = iBufCount; + + iRet = ioctl(iFd, VIDIOC_REQBUFS, &req); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_REQBUFS failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2Querybuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf) +{ + struct v4l2_buffer v4l2_buf; + struct v4l2_plane plane[JPEG_MAX_PLANE_CNT]; + int iRet = ERROR_NONE; + int i; + + memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane)); + + v4l2_buf.index = 0; + v4l2_buf.type = pstBufInfo->buf_type; + v4l2_buf.memory = pstBufInfo->memory; + v4l2_buf.length = pstBufInfo->numOfPlanes; + v4l2_buf.m.planes = plane; + + iRet = ioctl(iFd, VIDIOC_QUERYBUF, &v4l2_buf); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYBUF failed", __func__, iRet); + return iRet; + } + + for (i= 0; i < v4l2_buf.length; i++) { + pstBuf->size[i] = v4l2_buf.m.planes[i].length; + pstBuf->addr[i] = (char *) mmap(0, + pstBuf->size[i], + PROT_READ | PROT_WRITE, MAP_SHARED, iFd, + v4l2_buf.m.planes[i].m.mem_offset); + + if (pstBuf->addr[i] == MAP_FAILED) { + JPEG_ERROR_LOG("[%s]: mmap failed", __func__); + return -ERROR_MMAP_FAILED; + } + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2Qbuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf) +{ + struct v4l2_buffer v4l2_buf; + struct v4l2_plane plane[JPEG_MAX_PLANE_CNT]; + int i; + int iRet = ERROR_NONE; + + memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer)); + memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane)); + + v4l2_buf.index = 0; + v4l2_buf.type = pstBufInfo->buf_type; + v4l2_buf.memory = pstBufInfo->memory; + v4l2_buf.length = pstBufInfo->numOfPlanes; + v4l2_buf.m.planes = plane; + + if (pstBufInfo->memory == V4L2_MEMORY_USERPTR) { + for (i = 0; i < pstBufInfo->numOfPlanes; i++) { + v4l2_buf.m.planes[i].m.userptr = (unsigned long)pstBuf->addr[i]; + v4l2_buf.m.planes[i].length = pstBuf->size[i]; + } + } + + iRet = ioctl(iFd, VIDIOC_QBUF, &v4l2_buf); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d] VIDIOC_QBUF failed", __func__, iRet); + pstBuf->numOfPlanes = 0; + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory) +{ + struct v4l2_buffer buf; + int iRet = ERROR_NONE; + + memset(&buf, 0, sizeof(struct v4l2_buffer)); + + buf.type = eType; + buf.memory = eMemory; + + iRet = ioctl(iFd, VIDIOC_DQBUF, &buf); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d] VIDIOC_DQBUF failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2StreamOn(int iFd, enum v4l2_buf_type eType) +{ + int iRet = ERROR_NONE; + + iRet = ioctl(iFd, VIDIOC_STREAMON, &eType); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMON failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2StreamOff(int iFd, enum v4l2_buf_type eType) +{ + int iRet = ERROR_NONE; + + iRet = ioctl(iFd, VIDIOC_STREAMOFF, &eType); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMOFF failed", __func__, iRet); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2SetCtrl(int iFd, int iCid, int iValue) +{ + struct v4l2_control vc; + int iRet = ERROR_NONE; + + vc.id = iCid; + vc.value = iValue; + + iRet = ioctl(iFd, VIDIOC_S_CTRL, &vc); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s] VIDIOC_S_CTRL failed : cid(%d), value(%d)\n", __func__, iCid, iValue); + return iRet; + } + + return iRet; +} + +int SecJpegCodecHal::t_v4l2GetCtrl(int iFd, int iCid) +{ + struct v4l2_control ctrl; + int iRet = ERROR_NONE; + + ctrl.id = iCid; + + iRet = ioctl(iFd, VIDIOC_G_CTRL, &ctrl); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s] VIDIOC_G_CTRL failed : cid(%d)\n", __func__, ctrl.id); + return iRet; + } + + return ctrl.value; +} + diff --git a/exynos5/hal/libhwjpeg/SecJpegDecoderHal.cpp b/exynos5/hal/libhwjpeg/SecJpegDecoderHal.cpp new file mode 100644 index 0000000..563b15a --- /dev/null +++ b/exynos5/hal/libhwjpeg/SecJpegDecoderHal.cpp @@ -0,0 +1,498 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "SecJpegCodecHal.h" + +#define JPEG_ERROR_LOG(fmt,...) + +#define NUM_PLANES (1) +#define NUM_BUFFERS (1) + +SecJpegDecoderHal::SecJpegDecoderHal() +{ + t_iJpegFd = -1; + t_bFlagCreate = false; +} + +SecJpegDecoderHal::~SecJpegDecoderHal() +{ + if (t_bFlagCreate == true) { + this->destroy(); + } +} + +int SecJpegDecoderHal::create(void) +{ + if (t_bFlagCreate == true) { + return ERROR_JPEG_DEVICE_ALREADY_CREATE; + } + + int iRet = ERROR_NONE; + + t_iJpegFd = open(JPEG_DEC_NODE, O_RDWR, 0); + + if (t_iJpegFd < 0) { + t_iJpegFd = -1; + JPEG_ERROR_LOG("[%s]: JPEG_DEC_NODE open failed", __func__); + return ERROR_CANNOT_OPEN_JPEG_DEVICE; + } + + if (t_iJpegFd <= 0) { + t_iJpegFd = -1; + JPEG_ERROR_LOG("ERR(%s):JPEG device was closed\n", __func__); + return ERROR_JPEG_DEVICE_ALREADY_CLOSED; + } + + iRet = t_v4l2Querycap(t_iJpegFd); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s]: QUERYCAP failed", __func__); + close(t_iJpegFd); + return ERROR_CANNOT_OPEN_JPEG_DEVICE; + } + + memset(&t_stJpegConfig, 0, sizeof(struct CONFIG)); + memset(&t_stJpegInbuf, 0, sizeof(struct BUFFER)); + memset(&t_stJpegOutbuf, 0, sizeof(struct BUFFER)); + + t_stJpegConfig.mode = MODE_DECODE; + + t_bFlagCreate = true; + t_bFlagCreateInBuf = false; + t_bFlagCreateOutBuf = false; + t_bFlagExcute = false; + + t_iPlaneNum = 0; + + return ERROR_NONE; +} + +int SecJpegDecoderHal::destroy(void) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_ALREADY_DESTROY; + } + + if (t_iJpegFd > 0) { + struct BUF_INFO stBufInfo; + int iRet = ERROR_NONE; + + if (t_bFlagExcute) { + iRet = t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + } + + if (t_bFlagExcute) { + stBufInfo.numOfPlanes = NUM_PLANES; + stBufInfo.memory = V4L2_MEMORY_MMAP; + + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); + + stBufInfo.numOfPlanes = t_iPlaneNum; + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); + } + + iRet = close(t_iJpegFd); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: JPEG_DEC_NODE close failed", __func__, iRet); + } + } + + t_iJpegFd = -1; + t_bFlagCreate = false; + return ERROR_NONE; +} + +int SecJpegDecoderHal::setSize(int iW, int iH) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_NOT_CREATE_YET; + } + + if (iW < 0 || MAX_JPG_WIDTH < iW) { + return ERROR_INVALID_IMAGE_SIZE; + } + + if (iH < 0 || MAX_JPG_HEIGHT < iH) { + return ERROR_INVALID_IMAGE_SIZE; + } + + t_stJpegConfig.width = iW; + t_stJpegConfig.height = iH; + + return ERROR_NONE; +} + +int SecJpegDecoderHal::setJpegConfig(void *pConfig) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_NOT_CREATE_YET; + } + + if (pConfig == NULL) { + return ERROR_JPEG_CONFIG_POINTER_NULL; + } + + memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG)); + + if (t_stJpegConfig.pix.dec_fmt.out_fmt == V4L2_PIX_FMT_NV12) { + t_iPlaneNum = 2; + } else { + t_iPlaneNum = 1; + } + + return ERROR_NONE; +} + +void *SecJpegDecoderHal::getJpegConfig(void) +{ + if (t_bFlagCreate == false) { + return NULL; + } + + return &t_stJpegConfig; +} + +char *SecJpegDecoderHal::getInBuf(int *piInputSize) +{ + if (t_bFlagCreate == false) { + return NULL; + } + + if (t_bFlagCreateInBuf == false) { + + *piInputSize = 0; + return NULL; + } + + *piInputSize = t_stJpegInbuf.size[0]; + + return (char *)(t_stJpegInbuf.addr[0]); +} + +char **SecJpegDecoderHal::getOutBuf(int *piOutputSize) +{ + if (t_bFlagCreate == false) { + return NULL; + } + + if (t_bFlagCreateOutBuf == false) { + + *piOutputSize = 0; + return NULL; + } + + for (int i=0;i + +#include "SecJpegEncoder.h" + +static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; + +#define JPEG_ERROR_LOG(fmt,...) + +#define JPEG_MAIN_DUMP (0) +#define JPEG_THUMB_DUMP (0) + +SecJpegEncoder::SecJpegEncoder() +{ + m_flagCreate = false; + m_jpegMain = NULL; + m_jpegThumb = NULL; + m_thumbnailW = 0; + m_thumbnailH = 0; + m_pThumbInputBuffer = NULL; + m_pThumbOutputBuffer = NULL; +#ifdef JPEG_WA_FOR_PAGEFAULT + m_pJpegInputBuffer = 0; + m_pExtInBuf = NULL; + m_iInBufSize = 0; +#endif // JPEG_WA_FOR_PAGEFAULT + m_ionJpegClient = 0;; + m_ionThumbInBuffer = 0; + m_ionThumbOutBuffer = 0; +#ifdef JPEG_WA_FOR_PAGEFAULT + m_ionJpegInBuffer = 0;; +#endif // JPEG_WA_FOR_PAGEFAULT +} + +SecJpegEncoder::~SecJpegEncoder() +{ + if (m_flagCreate == true) { + this->destroy(); + } +} + +bool SecJpegEncoder::flagCreate(void) +{ + return m_flagCreate; +} + +int SecJpegEncoder::create(void) +{ + int ret = ERROR_NONE; + if (m_flagCreate == true) { + return ERROR_ALREADY_CREATE; + } + + if (m_jpegMain == NULL) { + m_jpegMain = new SecJpegEncoderHal; + + if (m_jpegMain == NULL) { + JPEG_ERROR_LOG("ERR(%s):Cannot create SecJpegEncoderHal class\n", __func__); + return ERROR_CANNOT_CREATE_SEC_JPEG_ENC_HAL; + } + + ret = m_jpegMain->create(); + if (ret) { + return ret; + } + + ret = m_jpegMain->setCache(JPEG_CACHE_ON); + + if (ret) { + m_jpegMain->destroy(); + return ret; + } + } + + m_flagCreate = true; + + return ERROR_NONE; +} + +int SecJpegEncoder::destroy(void) +{ + if (m_flagCreate == false) { + return ERROR_ALREADY_DESTROY; + } + + if (m_jpegMain != NULL) { + m_jpegMain->destroy(); + delete m_jpegMain; + m_jpegMain = NULL; + } + + if (m_jpegThumb != NULL) { + int iSize = sizeof(char)*m_thumbnailW*m_thumbnailH*4; + +#ifdef JPEG_WA_FOR_PAGEFAULT + iSize += JPEG_WA_BUFFER_SIZE; + + freeJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, m_iInBufSize); +#endif //JPEG_WA_FOR_PAGEFAULT + + freeJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iSize); + freeJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iSize); + + if (m_ionJpegClient != 0) { + ion_client_destroy(m_ionJpegClient); + m_ionJpegClient = 0; + } + + m_jpegThumb->destroy(); + delete m_jpegThumb; + m_jpegThumb = NULL; + } + + m_flagCreate = false; + m_thumbnailW = 0; + m_thumbnailH = 0; + return ERROR_NONE; +} + +int SecJpegEncoder::setSize(int w, int h) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + return m_jpegMain->setSize(w, h); +} + + +int SecJpegEncoder::setQuality(int quality) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + return m_jpegMain->setQuality(quality); +} + +int SecJpegEncoder::setColorFormat(int colorFormat) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + return m_jpegMain->setColorFormat(colorFormat); +} + +int SecJpegEncoder::setJpegFormat(int jpegFormat) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + return m_jpegMain->setJpegFormat(jpegFormat); +} + +int SecJpegEncoder::updateConfig(void) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + return m_jpegMain->updateConfig(); +} + +char *SecJpegEncoder::getInBuf(int *input_size) +{ + if (m_flagCreate == false) { + return NULL; + } + + int inSize = 0; + char *inBuf = *(m_jpegMain->getInBuf(&inSize)); + + if (inBuf == NULL) { + JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__); + return NULL; + } + + *input_size = inSize; + + return inBuf; +} + +char *SecJpegEncoder::getOutBuf(int *output_size) +{ + if (m_flagCreate == false) { + return NULL; + } + + int outSize = 0; + char *outBuf = m_jpegMain->getOutBuf(&outSize); + + if (outBuf == NULL) { + JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__); + return NULL; + } + + *output_size = outSize; + + return outBuf; +} + +int SecJpegEncoder::setInBuf(char *buf, int size) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + if (buf == NULL) { + return ERROR_BUFFR_IS_NULL; + } + + if (size<=0) { + return ERROR_BUFFER_TOO_SMALL; + } + + int ret = ERROR_NONE; + +#ifdef JPEG_WA_FOR_PAGEFAULT + size += JPEG_WA_BUFFER_SIZE; + + freeJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, size); + + if (m_ionJpegClient == 0) { + m_ionJpegClient = ion_client_create(); + if (m_ionJpegClient < 0) { + JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, size); + m_ionJpegClient = 0; + return ret; + } + } + + ret = allocJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, size); + if (ret != ERROR_NONE) { + return ret; + } + + ret = m_jpegMain->setInBuf(&m_pJpegInputBuffer, &size); + if (ret) { + JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__); + return ret; + } + m_iInBufSize = size; + + m_pExtInBuf = buf; + +#else // NO JPEG_WA_FOR_PAGEFAULT + ret = m_jpegMain->setInBuf(&buf, &size); + if (ret) { + JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__); + return ret; + } +#endif // JPEG_WA_FOR_PAGEFAULT + + return ERROR_NONE; +} + +int SecJpegEncoder::setOutBuf(char *buf, int size) +{ + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + + if (buf == NULL) { + return ERROR_BUFFR_IS_NULL; + } + + if (size<=0) { + return ERROR_BUFFER_TOO_SMALL; + } + + int ret = ERROR_NONE; + ret = m_jpegMain->setOutBuf(buf, size); + if (ret) { + JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__); + return ret; + } + + return ERROR_NONE; +} + +int SecJpegEncoder::encode(int *size, exif_attribute_t *exifInfo) +{ + int ret = ERROR_NONE; + unsigned char *exifOut = NULL; + + if (m_flagCreate == false) { + return ERROR_NOT_YET_CREATED; + } + +#ifdef JPEG_WA_FOR_PAGEFAULT + memcpy(m_pJpegInputBuffer, m_pExtInBuf, m_iInBufSize-JPEG_WA_BUFFER_SIZE); +#endif // JPEG_WA_FOR_PAGEFAULT + + ret = m_jpegMain->encode(); + if (ret) { + JPEG_ERROR_LOG("encode failed\n"); + return ret; + } + + int iJpegSize = m_jpegMain->getJpegSize(); + + if (iJpegSize<=0) { + JPEG_ERROR_LOG("%s:: output_size is too small(%d)!!\n", __func__, iJpegSize); + return ERROR_OUT_BUFFER_SIZE_TOO_SMALL; + } + + int iOutputSize = 0; + char *pcJpegBuffer = m_jpegMain->getOutBuf(&iOutputSize); + + if (pcJpegBuffer == NULL) { + JPEG_ERROR_LOG("%s::buffer is null!!\n", __func__); + return ERROR_OUT_BUFFER_CREATE_FAIL; + } + + if (exifInfo != NULL) { + unsigned int thumbLen, exifLen; + + unsigned int bufSize = 0; + if (exifInfo->enableThumb) { + if (encodeThumbnail(&thumbLen)) { + bufSize = EXIF_FILE_SIZE; + exifInfo->enableThumb = false; + } else { + if (thumbLen > EXIF_LIMIT_SIZE) { + bufSize = EXIF_FILE_SIZE; + exifInfo->enableThumb = false; + } + else { + bufSize = EXIF_FILE_SIZE + thumbLen; + } + } + } else { + bufSize = EXIF_FILE_SIZE; + exifInfo->enableThumb = false; + } + + exifOut = new unsigned char[bufSize]; + if (exifOut == NULL) { + JPEG_ERROR_LOG("%s::Failed to allocate for exifOut", __func__); + delete[] exifOut; + return ERROR_EXIFOUT_ALLOC_FAIL; + } + memset(exifOut, 0, bufSize); + + if (makeExif (exifOut, exifInfo, &exifLen)) { + JPEG_ERROR_LOG("%s::Failed to make EXIF", __func__); + delete[] exifOut; + return ERROR_MAKE_EXIF_FAIL; + } + + if (exifLen <= EXIF_LIMIT_SIZE) { + memmove(pcJpegBuffer+exifLen+2, pcJpegBuffer+2, iJpegSize - 2); + memcpy(pcJpegBuffer+2, exifOut, exifLen); + iJpegSize += exifLen; + } + + delete[] exifOut; + } + + *size = iJpegSize; + + return ERROR_NONE; +} + +int SecJpegEncoder::makeExif (unsigned char *exifOut, + exif_attribute_t *exifInfo, + unsigned int *size, + bool useMainbufForThumb) +{ + unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset; + unsigned int tmp, LongerTagOffest = 0, exifSizeExceptThumb; + pApp1Start = pCur = exifOut; + + //2 Exif Identifier Code & TIFF Header + pCur += 4; // Skip 4 Byte for APP1 marker and length + unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + memcpy(pCur, ExifIdentifierCode, 6); + pCur += 6; + + /* Byte Order - little endian, Offset of IFD - 0x00000008.H */ + unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 }; + memcpy(pCur, TiffHeader, 8); + pIfdStart = pCur; + pCur += 8; + + //2 0th IFD TIFF Tags + if (exifInfo->enableGps) + tmp = NUM_0TH_IFD_TIFF; + else + tmp = NUM_0TH_IFD_TIFF - 1; + + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII, + strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT, + 1, exifInfo->ycbcr_positioning); + writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); + if (exifInfo->enableGps) { + pGpsIfdPtr = pCur; + pCur += IFD_SIZE; // Skip a ifd size for gps IFD pointer + } + + pNextIfdOffset = pCur; // Skip a offset size for next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD Exif Private Tags + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_0TH_IFD_EXIF; + memcpy(pCur, &tmp , NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL, + 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL, + 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT, + 1, exifInfo->exposure_program); + writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT, + 1, exifInfo->iso_speed_rating); + writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED, + 4, exifInfo->exif_version); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII, + 20, exifInfo->date_time, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL, + 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT, + 1, exifInfo->metering_mode); + writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT, + 1, exifInfo->flash); + writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL, + 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart); + char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 }; + int commentsLen = strlen((char *)exifInfo->user_comment) + 1; + memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen); + memcpy(exifInfo->user_comment, code, sizeof(code)); + writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED, + commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT, + 1, exifInfo->color_space); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->width); + writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG, + 1, exifInfo->height); + writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG, + 1, exifInfo->exposure_mode); + writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG, + 1, exifInfo->white_balance); + writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG, + 1, exifInfo->scene_capture_type); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + //2 0th IFD GPS Info Tags + if (exifInfo->enableGps) { + writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG, + 1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + if (exifInfo->gps_processing_method[0] == 0) { + // don't create GPS_PROCESSING_METHOD tag if there isn't any + tmp = NUM_0TH_IFD_GPS - 1; + } else { + tmp = NUM_0TH_IFD_GPS; + } + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE, + 4, exifInfo->gps_version_id); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_latitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII, + 2, exifInfo->gps_longitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE, + 1, exifInfo->gps_altitude_ref); + writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL, + 1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL, + 3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart); + tmp = strlen((char*)exifInfo->gps_processing_method); + if (tmp > 0) { + if (tmp > 100) { + tmp = 100; + } + unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)]; + memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix)); + memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp); + writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED, + tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart); + } + writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII, + 11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart); + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + } + + //2 1th IFD TIFF Tags + char *thumbBuf = NULL; + unsigned int thumbSize = 0; + + if (useMainbufForThumb) { + if (m_jpegMain) { + thumbBuf = m_jpegMain->getOutBuf((int *)&thumbSize); + thumbSize = m_jpegMain->getJpegSize(); + } + } else { + if (m_jpegThumb) { + thumbBuf = m_jpegThumb->getOutBuf((int *)&thumbSize); + thumbSize = m_jpegThumb->getJpegSize(); + } + } + + if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize != 0)) { + exifSizeExceptThumb = tmp = LongerTagOffest; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + + pCur = pIfdStart + LongerTagOffest; + + tmp = NUM_1TH_IFD_TIFF; + memcpy(pCur, &tmp, NUM_SIZE); + pCur += NUM_SIZE; + + LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE; + + writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, + 1, exifInfo->widthThumb); + writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, + 1, exifInfo->heightThumb); + writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT, + 1, exifInfo->compression_scheme); + writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, + 1, exifInfo->orientation); + writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL, + 1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart); + writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT, + 1, exifInfo->resolution_unit); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG, + 1, LongerTagOffest); + writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG, + 1, thumbSize); + + tmp = 0; + memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset + pCur += OFFSET_SIZE; + + memcpy(pIfdStart + LongerTagOffest, + thumbBuf, thumbSize); + LongerTagOffest += thumbSize; + if (LongerTagOffest > EXIF_LIMIT_SIZE) { + LongerTagOffest = exifSizeExceptThumb; + tmp = 0; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + } + } else { + tmp = 0; + memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE); // NEXT IFD offset skipped on 0th IFD + } + + unsigned char App1Marker[2] = { 0xff, 0xe1 }; + memcpy(pApp1Start, App1Marker, 2); + pApp1Start += 2; + + *size = 10 + LongerTagOffest; + tmp = *size - 2; // APP1 Maker isn't counted + unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF}; + memcpy(pApp1Start, size_mm, 2); + + return ERROR_NONE; +} + +/* + * private member functions +*/ +inline void SecJpegEncoder::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned int value) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, &value, 4); + *pCur += 4; +} + +inline void SecJpegEncoder::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue) +{ + char buf[4] = { 0,}; + + memcpy(buf, pValue, count); + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, buf, 4); + *pCur += 4; +} + +inline void SecJpegEncoder::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + unsigned char *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, count); + *offset += count; +} + +inline void SecJpegEncoder::writeExifIfd(unsigned char **pCur, + unsigned short tag, + unsigned short type, + unsigned int count, + rational_t *pValue, + unsigned int *offset, + unsigned char *start) +{ + memcpy(*pCur, &tag, 2); + *pCur += 2; + memcpy(*pCur, &type, 2); + *pCur += 2; + memcpy(*pCur, &count, 4); + *pCur += 4; + memcpy(*pCur, offset, 4); + *pCur += 4; + memcpy(start + *offset, pValue, 8 * count); + *offset += 8 * count; +} + +int SecJpegEncoder::m_scaleDownYuv422(char *srcBuf, unsigned int srcW, unsigned int srcH, + char *dstBuf, unsigned int dstW, unsigned int dstH) +{ + int step_x, step_y; + int iXsrc, iXdst; + int x, y, src_y_start_pos, dst_pos, src_pos; + + if (dstW & 0x01 || dstH & 0x01) { + return ERROR_INVALID_SCALING_WIDTH_HEIGHT; + } + + step_x = srcW / dstW; + step_y = srcH / dstH; + + unsigned int srcWStride = srcW * 2; + unsigned int stepXStride = step_x * 2; + + dst_pos = 0; + for (unsigned int y = 0; y < dstH; y++) { + src_y_start_pos = srcWStride * step_y * y; + + for (unsigned int x = 0; x < dstW; x += 2) { + src_pos = src_y_start_pos + (stepXStride * x); + + dstBuf[dst_pos++] = srcBuf[src_pos ]; + dstBuf[dst_pos++] = srcBuf[src_pos + 1]; + dstBuf[dst_pos++] = srcBuf[src_pos + 2]; + dstBuf[dst_pos++] = srcBuf[src_pos + 3]; + } + } + + return ERROR_NONE; +} + +// thumbnail +int SecJpegEncoder::setThumbnailSize(int w, int h) +{ + if (m_flagCreate == false) { + return ERROR_CANNOT_CREATE_SEC_JPEG_ENC_HAL; + } + + if (w < 0 || MAX_JPG_WIDTH < w) { + return false; + } + + if (h < 0 || MAX_JPG_HEIGHT < h) { + return false; + } + + m_thumbnailW = w; + m_thumbnailH = h; + return ERROR_NONE; +} + + +int SecJpegEncoder::encodeThumbnail(unsigned int *size, bool useMain) +{ + int ret = ERROR_NONE; + + if (m_flagCreate == false) { + return ERROR_CANNOT_CREATE_SEC_JPEG_ENC_HAL; + } + + // create jpeg thumbnail class + if (m_jpegThumb == NULL) { + m_jpegThumb = new SecJpegEncoderHal; + + if (m_jpegThumb == NULL) { + JPEG_ERROR_LOG("ERR(%s):Cannot open a jpeg device file\n", __func__); + return ERROR_CANNOT_CREATE_SEC_THUMB; + } + } + + ret = m_jpegThumb->create(); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail create\n", __func__); + return ret; + } + + ret = m_jpegThumb->setCache(JPEG_CACHE_ON); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail cache set\n", __func__); + return ret; + } + + void *pConfig = m_jpegMain->getJpegConfig(); + if (pConfig == NULL) { + JPEG_ERROR_LOG("ERR(%s):Fail getJpegConfig\n", __func__); + return ERROR_BUFFR_IS_NULL; + } + + ret = m_jpegThumb->setJpegConfig(pConfig); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setJpegConfig\n", __func__); + return ret; + } + + ret = m_jpegThumb->setQuality(JPEG_THUMBNAIL_QUALITY); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setQuality\n", __func__); + return ret; + } + + ret = m_jpegThumb->setSize(m_thumbnailW, m_thumbnailH); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setSize\n", __func__); + return ret; + } + + int iThumbSize = sizeof(char)*m_thumbnailW*m_thumbnailH*4; +#ifdef JPEG_WA_FOR_PAGEFAULT + iThumbSize += JPEG_WA_BUFFER_SIZE; +#endif //JPEG_WA_FOR_PAGEFAULT + + freeJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iThumbSize); + freeJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iThumbSize); + + if (m_ionJpegClient == 0) { + m_ionJpegClient = ion_client_create(); + if (m_ionJpegClient < 0) { + JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, m_ionJpegClient); + m_ionJpegClient = 0; + return ret; + } + } + + ret = allocJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iThumbSize); + if (ret != ERROR_NONE) { + return ret; + } + + ret = m_jpegThumb->setInBuf(&m_pThumbInputBuffer, &iThumbSize); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setInBuf\n", __func__); + return ret; + } + + ret = allocJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iThumbSize); + if (ret != ERROR_NONE) { + return ret; + } + + ret = m_jpegThumb->setOutBuf((char *)m_pThumbOutputBuffer, iThumbSize); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setOutBuf\n", __func__); + return ret; + } + + ret = m_jpegThumb->updateConfig(); + if (ret) { + JPEG_ERROR_LOG("update config failed\n"); + return ret; + } + + if (useMain) { + + int iW=0, iH=0; + int input_sizeMain=0, input_sizeThumb=0; + + ret = m_jpegMain->getSize(&iW, &iH); + if (ret) { + JPEG_ERROR_LOG("ERR(%s):Fail setJpegConfig\n", __func__); + return ret; + } + + ret = m_scaleDownYuv422(*(m_jpegMain->getInBuf(&input_sizeMain)), + iW, + iH, + *(m_jpegThumb->getInBuf(&input_sizeThumb)), + m_thumbnailW, + m_thumbnailH); + if (ret) { + JPEG_ERROR_LOG("%s::m_scaleDownYuv422(%d, %d, %d, %d) fail", __func__, iW, iH, m_thumbnailW, m_thumbnailH); + return ret; + } + } + else { + return ERROR_IMPLEMENT_NOT_YET; + } + + int outSizeThumb; + + ret = m_jpegThumb->encode(); + if (ret) { + JPEG_ERROR_LOG("encode failed\n"); + return ret; + } + + outSizeThumb = m_jpegThumb->getJpegSize(); + if (outSizeThumb<=0) { + JPEG_ERROR_LOG("jpeg size is too small\n"); + return ERROR_THUMB_JPEG_SIZE_TOO_SMALL; + } + + *size = (unsigned int)outSizeThumb; + + return ERROR_NONE; + +} + +int SecJpegEncoder::allocJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size) +{ + int ret = ERROR_NONE; + + if (ionClient == 0) { + JPEG_ERROR_LOG("[%s]ionClient is zero (%d)\n", __func__, ionClient); + return ERROR_BUFFR_IS_NULL; + } + + *ionBuffer = ion_alloc(ionClient, size, 0, ION_HEAP_SYSTEM_MASK); + if (*ionBuffer == -1) { + JPEG_ERROR_LOG("[%s]ion_alloc(%d) failed\n", __func__, size); + *ionBuffer = 0; + return ret; + } + + *buffer = (char *)ion_map(*ionBuffer, size, 0); + if (*buffer == MAP_FAILED) { + JPEG_ERROR_LOG("[%s]src ion map failed(%d)\n", __func__, size); + ion_free(*ionBuffer); + *ionBuffer = 0; + *buffer = NULL; + return ret; + } + + return ret; +} + +void SecJpegEncoder::freeJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size) +{ + if (ionClient == 0) { + return; + } + + if (*buffer != NULL) { + ion_unmap(*buffer, size); + *buffer = NULL; + } + + if (*ionBuffer != 0) { + ion_free(*ionBuffer); + *ionBuffer = 0; + } +} + diff --git a/exynos5/hal/libhwjpeg/SecJpegEncoderHal.cpp b/exynos5/hal/libhwjpeg/SecJpegEncoderHal.cpp new file mode 100644 index 0000000..1a3deca --- /dev/null +++ b/exynos5/hal/libhwjpeg/SecJpegEncoderHal.cpp @@ -0,0 +1,497 @@ +/* + * Copyright Samsung Electronics Co.,LTD. + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "SecJpegCodecHal.h" + +#define JPEG_ERROR_LOG(fmt,...) + +#define NUM_PLANES (1) +#define NUM_BUFFERS (1) + +SecJpegEncoderHal::SecJpegEncoderHal() +{ + t_iJpegFd = -1; + t_bFlagCreate = false; +} + +SecJpegEncoderHal::~SecJpegEncoderHal() +{ + if (t_bFlagCreate == true) { + this->destroy(); + } +} + +int SecJpegEncoderHal::create(void) +{ + if (t_bFlagCreate == true) { + return ERROR_JPEG_DEVICE_ALREADY_CREATE; + } + + int iRet = ERROR_NONE; + + t_iJpegFd = open(JPEG_ENC_NODE, O_RDWR, 0); + + if (t_iJpegFd < 0) { + t_iJpegFd = -1; + JPEG_ERROR_LOG("[%s]: JPEG_ENC_NODE open failed", __func__); + return ERROR_CANNOT_OPEN_JPEG_DEVICE; + } + + if (t_iJpegFd <= 0) { + t_iJpegFd = -1; + JPEG_ERROR_LOG("ERR(%s):JPEG device was closed\n", __func__); + return ERROR_JPEG_DEVICE_ALREADY_CLOSED; + } + + iRet = t_v4l2Querycap(t_iJpegFd); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s]: QUERYCAP failed", __func__); + close(t_iJpegFd); + return ERROR_CANNOT_OPEN_JPEG_DEVICE; + } + + memset(&t_stJpegConfig, 0, sizeof(struct CONFIG)); + memset(&t_stJpegInbuf, 0, sizeof(struct BUFFER)); + memset(&t_stJpegOutbuf, 0, sizeof(struct BUFFER)); + + t_stJpegConfig.mode = MODE_ENCODE; + + t_bFlagCreate = true; + t_bFlagCreateInBuf = false; + t_bFlagCreateOutBuf = false; + t_bFlagExcute = false; + + t_iPlaneNum = 0; + + return ERROR_NONE; +} + +int SecJpegEncoderHal::destroy(void) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_ALREADY_DESTROY; + } + + if (t_iJpegFd > 0) { + struct BUF_INFO stBufInfo; + int iRet = ERROR_NONE; + + if (t_bFlagExcute) { + iRet = t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + } + + if (t_bFlagExcute) { + stBufInfo.numOfPlanes = t_iPlaneNum; + stBufInfo.memory = V4L2_MEMORY_MMAP; + + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); + + stBufInfo.numOfPlanes = NUM_PLANES; + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); + } + + iRet = close(t_iJpegFd); + } + + t_iJpegFd = -1; + t_bFlagCreate = false; + return ERROR_NONE; +} + +int SecJpegEncoderHal::setSize(int iW, int iH) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_NOT_CREATE_YET; + } + + if (iW < 0 || MAX_JPG_WIDTH < iW) { + return ERROR_INVALID_IMAGE_SIZE; + } + + if (iH < 0 || MAX_JPG_HEIGHT < iH) { + return ERROR_INVALID_IMAGE_SIZE; + } + + t_stJpegConfig.width = iW; + t_stJpegConfig.height = iH; + + return ERROR_NONE; +} + +int SecJpegEncoderHal::setJpegConfig(void *pConfig) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_NOT_CREATE_YET; + } + + if (pConfig == NULL) { + return ERROR_JPEG_CONFIG_POINTER_NULL; + } + + memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG)); + + if (t_stJpegConfig.pix.enc_fmt.in_fmt == V4L2_PIX_FMT_NV12) { + t_iPlaneNum = 2; + } else { + t_iPlaneNum = 1; + } + + return ERROR_NONE; +} + +void *SecJpegEncoderHal::getJpegConfig(void) +{ + if (t_bFlagCreate == false) { + return NULL; + } + + return &t_stJpegConfig; +} + +char **SecJpegEncoderHal::getInBuf(int *piInputSize) +{ + if (t_bFlagCreate == false) { + return NULL; + } + + if (t_bFlagCreateInBuf == false) { + + *piInputSize = 0; + return NULL; + } + + for (int i=0;i= 90) + t_stJpegConfig.enc_qual = QUALITY_LEVEL_1; + else if (iV4l2Quality >= 80) + t_stJpegConfig.enc_qual = QUALITY_LEVEL_2; + else if (iV4l2Quality >= 70) + t_stJpegConfig.enc_qual = QUALITY_LEVEL_3; + else + t_stJpegConfig.enc_qual = QUALITY_LEVEL_4; + + return ERROR_NONE; +} + +int SecJpegEncoderHal::getJpegSize(void) +{ + if (t_bFlagCreate == false) { + return 0; + } + + int iSize = t_v4l2GetCtrl(t_iJpegFd, V4L2_CID_CAM_JPEG_ENCODEDSIZE); + + if (iSize < 0) { + JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__); + return 0; + } + + return iSize; +} + +int SecJpegEncoderHal::encode(void) +{ + if (t_bFlagCreate == false) { + return ERROR_JPEG_DEVICE_NOT_CREATE_YET; + } + + struct BUF_INFO stBufInfo; + int iRet = ERROR_NONE; + + t_bFlagExcute = true; + + stBufInfo.numOfPlanes = t_iPlaneNum; + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + stBufInfo.memory = V4L2_MEMORY_USERPTR; + + iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegInbuf); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: Input QBUF failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + + stBufInfo.numOfPlanes = NUM_PLANES; + stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegOutbuf); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: Output QBUF failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + + stBufInfo.numOfPlanes = t_iPlaneNum; + iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: input stream on failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + stBufInfo.numOfPlanes = NUM_PLANES; + iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: output stream on failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + + stBufInfo.numOfPlanes = t_iPlaneNum; + iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: Intput DQBUF failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + stBufInfo.numOfPlanes = NUM_PLANES; + iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP); + if (iRet < 0) { + JPEG_ERROR_LOG("[%s:%d]: Output DQBUF failed", __func__, iRet); + return ERROR_EXCUTE_FAIL; + } + return ERROR_NONE; +} + -- cgit v1.1