From 8b1d71b5f3ab07c3b980666954c7ec9cc049a378 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 24 Mar 2016 10:10:31 +0900 Subject: [PATCH 2/7] Initial version of libomxil-e3250-v4l2 Change-Id: I33fa88ac5cacdfde8c76355f8bced8c835d6fdd8 --- AUTHORS | 1 + COPYING | 203 ++ Makefile.am | 8 + autogen.sh | 6 + config.guess | 1517 ++++++++++ config.sub | 1760 ++++++++++++ configure.ac | 212 ++ exynos/Makefile.am | 1 + exynos/include/csc.h | 379 +++ exynos/include/exynos_format.h | 159 ++ exynos/include/exynos_v4l2.h | 224 ++ exynos/libcsc/Android.mk | 63 + exynos/libcsc/Makefile.am | 12 + exynos/libcsc/csc.c | 790 ++++++ exynos/libcsc/csc_helper.c | 95 + exynos/libv4l2/Android.mk | 35 + exynos/libv4l2/Makefile.am | 9 + exynos/libv4l2/exynos_mc.c | 788 ++++++ exynos/libv4l2/exynos_subdev.c | 379 +++ exynos/libv4l2/exynos_v4l2.c | 798 ++++++ exynos4/Makefile.am | 1 + exynos4/include/ion.h | 162 ++ exynos4/include/swconverter.h | 469 ++++ exynos4/libcodec/Android.mk | 1 + exynos4/libcodec/Makefile.am | 1 + exynos4/libcodec/audio/Android.mk | 7 + exynos4/libcodec/audio/Makefile.am | 1 + exynos4/libcodec/audio/alp/Android.mk | 20 + exynos4/libcodec/audio/alp/Makefile.am | 11 + exynos4/libcodec/audio/alp/dec/srp_api.c | 300 ++ exynos4/libcodec/audio/alp/include/srp_api.h | 82 + exynos4/libcodec/audio/alp/include/srp_error.h | 51 + exynos4/libcodec/audio/alp/include/srp_ioctl.h | 49 + exynos4/libcodec/video/Android.mk | 5 + exynos4/libcodec/video/Makefile.am | 1 + exynos4/libcodec/video/v4l2/Android.mk | 24 + exynos4/libcodec/video/v4l2/Makefile.am | 19 + .../libcodec/video/v4l2/dec/ExynosVideoDecoder.c | 2094 ++++++++++++++ .../libcodec/video/v4l2/enc/ExynosVideoEncoder.c | 2298 +++++++++++++++ .../libcodec/video/v4l2/include/ExynosVideoApi.h | 308 ++ .../libcodec/video/v4l2/include/ExynosVideoDec.h | 50 + .../libcodec/video/v4l2/include/ExynosVideoEnc.h | 47 + exynos4/libion_exynos/Android.mk | 33 + exynos4/libion_exynos/Makefile.am | 9 + exynos4/libion_exynos/libion.c | 131 + exynos4/libswconverter/Android.mk | 31 + exynos4/libswconverter/Makefile.am | 17 + .../libswconverter/csc_ARGB8888_to_YUV420SP_NEON.s | 365 +++ .../libswconverter/csc_interleave_memcpy_neon.s | 120 + .../libswconverter/csc_linear_to_tiled_crop_neon.s | 492 ++++ .../csc_linear_to_tiled_interleave_crop_neon.s | 563 ++++ .../libswconverter/csc_tiled_to_linear_crop_neon.s | 701 +++++ .../csc_tiled_to_linear_deinterleave_crop_neon.s | 786 ++++++ exynos4/libswconverter/swconvertor.c | 1828 ++++++++++++ libomxil-e3250-v4l2.manifest | 5 + omxil-e3250-v4l2.pc.in | 12 + openmax/Android.mk | 42 + openmax/Makefile.am | 1 + openmax/component/Makefile.am | 1 + openmax/component/audio/Makefile.am | 1 + openmax/component/audio/dec/Android.mk | 28 + openmax/component/audio/dec/Exynos_OMX_Adec.c | 1566 +++++++++++ openmax/component/audio/dec/Exynos_OMX_Adec.h | 139 + openmax/component/audio/dec/Makefile.am | 19 + openmax/component/audio/dec/mp3/Android.mk | 38 + .../component/audio/dec/mp3/Exynos_OMX_Mp3dec.c | 955 +++++++ .../component/audio/dec/mp3/Exynos_OMX_Mp3dec.h | 68 + openmax/component/audio/dec/mp3/Makefile.am | 23 + openmax/component/audio/dec/mp3/library_register.c | 58 + openmax/component/audio/dec/mp3/library_register.h | 54 + openmax/component/common/Android.mk | 56 + .../component/common/Exynos_OMX_Basecomponent.c | 1582 +++++++++++ .../component/common/Exynos_OMX_Basecomponent.h | 151 + openmax/component/common/Exynos_OMX_Baseport.c | 933 +++++++ openmax/component/common/Exynos_OMX_Baseport.h | 215 ++ .../component/common/Exynos_OMX_Resourcemanager.c | 482 ++++ .../component/common/Exynos_OMX_Resourcemanager.h | 59 + openmax/component/common/Makefile.am | 24 + openmax/component/video/Makefile.am | 1 + openmax/component/video/dec/Android.mk | 40 + openmax/component/video/dec/Exynos_OMX_Vdec.c | 1342 +++++++++ openmax/component/video/dec/Exynos_OMX_Vdec.h | 175 ++ .../component/video/dec/Exynos_OMX_VdecControl.c | 1584 +++++++++++ .../component/video/dec/Exynos_OMX_VdecControl.h | 110 + openmax/component/video/dec/Makefile.am | 28 + openmax/component/video/dec/h264/Android.mk | 52 + .../component/video/dec/h264/Exynos_OMX_H264dec.c | 2847 +++++++++++++++++++ .../component/video/dec/h264/Exynos_OMX_H264dec.h | 81 + openmax/component/video/dec/h264/Makefile.am | 48 + .../component/video/dec/h264/library_register.c | 59 + .../component/video/dec/h264/library_register.h | 56 + openmax/component/video/dec/mpeg2/Android.mk | 51 + .../video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c | 2129 ++++++++++++++ .../video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h | 81 + openmax/component/video/dec/mpeg2/Makefile.am | 40 + .../component/video/dec/mpeg2/library_register.c | 58 + .../component/video/dec/mpeg2/library_register.h | 55 + openmax/component/video/dec/mpeg4/Android.mk | 48 + .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 2947 ++++++++++++++++++++ .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h | 114 + openmax/component/video/dec/mpeg4/Makefile.am | 40 + .../component/video/dec/mpeg4/library_register.c | 64 + .../component/video/dec/mpeg4/library_register.h | 59 + openmax/component/video/dec/vc1/Android.mk | 48 + .../component/video/dec/vc1/Exynos_OMX_Wmvdec.c | 2815 +++++++++++++++++++ .../component/video/dec/vc1/Exynos_OMX_Wmvdec.h | 119 + openmax/component/video/dec/vc1/Makefile.am | 40 + openmax/component/video/dec/vc1/library_register.c | 58 + openmax/component/video/dec/vc1/library_register.h | 54 + openmax/component/video/enc/Android.mk | 47 + openmax/component/video/enc/Exynos_OMX_Venc.c | 1167 ++++++++ openmax/component/video/enc/Exynos_OMX_Venc.h | 153 + .../component/video/enc/Exynos_OMX_VencControl.c | 1849 ++++++++++++ .../component/video/enc/Exynos_OMX_VencControl.h | 100 + openmax/component/video/enc/Makefile.am | 30 + openmax/component/video/enc/h264/Android.mk | 49 + .../component/video/enc/h264/Exynos_OMX_H264enc.c | 2580 +++++++++++++++++ .../component/video/enc/h264/Exynos_OMX_H264enc.h | 87 + openmax/component/video/enc/h264/Makefile.am | 35 + .../component/video/enc/h264/library_register.c | 55 + .../component/video/enc/h264/library_register.h | 55 + openmax/component/video/enc/mpeg4/Android.mk | 48 + .../video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c | 2721 ++++++++++++++++++ .../video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h | 86 + openmax/component/video/enc/mpeg4/Makefile.am | 36 + .../component/video/enc/mpeg4/library_register.c | 62 + .../component/video/enc/mpeg4/library_register.h | 59 + openmax/core/Android.mk | 34 + openmax/core/Exynos_OMX_Component_Register.c | 264 ++ openmax/core/Exynos_OMX_Component_Register.h | 75 + openmax/core/Exynos_OMX_Core.c | 364 +++ openmax/core/Exynos_OMX_Core.h | 89 + openmax/core/Makefile.am | 29 + openmax/include/exynos/Exynos_OMX_Def.h | 293 ++ openmax/include/exynos/Exynos_OMX_Macros.h | 72 + openmax/include/khronos/OMX_Audio.h | 1311 +++++++++ openmax/include/khronos/OMX_Component.h | 579 ++++ openmax/include/khronos/OMX_ContentPipe.h | 195 ++ openmax/include/khronos/OMX_Core.h | 1431 ++++++++++ openmax/include/khronos/OMX_IVCommon.h | 920 ++++++ openmax/include/khronos/OMX_Image.h | 328 +++ openmax/include/khronos/OMX_Index.h | 258 ++ openmax/include/khronos/OMX_Other.h | 337 +++ openmax/include/khronos/OMX_Types.h | 347 +++ openmax/include/khronos/OMX_Video.h | 1060 +++++++ openmax/osal/Android.mk | 55 + openmax/osal/Exynos_OSAL_ETC.c | 237 ++ openmax/osal/Exynos_OSAL_ETC.h | 66 + openmax/osal/Exynos_OSAL_Event.c | 217 ++ openmax/osal/Exynos_OSAL_Event.h | 61 + openmax/osal/Exynos_OSAL_Library.c | 54 + openmax/osal/Exynos_OSAL_Library.h | 46 + openmax/osal/Exynos_OSAL_Log.c | 115 + openmax/osal/Exynos_OSAL_Log.h | 108 + openmax/osal/Exynos_OSAL_Memory.c | 79 + openmax/osal/Exynos_OSAL_Memory.h | 48 + openmax/osal/Exynos_OSAL_Mutex.c | 92 + openmax/osal/Exynos_OSAL_Mutex.h | 47 + openmax/osal/Exynos_OSAL_Platform_Specific.c | 751 +++++ openmax/osal/Exynos_OSAL_Platform_Specific.h | 100 + openmax/osal/Exynos_OSAL_Queue.c | 195 ++ openmax/osal/Exynos_OSAL_Queue.h | 68 + openmax/osal/Exynos_OSAL_Semaphore.c | 151 + openmax/osal/Exynos_OSAL_Semaphore.h | 50 + openmax/osal/Exynos_OSAL_SharedMemory.c | 489 ++++ openmax/osal/Exynos_OSAL_SharedMemory.h | 56 + openmax/osal/Exynos_OSAL_Thread.c | 158 ++ openmax/osal/Exynos_OSAL_Thread.h | 48 + openmax/osal/Makefile.am | 40 + packaging/libomxil-e3250-v4l2.spec | 74 + srp.pc.in | 12 + tool/NV12T_converter | Bin 0 -> 16224 bytes tool/NV12T_converter.c | 208 ++ 173 files changed, 61101 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure.ac create mode 100644 exynos/Makefile.am create mode 100644 exynos/include/csc.h create mode 100644 exynos/include/exynos_format.h create mode 100644 exynos/include/exynos_v4l2.h create mode 100644 exynos/libcsc/Android.mk create mode 100644 exynos/libcsc/Makefile.am create mode 100644 exynos/libcsc/csc.c create mode 100644 exynos/libcsc/csc_helper.c create mode 100644 exynos/libv4l2/Android.mk create mode 100644 exynos/libv4l2/Makefile.am create mode 100644 exynos/libv4l2/exynos_mc.c create mode 100644 exynos/libv4l2/exynos_subdev.c create mode 100644 exynos/libv4l2/exynos_v4l2.c create mode 100644 exynos4/Makefile.am create mode 100644 exynos4/include/ion.h create mode 100644 exynos4/include/swconverter.h create mode 100644 exynos4/libcodec/Android.mk create mode 100644 exynos4/libcodec/Makefile.am create mode 100644 exynos4/libcodec/audio/Android.mk create mode 100644 exynos4/libcodec/audio/Makefile.am create mode 100644 exynos4/libcodec/audio/alp/Android.mk create mode 100644 exynos4/libcodec/audio/alp/Makefile.am create mode 100644 exynos4/libcodec/audio/alp/dec/srp_api.c create mode 100644 exynos4/libcodec/audio/alp/include/srp_api.h create mode 100644 exynos4/libcodec/audio/alp/include/srp_error.h create mode 100644 exynos4/libcodec/audio/alp/include/srp_ioctl.h create mode 100644 exynos4/libcodec/video/Android.mk create mode 100644 exynos4/libcodec/video/Makefile.am create mode 100644 exynos4/libcodec/video/v4l2/Android.mk create mode 100644 exynos4/libcodec/video/v4l2/Makefile.am create mode 100755 exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c create mode 100755 exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c create mode 100644 exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h create mode 100644 exynos4/libcodec/video/v4l2/include/ExynosVideoDec.h create mode 100644 exynos4/libcodec/video/v4l2/include/ExynosVideoEnc.h create mode 100644 exynos4/libion_exynos/Android.mk create mode 100644 exynos4/libion_exynos/Makefile.am create mode 100644 exynos4/libion_exynos/libion.c create mode 100644 exynos4/libswconverter/Android.mk create mode 100644 exynos4/libswconverter/Makefile.am create mode 100644 exynos4/libswconverter/csc_ARGB8888_to_YUV420SP_NEON.s create mode 100644 exynos4/libswconverter/csc_interleave_memcpy_neon.s create mode 100644 exynos4/libswconverter/csc_linear_to_tiled_crop_neon.s create mode 100644 exynos4/libswconverter/csc_linear_to_tiled_interleave_crop_neon.s create mode 100644 exynos4/libswconverter/csc_tiled_to_linear_crop_neon.s create mode 100644 exynos4/libswconverter/csc_tiled_to_linear_deinterleave_crop_neon.s create mode 100644 exynos4/libswconverter/swconvertor.c create mode 100755 libomxil-e3250-v4l2.manifest create mode 100644 omxil-e3250-v4l2.pc.in create mode 100644 openmax/Android.mk create mode 100644 openmax/Makefile.am create mode 100644 openmax/component/Makefile.am create mode 100644 openmax/component/audio/Makefile.am create mode 100644 openmax/component/audio/dec/Android.mk create mode 100755 openmax/component/audio/dec/Exynos_OMX_Adec.c create mode 100644 openmax/component/audio/dec/Exynos_OMX_Adec.h create mode 100644 openmax/component/audio/dec/Makefile.am create mode 100644 openmax/component/audio/dec/mp3/Android.mk create mode 100644 openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.c create mode 100644 openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.h create mode 100644 openmax/component/audio/dec/mp3/Makefile.am create mode 100644 openmax/component/audio/dec/mp3/library_register.c create mode 100644 openmax/component/audio/dec/mp3/library_register.h create mode 100644 openmax/component/common/Android.mk create mode 100755 openmax/component/common/Exynos_OMX_Basecomponent.c create mode 100644 openmax/component/common/Exynos_OMX_Basecomponent.h create mode 100755 openmax/component/common/Exynos_OMX_Baseport.c create mode 100644 openmax/component/common/Exynos_OMX_Baseport.h create mode 100644 openmax/component/common/Exynos_OMX_Resourcemanager.c create mode 100644 openmax/component/common/Exynos_OMX_Resourcemanager.h create mode 100644 openmax/component/common/Makefile.am create mode 100644 openmax/component/video/Makefile.am create mode 100644 openmax/component/video/dec/Android.mk create mode 100755 openmax/component/video/dec/Exynos_OMX_Vdec.c create mode 100755 openmax/component/video/dec/Exynos_OMX_Vdec.h create mode 100644 openmax/component/video/dec/Exynos_OMX_VdecControl.c create mode 100644 openmax/component/video/dec/Exynos_OMX_VdecControl.h create mode 100644 openmax/component/video/dec/Makefile.am create mode 100644 openmax/component/video/dec/h264/Android.mk create mode 100755 openmax/component/video/dec/h264/Exynos_OMX_H264dec.c create mode 100644 openmax/component/video/dec/h264/Exynos_OMX_H264dec.h create mode 100644 openmax/component/video/dec/h264/Makefile.am create mode 100644 openmax/component/video/dec/h264/library_register.c create mode 100644 openmax/component/video/dec/h264/library_register.h create mode 100644 openmax/component/video/dec/mpeg2/Android.mk create mode 100644 openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c create mode 100644 openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h create mode 100644 openmax/component/video/dec/mpeg2/Makefile.am create mode 100644 openmax/component/video/dec/mpeg2/library_register.c create mode 100644 openmax/component/video/dec/mpeg2/library_register.h create mode 100644 openmax/component/video/dec/mpeg4/Android.mk create mode 100644 openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c create mode 100644 openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h create mode 100644 openmax/component/video/dec/mpeg4/Makefile.am create mode 100644 openmax/component/video/dec/mpeg4/library_register.c create mode 100644 openmax/component/video/dec/mpeg4/library_register.h create mode 100644 openmax/component/video/dec/vc1/Android.mk create mode 100644 openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c create mode 100644 openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h create mode 100644 openmax/component/video/dec/vc1/Makefile.am create mode 100644 openmax/component/video/dec/vc1/library_register.c create mode 100644 openmax/component/video/dec/vc1/library_register.h create mode 100644 openmax/component/video/enc/Android.mk create mode 100644 openmax/component/video/enc/Exynos_OMX_Venc.c create mode 100644 openmax/component/video/enc/Exynos_OMX_Venc.h create mode 100644 openmax/component/video/enc/Exynos_OMX_VencControl.c create mode 100644 openmax/component/video/enc/Exynos_OMX_VencControl.h create mode 100644 openmax/component/video/enc/Makefile.am create mode 100644 openmax/component/video/enc/h264/Android.mk create mode 100644 openmax/component/video/enc/h264/Exynos_OMX_H264enc.c create mode 100644 openmax/component/video/enc/h264/Exynos_OMX_H264enc.h create mode 100644 openmax/component/video/enc/h264/Makefile.am create mode 100644 openmax/component/video/enc/h264/library_register.c create mode 100644 openmax/component/video/enc/h264/library_register.h create mode 100644 openmax/component/video/enc/mpeg4/Android.mk create mode 100644 openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c create mode 100644 openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h create mode 100644 openmax/component/video/enc/mpeg4/Makefile.am create mode 100644 openmax/component/video/enc/mpeg4/library_register.c create mode 100644 openmax/component/video/enc/mpeg4/library_register.h create mode 100644 openmax/core/Android.mk create mode 100644 openmax/core/Exynos_OMX_Component_Register.c create mode 100644 openmax/core/Exynos_OMX_Component_Register.h create mode 100644 openmax/core/Exynos_OMX_Core.c create mode 100644 openmax/core/Exynos_OMX_Core.h create mode 100644 openmax/core/Makefile.am create mode 100644 openmax/include/exynos/Exynos_OMX_Def.h create mode 100644 openmax/include/exynos/Exynos_OMX_Macros.h create mode 100644 openmax/include/khronos/OMX_Audio.h create mode 100644 openmax/include/khronos/OMX_Component.h create mode 100644 openmax/include/khronos/OMX_ContentPipe.h create mode 100644 openmax/include/khronos/OMX_Core.h create mode 100644 openmax/include/khronos/OMX_IVCommon.h create mode 100644 openmax/include/khronos/OMX_Image.h create mode 100644 openmax/include/khronos/OMX_Index.h create mode 100644 openmax/include/khronos/OMX_Other.h create mode 100644 openmax/include/khronos/OMX_Types.h create mode 100644 openmax/include/khronos/OMX_Video.h create mode 100644 openmax/osal/Android.mk create mode 100644 openmax/osal/Exynos_OSAL_ETC.c create mode 100644 openmax/osal/Exynos_OSAL_ETC.h create mode 100644 openmax/osal/Exynos_OSAL_Event.c create mode 100644 openmax/osal/Exynos_OSAL_Event.h create mode 100644 openmax/osal/Exynos_OSAL_Library.c create mode 100644 openmax/osal/Exynos_OSAL_Library.h create mode 100644 openmax/osal/Exynos_OSAL_Log.c create mode 100644 openmax/osal/Exynos_OSAL_Log.h create mode 100644 openmax/osal/Exynos_OSAL_Memory.c create mode 100644 openmax/osal/Exynos_OSAL_Memory.h create mode 100644 openmax/osal/Exynos_OSAL_Mutex.c create mode 100644 openmax/osal/Exynos_OSAL_Mutex.h create mode 100755 openmax/osal/Exynos_OSAL_Platform_Specific.c create mode 100755 openmax/osal/Exynos_OSAL_Platform_Specific.h create mode 100644 openmax/osal/Exynos_OSAL_Queue.c create mode 100644 openmax/osal/Exynos_OSAL_Queue.h create mode 100644 openmax/osal/Exynos_OSAL_Semaphore.c create mode 100644 openmax/osal/Exynos_OSAL_Semaphore.h create mode 100644 openmax/osal/Exynos_OSAL_SharedMemory.c create mode 100644 openmax/osal/Exynos_OSAL_SharedMemory.h create mode 100644 openmax/osal/Exynos_OSAL_Thread.c create mode 100644 openmax/osal/Exynos_OSAL_Thread.h create mode 100644 openmax/osal/Makefile.am create mode 100755 packaging/libomxil-e3250-v4l2.spec create mode 100644 srp.pc.in create mode 100755 tool/NV12T_converter create mode 100755 tool/NV12T_converter.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..47f6444 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Hyunseok Lee diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4a67574 --- /dev/null +++ b/COPYING @@ -0,0 +1,203 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..1722972 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = exynos4 exynos openmax + +pcfiles = omxil-e3250-v4l2.pc \ + srp.pc +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = $(pcfiles) +EXTRA_DIST = $(pcfiles) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..a2bf629 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +aclocal +libtoolize --copy +autoheader +autoconf +automake --add-missing --copy --foreign +#./configure --with-xo-machine=W1 diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..40eaed4 --- /dev/null +++ b/config.guess @@ -0,0 +1,1517 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-05-11' + +# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-tilera-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..30fdca8 --- /dev/null +++ b/config.sub @@ -0,0 +1,1760 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-03-23' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..4a336a0 --- /dev/null +++ b/configure.ac @@ -0,0 +1,212 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.65]) +AC_INIT([libomxil-e3250], [0.1]) +AM_INIT_AUTOMAKE([tar-ustar]) +#AC_CONFIG_HEADERS([config.h]) + +# Set to 'm4' the directory where the extra autoconf macros are stored +AC_CONFIG_MACRO_DIR([m4]) + +AC_CONFIG_FILES([ + omxil-e3250-v4l2.pc + srp.pc + Makefile + exynos4/Makefile + exynos4/libcodec/Makefile + exynos4/libcodec/audio/Makefile + exynos4/libcodec/audio/alp/Makefile + exynos4/libcodec/video/Makefile + exynos4/libcodec/video/v4l2/Makefile + exynos4/libion_exynos/Makefile + exynos4/libswconverter/Makefile + exynos/Makefile + exynos/libv4l2/Makefile + exynos/libcsc/Makefile + openmax/Makefile + openmax/osal/Makefile + openmax/core/Makefile + openmax/component/Makefile + openmax/component/common/Makefile + openmax/component/audio/Makefile + openmax/component/audio/dec/Makefile + openmax/component/audio/dec/mp3/Makefile + openmax/component/video/Makefile + openmax/component/video/dec/Makefile + openmax/component/video/dec/h264/Makefile + openmax/component/video/dec/mpeg2/Makefile + openmax/component/video/dec/mpeg4/Makefile + openmax/component/video/dec/vc1/Makefile + openmax/component/video/enc/Makefile + openmax/component/video/enc/h264/Makefile + openmax/component/video/enc/mpeg4/Makefile +]) + +# Checks for programs. +AC_PROG_CC +AM_PROG_AS + +# Check for libtool +AM_PROG_LIBTOOL + +# Checks for libraries. + +# Check for pthread +AC_SEARCH_LIBS([pthread_create], [pthread], [], [AC_MSG_ERROR([pthread is required])]) + +# Check for libdl +AC_SEARCH_LIBS([dlopen], [dl], [], [AC_MSG_ERROR([libdl is required])]) + +# Checks for header files. +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/ioctl.h sys/time.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_MMAP +AC_FUNC_REALLOC +AC_CHECK_FUNCS([gettimeofday memmove memset munmap]) + +AC_DEFINE([SLP_PLATFORM]) +AC_DEFINE([USE_IMMEDIATE_DISPLAY]) + +dnl use dlog ------------------------------------------------------------------ +AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]), + [ + case "${enableval}" in + yes) USE_DLOG=yes ;; + no) USE_DLOG=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;; + esac + ],[USE_DLOG=no]) + +if test "x$USE_DLOG" = "xyes"; then + PKG_CHECK_MODULES(DLOG, dlog) + AC_SUBST(DLOG_CFLAGS) + AC_SUBST(DLOG_LIBS) +fi +AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes") +dnl end ----------------------------------------------------------------------- + +dnl use mm-ta ------------------------------------------------------------------ +AC_ARG_ENABLE(mm-ta, AC_HELP_STRING([--enable-mm-ta], [using mm-ta]), + [ + case "${enableval}" in + yes) USE_MMTA=yes ;; + no) USE_MMTA=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-mm-ta) ;; + esac + ],[USE_MMTA=no]) + +if test "x$USE_MMTA" = "xyes"; then + PKG_CHECK_MODULES(MMTA, mm-ta) + AC_SUBST(MMTA_CFLAGS) + AC_SUBST(MMTA_LIBS) +fi +AM_CONDITIONAL(USE_MMTA, test "x$USE_MMTA" = "xyes") +dnl end ----------------------------------------------------------------------- +AC_ARG_ENABLE([exynos3250], AC_HELP_STRING([--enable-exynos3250], [Enable exynos3250 specific code]), + [ + case "${enableval}" in + yes) EXYNOS_3250=yes ;; + no) EXYNOS_3250=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-exynos3250) ;; + esac + ], + [EXYNOS_3250=no]) +AM_CONDITIONAL([EXYNOS_3250], [test "x$EXYNOS_3250" = "xyes"]) + +AC_ARG_ENABLE(s3dsupport, AC_HELP_STRING([--enable-s3dsupport], [use s3d support]), + [ + case "${enableval}" in + yes) BOARD_USE_S3D_SUPPORT=yes ;; + no) BOARD_USE_S3D_SUPPORT=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-s3dsupport) ;; + esac + ], + [BOARD_USE_S3D_SUPPORT=no]) +AM_CONDITIONAL([BOARD_USE_S3D_SUPPORT], [test "x$BOARD_USE_S3D_SUPPORT" = "xyes"]) + +AC_ARG_ENABLE(mfcfps, AC_HELP_STRING([--enable-mfc-fps], [use mfc fps]), + [ + case "${enableval}" in + yes) BOARD_USE_MFC_FPS=yes ;; + no) BOARD_USE_MFC_FPS=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-mfc-fps) ;; + esac + ], + [BOARD_USE_MFC_FPS=no]) +AM_CONDITIONAL([BOARD_USE_MFC_FPS], [test "x$BOARD_USE_MFC_FPS" = "xyes"]) + +AC_ARG_ENABLE(blockmodeprocess, AC_HELP_STRING([--enable-nonblock-mode-process], [non-block mode process]), + [ + case "${enableval}" in + yes) BOARD_NONBLOCK_MODE_PROCESS=yes ;; + no) BOARD_NONBLOCK_MODE_PROCESS=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-nonblock-mode-process) ;; + esac + ], + [BOARD_NONBLOCK_MODE_PROCESS=yes]) +AM_CONDITIONAL([BOARD_NONBLOCK_MODE_PROCESS], [test "x$BOARD_NONBLOCK_MODE_PROCESS" = "xyes"]) + +AC_ARG_ENABLE(anb, AC_HELP_STRING([--enable-anb], [use anb]), + [ + case "${enableval}" in + yes) BOARD_USE_ANB=yes ;; + no) BOARD_USE_ANB=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-anb) ;; + esac + ], + [BOARD_USE_ANB=no]) +AM_CONDITIONAL([BOARD_USE_ANB], [test "x$BOARD_USE_ANB" = "xyes"]) + +AC_ARG_ENABLE(metadatabuffertype, AC_HELP_STRING([--enable-metadata-buffertype], [use metadata buffertype]), + [ + case "${enableval}" in + yes) BOARD_USE_METADATABUFFERTYPE=yes ;; + no) BOARD_USE_METADATABUFFERTYPE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-metadata-buffertype) ;; + esac + ], + [BOARD_USE_METADATABUFFERTYPE=no]) +AM_CONDITIONAL([BOARD_USE_METADATABUFFERTYPE], [test "x$BOARD_USE_METADATABUFFERTYPE" = "xyes"]) + +AC_ARG_ENABLE(storemetadata, AC_HELP_STRING([--enable-store-metadata], [use store metadata]), + [ + case "${enableval}" in + yes) BOARD_USE_STOREMETADATA=yes ;; + no) BOARD_USE_STOREMETADATA=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-store-metadata) ;; + esac + ], + [BOARD_USE_STOREMETADATA=no]) +AM_CONDITIONAL([BOARD_USE_STOREMETADATA], [test "x$BOARD_USE_STOREMETADATA" = "xyes"]) + +AC_ARG_ENABLE(dmabuf, AC_HELP_STRING([--enable-use-dmabuf], [use dma buf]), + [ + case "${enableval}" in + yes) BOARD_USE_DMA_BUF=yes ;; + no) BOARD_USE_DMA_BUF=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-use-dambuf) ;; + esac + ], + [BOARD_USE_DMA_BUF=no]) +AM_CONDITIONAL([BOARD_USE_DMA_BUF], [test "x$BOARD_USE_DMA_BUF" = "xyes"]) + +AC_ARG_ENABLE(drm, AC_HELP_STRING([--enable-use-drm], [use drm]), + [ + case "${enableval}" in + yes) BOARD_USE_DRM=yes ;; + no) BOARD_USE_DRM=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-use-drm) ;; + esac + ], + [BOARD_USE_DRM=no]) +AM_CONDITIONAL([BOARD_USE_DRM], [test "x$BOARD_USE_DRM" = "xyes"]) + +AC_OUTPUT diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..f18d464 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = libv4l2 libcsc diff --git a/exynos/include/csc.h b/exynos/include/csc.h new file mode 100644 index 0000000..5eb4d2a --- /dev/null +++ b/exynos/include/csc.h @@ -0,0 +1,379 @@ +/* + * 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.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; + +typedef enum _CSC_HW_PROPERTY_TYPE { + CSC_HW_PROPERTY_FIXED_NODE = 0, + CSC_HW_PROPERTY_MODE_DRM, +} CSC_HW_PROPERTY_TYPE; + +/* + * 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); + +/* + * Set hw property + * + * @param handle + * CSC handle[in] + * + * @param property + * csc hw property[in] + * + * @param value + * csc hw property value[in] + * + * @return + * csc handle + */ +CSC_ERRORCODE csc_set_hw_property( + void *handle, + CSC_HW_PROPERTY_TYPE property, + int value); + +/* + * 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/exynos/include/exynos_format.h b/exynos/include/exynos_format.h new file mode 100644 index 0000000..86062a2 --- /dev/null +++ b/exynos/include/exynos_format.h @@ -0,0 +1,159 @@ +/* + * 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 _EXYNOS_FORMAT_H_ +#define _EXYNOS_FORMAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +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, + 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, + 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_MAX +}; + +struct ADDRS { + unsigned int addr_y; + unsigned int addr_cbcr; + unsigned int buf_idx; + unsigned int reserved; +}; + +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') + +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#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) + +/* + * Convert hal_pixel_format to v4l2_pixel_format. + * + * @param hal_pixel_format + * hal_pixel_format[in] + * + * @return + * v4l2_pixel_format + */ +int HAL_PIXEL_FORMAT_2_V4L2_PIX( + int hal_pixel_format); + +/* + * Convert v4l2_pixel_format to hal_pixel_format. + * + * @param v4l2_pixel_format + * v4l2_pixel_format[in] + * + * @return + * hal_pixel_format + */ +int V4L2_PIX_2_HAL_PIXEL_FORMAT( + int v4l2_pixel_format); + +/* + * Get frame_size of hal_pixel_format. + * + * @param hal_pixel_format + * hal_pixel_format[in] + * + * @param width + * width[in] + * + * @param height + * height[in] + * + * @return + * frame_size + */ +unsigned int FRAME_SIZE( + int hal_pixel_format, + int width, + int height); + +/* + * Get bpp and plane of v4l2_pixel_format. + * + * @param v4l2_pixel_format + * v4l2_pixel_format[in] + * + * @param bpp + * address of bpp[out] + * + * @param planes + * address of planes[out] + * + * @return + * error code + */ +int V4L2_PIX_2_YUV_INFO( + unsigned int v4l2_pixel_format, + unsigned int *bpp, + unsigned int *planes); + +/* + * Get bpp of v4l2_pixel_format. + * + * @param v4l2_pixel_format + * v4l2_pixel_format[in] + * + * @return + * bpp + */ +unsigned int get_yuv_bpp( + unsigned int v4l2_pixel_format); + +/* + * Get plane of v4l2_pixel_format. + * + * @param v4l2_pixel_format + * v4l2_pixel_format[in] + * + * @return + * num of plane + */ +unsigned int get_yuv_planes( + unsigned int v4l2_pixel_format); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exynos/include/exynos_v4l2.h b/exynos/include/exynos_v4l2.h new file mode 100644 index 0000000..2abbb5c --- /dev/null +++ b/exynos/include/exynos_v4l2.h @@ -0,0 +1,224 @@ +/* + * 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 exynos_v4l2.h + * \brief header file for libv4l2 + * \author Jinsung Yang (jsgood.yang@samsung.com) + * \date 2011/12/15 + * + * Revision History: + * - 2011/12/15 : Jinsung Yang (jsgood.yang@samsung.com) \n + * Initial version + * + */ + +/*! + * \defgroup exynos_v4l2 + * \brief API for v4l2 + * \addtogroup Exynos + */ + +#ifndef __EXYNOS_LIB_V4L2_H__ +#define __EXYNOS_LIB_V4L2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* V4L2 */ +#include +#ifdef SLP_PLATFORM +#include +#include +#else +#include "videodev2.h" /* vendor specific videodev2.h */ +#include "videodev2_exynos_media.h" +#endif + +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_open(const char *filename, int oflag, ...); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_open_devname(const char *devname, int oflag, ...); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_close(int fd); +/*! \ingroup exynos_v4l2 */ +bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_input(int fd, int index); +/*! \ingroup exynos_v4l2 */ +bool exynos_v4l2_querycap(int fd, unsigned int need_caps); +/*! \ingroup exynos_v4l2 */ +bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf); +#ifdef SLP_PLATFORM +int exynos_v4l2_expbuf(int fd, int *buf_fd, __u32 mem_offset); +#endif +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl); +/*! \ingroup exynos_v4l2 */ +int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl); + +/* V4L2_SUBDEV */ +#ifndef SLP_PLATFORM /* build env */ +#include +#else + +#include + +#endif + +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_open(const char *filename, int oflag, ...); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_open_devname(const char *devname, int oflag, ...); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_enum_frame_size(int fd, struct v4l2_subdev_frame_size_enum *frame_size_enum); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_g_fmt(int fd, struct v4l2_subdev_format *fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_s_fmt(int fd, struct v4l2_subdev_format *fmt); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_g_crop(int fd, struct v4l2_subdev_crop *crop); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_s_crop(int fd, struct v4l2_subdev_crop *crop); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_enum_frame_interval(int fd, struct v4l2_subdev_frame_interval_enum *frame_internval_enum); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_g_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval_enum); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_s_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval_enum); +/*! \ingroup exynos_v4l2 */ +int exynos_subdev_enum_mbus_code(int fd, struct v4l2_subdev_mbus_code_enum *mbus_code_enum); + +/* MEDIA CONTORLLER */ +#ifndef SLP_PLATFORM /* build env */ +#include +#else + +//#include +#include + +#endif + +/*! media_link + * \ingroup exynos_v4l2 + */ +struct media_link { + struct media_pad *source; + struct media_pad *sink; + struct media_link *twin; + __u32 flags; + __u32 padding[3]; +}; + +/*! media_link + * \ingroup exynos_v4l2 + */ +struct media_pad { + struct media_entity *entity; + __u32 index; + __u32 flags; + __u32 padding[3]; +}; + +/*! media_link + * \ingroup exynos_v4l2 + */ +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]; +}; + +/*! media_link + * \ingroup exynos_v4l2 + */ +struct media_device { + int fd; + struct media_entity *entities; + unsigned int entities_count; + void (*debug_handler)(void *, ...); + void *debug_priv; + __u32 padding[6]; +}; + +/*! \ingroup exynos_v4l2 */ +struct media_device *exynos_media_open(const char *filename); +/*! \ingroup exynos_v4l2 */ +void exynos_media_close(struct media_device *media); +/*! \ingroup exynos_v4l2 */ +struct media_pad *exynos_media_entity_remote_source(struct media_pad *pad); +/*! \ingroup exynos_v4l2 */ +struct media_entity *exynos_media_get_entity_by_name(struct media_device *media, const char *name, size_t length); +/*! \ingroup exynos_v4l2 */ +struct media_entity *exynos_media_get_entity_by_id(struct media_device *media, __u32 id); +/*! \ingroup exynos_v4l2 */ +int exynos_media_setup_link(struct media_device *media, struct media_pad *source, struct media_pad *sink, __u32 flags); +/*! \ingroup exynos_v4l2 */ +int exynos_media_reset_links(struct media_device *media); +/*! \ingroup exynos_v4l2 */ +struct media_pad *exynos_media_parse_pad(struct media_device *media, const char *p, char **endp); +/*! \ingroup exynos_v4l2 */ +struct media_link *exynos_media_parse_link(struct media_device *media, const char *p, char **endp); +/*! \ingroup exynos_v4l2 */ +int exynos_media_parse_setup_link(struct media_device *media, const char *p, char **endp); +/*! \ingroup exynos_v4l2 */ +int exynos_media_parse_setup_links(struct media_device *media, const char *p); + +#ifdef __cplusplus +} +#endif + +#endif /* __EXYNOS_LIB_V4L2_H__ */ diff --git a/exynos/libcsc/Android.mk b/exynos/libcsc/Android.mk new file mode 100644 index 0000000..36ebabe --- /dev/null +++ b/exynos/libcsc/Android.mk @@ -0,0 +1,63 @@ +LOCAL_PATH := $(call my-dir) + +OMX_NAME := exynos + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + csc_helper.c + +LOCAL_C_INCLUDES := \ + system/core/include \ + $(LOCAL_PATH)/../../openmax/include/khronos \ + $(LOCAL_PATH)/../../openmax/include/$(OMX_NAME) \ + hardware/samsung_slsi/exynos5/include \ + hardware/samsung_slsi/exynos/include + +LOCAL_CFLAGS := \ + -DUSE_SAMSUNG_COLORFORMAT \ + -DEXYNOS_OMX + +LOCAL_MODULE := libcsc_helper +LOCAL_MODULE_TAGS := optional +LOCAL_STATIC_LIBRARIES := liblog + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + csc.c + +LOCAL_C_INCLUDES := \ + hardware/samsung_slsi/exynos5/include \ + $(LOCAL_PATH)/../../openmax/include/khronos \ + $(LOCAL_PATH)/../../openmax/include/$(OMX_NAME) \ + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) + +LOCAL_CFLAGS := + +LOCAL_MODULE := libcsc + +LOCAL_PRELINK_MODULE := false + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libswconverter +LOCAL_WHOLE_STATIC_LIBRARIES := libcsc_helper +LOCAL_SHARED_LIBRARIES := liblog + +LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../include + +LOCAL_CFLAGS += -DUSE_ION +LOCAL_SHARED_LIBRARIES += libion_exynos + +LOCAL_CFLAGS += -DEXYNOS_OMX + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/libcsc/Makefile.am b/exynos/libcsc/Makefile.am new file mode 100644 index 0000000..ec268f1 --- /dev/null +++ b/exynos/libcsc/Makefile.am @@ -0,0 +1,12 @@ +lib_LTLIBRARIES = libcsc.la + +libcsc_la_SOURCES = csc.c \ + csc_helper.c + +libcsc_la_LIBADD = $(top_builddir)/exynos4/libswconverter/libswconverter.la + +libcsc_la_CFLAGS = -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/exynos4/include diff --git a/exynos/libcsc/csc.c b/exynos/libcsc/csc.c new file mode 100644 index 0000000..970f1ad --- /dev/null +++ b/exynos/libcsc/csc.c @@ -0,0 +1,790 @@ +/* + * + * 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" +#ifndef SLP_PLATFORM /* build env */ +#include +#endif + +#include +#include +#ifndef SLP_PLATFORM /* build env */ +#include +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + + +#include "csc.h" +#include "exynos_format.h" +#include "swconverter.h" + +#ifdef SLP_PLATFORM /* build env */ +#define EXYNOS_OMX +#endif + +#ifdef EXYNOS_OMX +#include "Exynos_OMX_Def.h" +#else +#include "SEC_OMX_Def.h" +#endif + +#ifdef ENABLE_FIMC +#include "hwconverter_wrapper.h" +#endif + +#ifdef ENABLE_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; + unsigned int mode_drm; +} CSC_FORMAT; + +typedef struct _CSC_BUFFER { + unsigned char *planes[CSC_MAX_PLANES]; + int ion_fd; +} CSC_BUFFER; + +typedef struct _CSC_HW_PROPERTY { + int fixed_node; + int mode_drm; +} CSC_HW_PROPERTY; + +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_HW_PROPERTY hw_property; +} CSC_HANDLE; + +/* 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_NEON( + (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: + ALOGE("dst_format 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: + ALOGE("dst_format 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; +#ifdef OUTPUT_FILE_DUMP + { + FILE *pf; + char filename[100]; + static int tmp_cnt=0; + int w = handle->dst_buffer.width; + int h = handle->dst_buffer.height; + + memset(filename, 0x00, sizeof(filename)); + sprintf(filename, "/tmp/dec_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt); + + pf = fopen(filename, "wb"); + if (pf == NULL) { + ALOGE("[file dump] filepoint NULL!"); + } else { + ALOGE("[file dump] fwrite[%d]", tmp_cnt); + fwrite(handle->dst_buffer.planes[CSC_Y_PLANE], sizeof(char), w * h, pf); + fwrite(handle->dst_buffer.planes[CSC_UV_PLANE], sizeof(char), w * h / 2, pf); + } + fclose(pf); + } +#endif + break; + default: + ALOGE("dst_format CSC_ErrorUnsupportFormat"); + 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; + + ALOGE("%s:: handle->src_format.color_format = %d", __func__, handle->src_format.color_format); + switch (handle->src_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED"); + ret = conv_sw_src_nv12t(handle); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_P"); + ret = conv_sw_src_yuv420p(handle); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + ALOGE("src_format HAL_PIXEL_FORMAT_YCbCr_420_SP"); + ret = conv_sw_src_yuv420sp(handle); + break; + case HAL_PIXEL_FORMAT_ARGB888: + ALOGE("src_format 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 ENABLE_FIMC + case CSC_HW_TYPE_FIMC: + { + void *src_addr[3]; + void *dst_addr[3]; + OMX_COLOR_FORMATTYPE src_omx_format; + OMX_COLOR_FORMATTYPE dst_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]; + src_omx_format = hal_2_omx_pixel_format(handle->src_format.color_format); + dst_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, + dst_omx_format, + src_omx_format); + break; + } +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + if (exynos_gsc_convert(handle->csc_hw_handle) != 0) { + ALOGE("%s:: exynos_gsc_convert() fail", __func__); + ret = CSC_Error; + } + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type); + ret = CSC_ErrorNotImplemented; + break; + } + + return ret; +} + +static CSC_ERRORCODE csc_init_hw( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { +#ifdef ENABLE_FIMC + csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC; +#endif +#ifdef ENABLE_GSCALER + csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER; +#endif + switch (csc_handle->csc_hw_type) { +#ifdef ENABLE_FIMC + case CSC_HW_TYPE_FIMC: + csc_handle->csc_hw_handle = csc_hwconverter_open(); + ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__); + break; +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + if (csc_handle->hw_property.fixed_node >= 0) + csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0); + else + csc_handle->csc_hw_handle = exynos_gsc_create(); + ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__); + csc_handle->csc_hw_handle == NULL; + break; + } + } + + if (csc_handle->csc_method == CSC_METHOD_HW) { + if (csc_handle->csc_hw_handle == NULL) { + ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__); + free(csc_handle); + csc_handle = NULL; + } + } + + ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method); + + return ret; +} + +static CSC_ERRORCODE csc_set_format( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef ENABLE_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, + csc_handle->src_format.crop_width, + csc_handle->src_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), + csc_handle->src_format.cacheable, + csc_handle->hw_property.mode_drm); + + 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, + csc_handle->dst_format.crop_width, + csc_handle->dst_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), + csc_handle->dst_format.cacheable, + csc_handle->hw_property.mode_drm); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +static CSC_ERRORCODE csc_set_buffer( + void *handle) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + void *src_addr[3] = {NULL, }; + void *dst_addr[3] = {NULL, }; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + if (csc_handle->csc_method == CSC_METHOD_HW) { + src_addr[0] = csc_handle->src_buffer.planes[CSC_Y_PLANE]; + src_addr[1] = csc_handle->src_buffer.planes[CSC_U_PLANE]; + src_addr[2] = csc_handle->src_buffer.planes[CSC_V_PLANE]; + dst_addr[0] = csc_handle->dst_buffer.planes[CSC_Y_PLANE]; + dst_addr[1] = csc_handle->dst_buffer.planes[CSC_U_PLANE]; + dst_addr[2] = csc_handle->dst_buffer.planes[CSC_V_PLANE]; + + switch (csc_handle->csc_hw_type) { + case CSC_HW_TYPE_FIMC: + break; +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, src_addr); + exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, dst_addr); + break; +#endif + default: + ALOGE("%s:: unsupported csc_hw_type", __func__); + break; + } + } + + return ret; +} + +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->hw_property.fixed_node = -1; + csc_handle->hw_property.mode_drm = 0; + csc_handle->csc_method = 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 ENABLE_FIMC + case CSC_HW_TYPE_FIMC: + csc_hwconverter_close(csc_handle->csc_hw_handle); + break; +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + exynos_gsc_destroy(csc_handle->csc_hw_handle); + break; +#endif + default: + ALOGE("%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_set_hw_property( + void *handle, + CSC_HW_PROPERTY_TYPE property, + int value) +{ + CSC_HANDLE *csc_handle; + CSC_ERRORCODE ret = CSC_ErrorNone; + + if (handle == NULL) + return CSC_ErrorNotInit; + + csc_handle = (CSC_HANDLE *)handle; + switch (property) { + case CSC_HW_PROPERTY_FIXED_NODE: + csc_handle->hw_property.fixed_node = value; + break; + case CSC_HW_PROPERTY_MODE_DRM: + csc_handle->hw_property.mode_drm = value; + break; + default: + ALOGE("%s:: not supported hw property", __func__); + ret = CSC_ErrorUnsupportFormat; + } + + 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; + + 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; + + 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; + + 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; + + 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) && + (csc_handle->csc_hw_handle == NULL)) + csc_init_hw(handle); + + csc_set_format(csc_handle); + csc_set_buffer(csc_handle); + + if (csc_handle->csc_method == CSC_METHOD_HW) { + ALOGE("conv_hw"); + ret = conv_hw(csc_handle); + } + else { + ALOGE("conv_sw"); + ret = conv_sw(csc_handle); + ALOGE("after conv_sw"); + } + + return ret; +} diff --git a/exynos/libcsc/csc_helper.c b/exynos/libcsc/csc_helper.c new file mode 100644 index 0000000..2a59c47 --- /dev/null +++ b/exynos/libcsc/csc_helper.c @@ -0,0 +1,95 @@ +/* + * + * 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. + */ + +#define LOG_TAG "libcsc_helper" +#ifndef SLP_PLATFORM /* build env */ +#include +#include +#endif + +#include "Exynos_OMX_Def.h" + +#include "csc.h" +#include "exynos_format.h" + +OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( + unsigned int hal_format) +{ + OMX_COLOR_FORMATTYPE omx_format; + switch (hal_format) { +#ifndef SLP_PLATFORM /* build env */ /* useless */ + case HAL_PIXEL_FORMAT_YCbCr_422_I: + omx_format = OMX_COLOR_FormatYCbYCr; + break; +#endif + 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_CUSTOM_YCbCr_420_SP_TILED: + omx_format = OMX_SEC_COLOR_FormatNV12TPhysicalAddress; + 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) { +#ifndef SLP_PLATFORM /* build env */ /* useless */ + case OMX_COLOR_FormatYCbYCr: + hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I; + break; +#endif + 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_FormatNV12TPhysicalAddress: + hal_format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED; + 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; +} diff --git a/exynos/libv4l2/Android.mk b/exynos/libv4l2/Android.mk new file mode 100644 index 0000000..a4542f3 --- /dev/null +++ b/exynos/libv4l2/Android.mk @@ -0,0 +1,35 @@ +# 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + exynos_v4l2.c \ + exynos_subdev.c \ + exynos_mc.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils + +LOCAL_MODULE := libexynosv4l2 +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := eng + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos/libv4l2/Makefile.am b/exynos/libv4l2/Makefile.am new file mode 100644 index 0000000..084c2c8 --- /dev/null +++ b/exynos/libv4l2/Makefile.am @@ -0,0 +1,9 @@ +lib_LTLIBRARIES = libexynosv4l2.la + +libexynosv4l2_la_SOURCES = exynos_v4l2.c \ + exynos_subdev.c \ + exynos_mc.c + +libexynosv4l2_la_LIBADD = +libexynosv4l2_la_CFLAGS = -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/openmax/osal diff --git a/exynos/libv4l2/exynos_mc.c b/exynos/libv4l2/exynos_mc.c new file mode 100644 index 0000000..bfaa9b3 --- /dev/null +++ b/exynos/libv4l2/exynos_mc.c @@ -0,0 +1,788 @@ +/* + * 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 exynos_mc.c + * \brief source file for libexynosv4l2 + * \author Jinsung Yang (jsgood.yang@samsung.com) + * \author Sangwoo Park (sw5771.park@samsung.com) + * \date 2012/01/17 + * + * Revision History: + * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n + * Initial version + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef SLP_PLATFORM /* build env */ +#include +#else + +//#include +#include + +#endif +#include +#include + +#include "exynos_v4l2.h" + +//#define LOG_NDEBUG 0 +#define LOG_TAG "libexynosv4l2-mc" +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +static inline unsigned int __media_entity_type(struct media_entity *entity) +{ + return entity->info.type & MEDIA_ENT_TYPE_MASK; +} + +static void __media_debug_default(void *ptr, ...) +{ + va_list argptr; + va_start(argptr, ptr); + vprintf((const char*)ptr, argptr); + va_end(argptr); +} + +static 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; + } +} + +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) +{ + ALOGD("%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) { + ALOGE("Unable to enumerate pads and links (%s)", 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 = exynos_media_get_entity_by_id(media, link->source.entity); + sink = exynos_media_get_entity_by_id(media, link->sink.entity); + if (source == NULL || sink == NULL) { + ALOGE("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; +} + +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; +} + +static int __media_get_media_fd(const char *filename, struct media_device *media) +{ + ssize_t num; + int media_node; + char *ptr; + char media_buf[6]; + + ALOGD("%s: %s", __func__, filename); + + media->fd = open(filename, O_RDWR, 0); + if (media->fd < 0) { + ALOGE("Open sysfs media device failed, media->fd: %d", media->fd); + return -1; + } + + ALOGD("%s: media->fd: %d", __func__, media->fd); + + return media->fd; + +} + +static int __media_enum_entities(struct media_device *media) +{ + struct media_entity *entity, *temp_entity; + unsigned int size; + __u32 id; + int ret; + + temp_entity = 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) + ALOGE("media_get_devname failed"); + } + free(temp_entity); + + return ret; +} + +static struct media_device *__media_open_debug( + const char *filename, + 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) { + ALOGE("media: %p", media); + return NULL; + } + + __media_debug_set_handler(media, debug_handler, debug_priv); + + ALOGD("%s: Opening media device %s", __func__, filename); + ALOGD("%s: media: %p", __func__, media); + + media->fd = __media_get_media_fd(filename, media); + if (media->fd < 0) { + exynos_media_close(media); + ALOGE("failed __media_get_media_fd %s", filename); + return NULL; + } + + ALOGD("%s: media->fd: %d", __func__, media->fd); + ret = __media_enum_entities(media); + + if (ret < 0) { + ALOGE("Unable to enumerate entities for device %s (%s)", filename, strerror(-ret)); + exynos_media_close(media); + return NULL; + } + + ALOGD("%s: Found %u entities", __func__, media->entities_count); + ALOGD("%s: Enumerating pads and links", __func__); + + ret = __media_enum_links(media); + if (ret < 0) { + ALOGE("Unable to enumerate pads and links for device %s", filename); + exynos_media_close(media); + return NULL; + } + + return media; +} + +/** + * @brief Open a media device. + * @param filename - name (including path) of the device node. + * + * Open the media device referenced by @a filename 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 + * exynos_media_close when the device isn't needed anymore. + */ +struct media_device *exynos_media_open(const char *filename) +{ + return __media_open_debug(filename, (void (*)(void *, ...))fprintf, stdout); +} + +/** + * @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 exynos_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); +} + +/** + * @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 *exynos_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; +} + +/** + * @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 *exynos_media_get_entity_by_name(struct media_device *media, + const char *name, size_t length) +{ + unsigned int i; + struct media_entity *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; +} + +/** + * @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 *exynos_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; +} + +/** + * @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 exynos_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) { + ALOGE("Link not found"); + 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) { + ALOGE("Unable to setup link (%s)", strerror(errno)); + return -errno; + } + + link->flags = ulink.flags; + link->twin->flags = ulink.flags; + return 0; +} + +/** + * @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 exynos_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 = exynos_media_setup_link(media, link->source, link->sink, + link->flags & ~MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + } + } + + return 0; +} + +#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); + ALOGE("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 */ + +/** + * @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 *exynos_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 = exynos_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 = exynos_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]; +} + +/** + * @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 *exynos_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 = exynos_media_parse_pad(media, p, &end); + if (source == NULL) + return NULL; + + if (end[0] != '-' || end[1] != '>') + return NULL; + p = end + 2; + + sink = exynos_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; +} + +/** + * @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 exynos_media_parse_setup_link( + struct media_device *media, + const char *p, + char **endp) +{ + struct media_link *link; + __u32 flags; + char *end; + + link = exynos_media_parse_link(media, p, &end); + if (link == NULL) { + ALOGE("Unable to parse link"); + return -EINVAL; + } + + p = end; + if (*p++ != '[') { + ALOGE("Unable to parse link flags"); + return -EINVAL; + } + + flags = strtoul(p, &end, 10); + for (p = end; isspace(*p); p++); + if (*p++ != ']') { + ALOGE("Unable to parse link flags"); + return -EINVAL; + } + + for (; isspace(*p); p++); + *endp = (char *)p; + + ALOGD("%s: Setting up link %u:%u -> %u:%u [%u]", __func__, + link->source->entity->info.id, link->source->index, + link->sink->entity->info.id, link->sink->index, + flags); + + return exynos_media_setup_link(media, link->source, link->sink, flags); +} + +/** + * @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 exynos_media_parse_setup_links(struct media_device *media, const char *p) +{ + char *end; + int ret; + + do { + ret = exynos_media_parse_setup_link(media, p, &end); + if (ret < 0) + return ret; + + p = end + 1; + } while (*end == ','); + + return *end ? -EINVAL : 0; +} diff --git a/exynos/libv4l2/exynos_subdev.c b/exynos/libv4l2/exynos_subdev.c new file mode 100644 index 0000000..5ac578d --- /dev/null +++ b/exynos/libv4l2/exynos_subdev.c @@ -0,0 +1,379 @@ +/* + * 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 exynos_subdev.c + * \brief source file for libv4l2 + * \author Jinsung Yang (jsgood.yang@samsung.com) + * \author Sangwoo Park (sw5771.park@samsung.com) + * \date 2012/01/17 + * + * Revision History: + * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n + * Initial version + * + */ + +#include +#include +#include +#include +#include +#include + +#include "exynos_v4l2.h" + +//#define LOG_NDEBUG 0 +#define LOG_TAG "libexynosv4l2-subdev" +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +#define SUBDEV_MINOR_MAX 191 + +static int __subdev_open(const char *filename, int oflag, va_list ap) +{ + mode_t mode = 0; + int fd; + + if (oflag & O_CREAT) + mode = va_arg(ap, int); + + fd = open(filename, oflag, mode); + + return fd; +} + +int exynos_subdev_open(const char *filename, int oflag, ...) +{ + va_list ap; + int fd; + + va_start(ap, oflag); + fd = __subdev_open(filename, oflag, ap); + va_end(ap); + + return fd; +} + +int exynos_subdev_open_devname(const char *devname, int oflag, ...) +{ + bool found = false; + int fd = -1; + struct stat s; + va_list ap; + FILE *stream_fd; + char filename[64], name[64]; + int minor, size, i = 0; + + do { + if (i > (SUBDEV_MINOR_MAX - 128)) + break; + + /* video device node */ + sprintf(filename, "/dev/v4l-subdev%d", i++); + + /* if the node is video device */ + if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) && + ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) { + minor = (int)((unsigned short)(s.st_rdev & 0x3f)); + ALOGD("try node: %s, minor: %d", filename, minor); + /* open sysfs entry */ + sprintf(filename, "/sys/class/video4linux/v4l-subdev%d/name", minor); + stream_fd = fopen(filename, "r"); + if (stream_fd == NULL) { + ALOGE("failed to open sysfs entry for subdev"); + continue; /* try next */ + } + + /* read sysfs entry for device name */ + size = (int)fgets(name, sizeof(name), stream_fd); + fclose(stream_fd); + + /* check read size */ + if (size == 0) { + ALOGE("failed to read sysfs entry for subdev"); + } else { + /* matched */ + if (strncmp(name, devname, strlen(devname)) == 0) { + ALOGI("node found for device %s: /dev/v4l-subdev%d", devname, minor); + found = true; + } + } + } + } while (found == false); + + if (found) { + sprintf(filename, "/dev/v4l-subdev%d", minor); + va_start(ap, oflag); + fd = __subdev_open(filename, oflag, ap); + va_end(ap); + + if (fd > 0) + ALOGI("open subdev device %s", filename); + else + ALOGE("failed to open subdev device %s", filename); + } else { + ALOGE("no subdev device found"); + } + + return fd; +} + +/** + * @brief enum frame size on a pad. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_enum_frame_size(int fd, struct v4l2_subdev_frame_size_enum *frame_size_enum) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!frame_size_enum) { + ALOGE("%s: frame_size_enum is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, frame_size_enum); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE"); + return ret; + } + + return ret; +} + +/** + * @brief Retrieve the format on a pad. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_g_fmt(int fd, struct v4l2_subdev_format *fmt) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!fmt) { + ALOGE("%s: fmt is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_G_FMT, fmt); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_FMT"); + return ret; + } + + return ret; +} + +/** + * @brief Set the format on a pad. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_s_fmt(int fd, struct v4l2_subdev_format *fmt) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!fmt) { + ALOGE("%s: fmt is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_S_FMT, fmt); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_FMT"); + return ret; + } + + return ret; +} + +/** + * @brief Retrieve the crop rectangle on a pad. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_g_crop(int fd, struct v4l2_subdev_crop *crop) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!crop) { + ALOGE("%s: crop is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_G_CROP, crop); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_CROP"); + return ret; + } + + return ret; +} + +/** + * @brief Set the crop rectangle on a pad. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_s_crop(int fd, struct v4l2_subdev_crop *crop) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!crop) { + ALOGE("%s: crop is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_S_CROP, crop); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_CROP"); + return ret; + } + + return ret; +} + +/** + * @brief Retrieve the frame interval on a sub-device. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_enum_frame_interval(int fd, struct v4l2_subdev_frame_interval_enum *frame_internval_enum) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!frame_internval_enum) { + ALOGE("%s: frame_internval_enum is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, frame_internval_enum); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL"); + return ret; + } + + return ret; +} + +/** + * @brief Retrieve the frame interval on a sub-device. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_g_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!frame_internval) { + ALOGE("%s: frame_internval is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, frame_internval); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL"); + return ret; + } + + return ret; +} + +/** + * @brief Set the frame interval on a sub-device. + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_s_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!frame_internval) { + ALOGE("%s: frame_internval is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, frame_internval); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL"); + return ret; + } + + return ret; +} + +/** + * @brief enum mbus code + * @return 0 on success, or a negative error code on failure. + */ +int exynos_subdev_enum_mbus_code(int fd, struct v4l2_subdev_mbus_code_enum *mbus_code_enum) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!mbus_code_enum) { + ALOGE("%s: mbus_code_enum is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, mbus_code_enum); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE"); + return ret; + } + + return ret; +} diff --git a/exynos/libv4l2/exynos_v4l2.c b/exynos/libv4l2/exynos_v4l2.c new file mode 100644 index 0000000..dce7223 --- /dev/null +++ b/exynos/libv4l2/exynos_v4l2.c @@ -0,0 +1,798 @@ +/* + * 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 exynos_v4l2.c + * \brief source file for libv4l2 + * \author Jinsung Yang (jsgood.yang@samsung.com) + * \author Sangwoo Park (sw5771.park@samsung.com) + * \date 2012/01/17 + * + * Revision History: + * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n + * Initial version + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exynos_v4l2.h" + +//#define LOG_NDEBUG 0 +#define LOG_TAG "libexynosv4l2" +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +#define VIDEODEV_MAX 255 + +static bool __v4l2_check_buf_type(enum v4l2_buf_type type) +{ + bool supported; + + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + supported = true; + break; + + default: + supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false; + break; + } + + return supported; +} + +static int __v4l2_open(const char *filename, int oflag, va_list ap) +{ + mode_t mode = 0; + int fd; + + if (oflag & O_CREAT) + mode = va_arg(ap, int); + + fd = open(filename, oflag, mode); + + return fd; +} + +int exynos_v4l2_open(const char *filename, int oflag, ...) +{ + va_list ap; + int fd; + + va_start(ap, oflag); + fd = __v4l2_open(filename, oflag, ap); + va_end(ap); + + return fd; +} + +int exynos_v4l2_open_devname(const char *devname, int oflag, ...) +{ + bool found = false; + int fd = -1; + struct stat s; + va_list ap; + FILE *stream_fd; + char filename[64], name[64]; + int size, i = 0; + + do { + if (i > VIDEODEV_MAX) + break; + + /* video device node */ + snprintf(filename, sizeof(filename), "/dev/video%d", i); + + /* if the node is video device */ + if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) && + ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) { + ALOGD("try node: %s", filename); + /* open sysfs entry */ + snprintf(filename, sizeof(filename), "/sys/class/video4linux/video%d/name", i); + if (S_ISLNK(s.st_mode)) { + ALOGE("symbolic link detected"); + return -1; + } + stream_fd = fopen(filename, "r"); + if (stream_fd == NULL) { + ALOGE("failed to open sysfs entry for videodev"); + i++; + continue; /* try next */ + } + + /* read sysfs entry for device name */ + size = (int)fgets(name, sizeof(name), stream_fd); + fclose(stream_fd); + + /* check read size */ + if (size == 0) { + ALOGE("failed to read sysfs entry for videodev"); + } else { + /* matched */ + if (strncmp(name, devname, strlen(devname)) == 0) { + ALOGI("node found for device %s: /dev/video%d", devname, i); + found = true; + break; + } + } + } + i++; + } while (found == false); + + if (found) { + snprintf(filename, sizeof(filename), "/dev/video%d", i); + va_start(ap, oflag); + fd = __v4l2_open(filename, oflag, ap); + va_end(ap); + + if (fd > 0) + ALOGI("open video device %s", filename); + else + ALOGE("failed to open video device %s", filename); + } else { + ALOGE("no video device found"); + } + + return fd; +} + +int exynos_v4l2_close(int fd) +{ + int ret = -1; + + if (fd < 0) + ALOGE("%s: invalid fd: %d", __func__, fd); + else + ret = close(fd); + + return ret; +} + +bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf) +{ + int ret = -1; + struct v4l2_input input; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return NULL; + } + + input.index = index; + ret = ioctl(fd, VIDIOC_ENUMINPUT, &input); + if (ret) { + ALOGE("%s: no matching index founds", __func__); + return false; + } + + ALOGI("Name of input channel[%d] is %s", input.index, input.name); + + strcpy(input_name_buf, (const char *)input.name); + + return true; +} + +int exynos_v4l2_s_input(int fd, int index) +{ + int ret = -1; + struct v4l2_input input; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + input.index = index; + + ret = ioctl(fd, VIDIOC_S_INPUT, &input); + if (ret){ + ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +bool exynos_v4l2_querycap(int fd, unsigned int need_caps) +{ + struct v4l2_capability cap; + int ret; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return false; + } + + if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) && + !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) && + !(need_caps & V4L2_CAP_VIDEO_OUTPUT) && + !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) && + !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) { + ALOGE("%s: unsupported capabilities", __func__); + return false; + } + + memset(&cap, 0, sizeof(cap)); + + ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno)); + return false; + } + + if ((need_caps & cap.capabilities) != need_caps) { + ALOGE("%s: unsupported capabilities", __func__); + return false; + } + + return true; +} + +bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int found = 0; + + fmtdesc.type = type; + fmtdesc.index = 0; + + while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { + if (fmtdesc.pixelformat == fmt) { + ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description); + found = 1; + break; + } + + fmtdesc.index++; + } + + if (!found) { + ALOGE("%s: unsupported pixel format", __func__); + return false; + } + + return true; +} + +int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!fmt) { + ALOGE("%s: fmt is NULL", __func__); + return ret; + } + + if (__v4l2_check_buf_type(fmt->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_G_FMT, fmt); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!fmt) { + ALOGE("%s: fmt is NULL", __func__); + return ret; + } + + if (__v4l2_check_buf_type(fmt->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } else { + ret = ioctl(fd, request, fmt); + if (ret) { + if (request == VIDIOC_TRY_FMT) + ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno)); + else + ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno)); + + return ret; + } + } + + return ret; +} + +int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt) +{ + return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt); +} + +int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt) +{ + return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt); +} + +int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req) +{ + int ret = -1; + unsigned int count; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!req) { + ALOGE("%s: req is NULL", __func__); + return ret; + } + + if ((req->memory != V4L2_MEMORY_MMAP) && + (req->memory != V4L2_MEMORY_USERPTR) && + (req->memory != V4L2_MEMORY_DMABUF)) { + ALOGE("%s: unsupported memory type", __func__); + return ret; + } + + if (__v4l2_check_buf_type(req->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + count = req->count; + + ret = ioctl(fd, VIDIOC_REQBUFS, req); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno)); + return ret; + } + + if (count != req->count) { + ALOGW("number of buffers had been changed: %d => %d", count, req->count); + } + + return ret; +} + +int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!buf) { + ALOGE("%s: buf is NULL", __func__); + return ret; + } + + if ((buf->memory != V4L2_MEMORY_MMAP) && + (buf->memory != V4L2_MEMORY_DMABUF)) { + ALOGE("%s: unsupported memory type", __func__); + return ret; + } + + if (__v4l2_check_buf_type(buf->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_QUERYBUF, buf); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +#ifdef SLP_PLATFORM /*dmabuf */ + +#ifndef VIDIOC_EXPBUF +struct v4l2_exportbuffer { + __u32 fd; + __u32 reserved0; + __u32 mem_offset; + __u32 flags; + __u32 reserved[12]; +}; +#define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer) +#endif + +int exynos_v4l2_expbuf(int fd, int *buf_fd, __u32 mem_offset) +{ + int ret = -1; + struct v4l2_exportbuffer expbuf; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + expbuf.flags = O_CLOEXEC; + expbuf.mem_offset = mem_offset; + ALOGE("%s: fd:%d mem_offset:%d", __func__, fd, mem_offset); + + ret = ioctl(fd, VIDIOC_EXPBUF, &expbuf); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_EXPBUF (%d - %s)", errno, strerror(errno)); + return ret; + } + ALOGE("%s: got fd: %d", __func__, expbuf.fd); + *buf_fd = expbuf.fd; + + return ret; +} +#endif + +int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!buf) { + ALOGE("%s: buf is NULL", __func__); + return ret; + } + + if ((buf->memory != V4L2_MEMORY_MMAP) && + (buf->memory != V4L2_MEMORY_USERPTR) && + (buf->memory != V4L2_MEMORY_DMABUF)) { + ALOGE("%s: unsupported memory type", __func__); + return ret; + } + + if (__v4l2_check_buf_type(buf->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_QBUF, buf); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!buf) { + ALOGE("%s: buf is NULL", __func__); + return ret; + } + + if ((buf->memory != V4L2_MEMORY_MMAP) && + (buf->memory != V4L2_MEMORY_USERPTR) && + (buf->memory != V4L2_MEMORY_DMABUF)) { + ALOGE("%s: unsupported memory type", __func__); + return ret; + } + + if (__v4l2_check_buf_type(buf->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_DQBUF, buf); + + return ret; +} + +int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (__v4l2_check_buf_type(type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_STREAMON, &type); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (__v4l2_check_buf_type(type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_STREAMOFF, &type); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!crop) { + ALOGE("%s: crop is NULL", __func__); + return ret; + } + + if (__v4l2_check_buf_type(crop->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_CROPCAP, crop); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!crop) { + ALOGE("%s: crop is NULL", __func__); + return ret; + } + + if (__v4l2_check_buf_type(crop->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_G_CROP, crop); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (!crop) { + ALOGE("%s: crop is NULL", __func__); + return ret; + } + + if (__v4l2_check_buf_type(crop->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_S_CROP, crop); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value) +{ + int ret = -1; + struct v4l2_control ctrl; + + ctrl.id = id; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_G_CTRL id: %x (%d - %s)", id, errno, strerror(errno)); + return ret; + } + + *value = ctrl.value; + + return ret; +} + +int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value) +{ + int ret = -1; + struct v4l2_control ctrl; + + ctrl.id = id; + ctrl.value = value; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_S_CTRL id: %x (errno: %d)", id, errno); + return ret; + } + + return ret; +} + +int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (__v4l2_check_buf_type(streamparm->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_G_PARM, streamparm); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (__v4l2_check_buf_type(streamparm->type) == false) { + ALOGE("%s: unsupported buffer type", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_S_PARM, streamparm); + if (ret) { + ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno)); + return ret; + } + + return ret; +} + +int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (ctrl == NULL) { + ALOGE("%s: ctrl is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl); + if (ret) + ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno)); + + return ret; +} + +int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) +{ + int ret = -1; + + if (fd < 0) { + ALOGE("%s: invalid fd: %d", __func__, fd); + return ret; + } + + if (ctrl == NULL) { + ALOGE("%s: ctrl is NULL", __func__); + return ret; + } + + ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl); + if (ret) + ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno)); + + return ret; +} diff --git a/exynos4/Makefile.am b/exynos4/Makefile.am new file mode 100644 index 0000000..a4d7592 --- /dev/null +++ b/exynos4/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = libcodec libswconverter libion_exynos diff --git a/exynos4/include/ion.h b/exynos4/include/ion.h new file mode 100644 index 0000000..9b1cdee --- /dev/null +++ b/exynos4/include/ion.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2012 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 _LIB_ION_H_ +#define _LIB_ION_H_ + +#include /* size_t */ + +#define ION_FLAG_CACHED 1 + +#define ION_HEAP_SYSTEM_MASK (1 << 0) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1) +#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) +#define ION_HEAP_EXYNOS_MASK (1 << 5) +#define ION_EXYNOS_FIMD_VIDEO_MASK (1 << 29) +#define ION_EXYNOS_GSC_MASK (1 << 28) +#define ION_EXYNOS_MFC_SECURE_MASK (1 << 27) + +/* 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. + * @heap_mask: Mask of heaps which you want this allocation to be served from. + * @flags: Additional requirements about buffer. ION_FLAG_CACHED for a + * buffer you want to have a cached mapping of + * @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 heap_mask, 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_sync(ion_client client, ion_buffer buffer); + +#ifdef __cplusplus +} +#endif +#endif /* _LIB_ION_H_ */ diff --git a/exynos4/include/swconverter.h b/exynos4/include/swconverter.h new file mode 100644 index 0000000..6d80ee0 --- /dev/null +++ b/exynos4/include/swconverter.h @@ -0,0 +1,469 @@ +/* + * + * 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); + +void csc_ARGB8888_to_YUV420SP_NEON( + 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/libcodec/Android.mk b/exynos4/libcodec/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/exynos4/libcodec/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/exynos4/libcodec/Makefile.am b/exynos4/libcodec/Makefile.am new file mode 100644 index 0000000..5d97af8 --- /dev/null +++ b/exynos4/libcodec/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = video audio diff --git a/exynos4/libcodec/audio/Android.mk b/exynos4/libcodec/audio/Android.mk new file mode 100644 index 0000000..1cfc927 --- /dev/null +++ b/exynos4/libcodec/audio/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +ifeq ($(BOARD_USE_ALP_AUDIO), true) +include $(LOCAL_PATH)/alp/Android.mk +endif diff --git a/exynos4/libcodec/audio/Makefile.am b/exynos4/libcodec/audio/Makefile.am new file mode 100644 index 0000000..5c45ba9 --- /dev/null +++ b/exynos4/libcodec/audio/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = alp diff --git a/exynos4/libcodec/audio/alp/Android.mk b/exynos4/libcodec/audio/alp/Android.mk new file mode 100644 index 0000000..c6a3aef --- /dev/null +++ b/exynos4/libcodec/audio/alp/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + dec/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/libcodec/audio/alp/Makefile.am b/exynos4/libcodec/audio/alp/Makefile.am new file mode 100644 index 0000000..cc57920 --- /dev/null +++ b/exynos4/libcodec/audio/alp/Makefile.am @@ -0,0 +1,11 @@ +lib_LTLIBRARIES = libsrpapi.la + +libsrpapi_la_SOURCES = dec/srp_api.c + +libsrpapi_la_CFLAGS = -I$(CURDIR)/include \ + -I$(top_srcdir)/openmax/osal + +includelibsrpapidir = $(includedir)/srpapi +includelibsrpapi_HEADERS = $(CURDIR)/include/srp_api.h \ + $(CURDIR)/include/srp_ioctl.h \ + $(CURDIR)/include/srp_error.h diff --git a/exynos4/libcodec/audio/alp/dec/srp_api.c b/exynos4/libcodec/audio/alp/dec/srp_api.c new file mode 100644 index 0000000..ab53022 --- /dev/null +++ b/exynos4/libcodec/audio/alp/dec/srp_api.c @@ -0,0 +1,300 @@ +/* + * + * 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 srp_api.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "srp_api.h" + +#define LOG_NDEBUG 1 +#define LOG_TAG "libsrpapi" + +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +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; + } + + ALOGE("%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) { + ALOGE("%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) { + ALOGE("%s: mmap is failed", __func__); + return SRP_ERROR_OBUF_MMAP; + } + obuf_info.mmapped_size = mmapped_size; + + ret = SRP_RETURN_OK; + } else { + ALOGE("%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) { + ALOGV("%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) { +#ifdef SLP_PLATFORM +/* in slp, ret value is different from android. this is caused from glib. android uses bionic libc. */ + ret = -(errno); +#endif + if (ret != SRP_ERROR_IBUF_OVERFLOW) + ALOGE("SRP_Decode returned error code: %d", ret); + } + return ret; /* Write Success */ + } else { + return ret; + } + } + + ALOGE("%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; + ALOGE("%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) { + ALOGE("%s: Failed to get dec info", __func__); + return SRP_ERROR_GETINFO_FAIL; + } + + ALOGV("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) { + ALOGE("%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) { + ALOGE("%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) { + ALOGE("%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) { + ALOGE("%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) { + ALOGV("%s: Device is not opened", __func__); + return 0; + } + + ALOGV("%s: Device is opened", __func__); + return 1; +} diff --git a/exynos4/libcodec/audio/alp/include/srp_api.h b/exynos4/libcodec/audio/alp/include/srp_api.h new file mode 100644 index 0000000..0dcddae --- /dev/null +++ b/exynos4/libcodec/audio/alp/include/srp_api.h @@ -0,0 +1,82 @@ +/* + * + * 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 srp_api.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#ifndef __SRP_API_H__ +#define __SRP_API_H__ + +#include "srp_ioctl.h" +#include "srp_error.h" + +#ifndef SLP_PLATFORM +#define SRP_DEV_NAME "dev/srp" +#else +#define SRP_DEV_NAME "/dev/srp" +#endif + +#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/libcodec/audio/alp/include/srp_error.h b/exynos4/libcodec/audio/alp/include/srp_error.h new file mode 100644 index 0000000..0251ce8 --- /dev/null +++ b/exynos4/libcodec/audio/alp/include/srp_error.h @@ -0,0 +1,51 @@ +/* + * + * 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 srp_error.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#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, +#ifdef SLP_PLATFORM + SRP_ERROR_IBUF_BUFFERING = -2002, +#endif + + 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/libcodec/audio/alp/include/srp_ioctl.h b/exynos4/libcodec/audio/alp/include/srp_ioctl.h new file mode 100644 index 0000000..7eb2757 --- /dev/null +++ b/exynos4/libcodec/audio/alp/include/srp_ioctl.h @@ -0,0 +1,49 @@ +/* + * + * 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 srp_ioctl.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#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/libcodec/video/Android.mk b/exynos4/libcodec/video/Android.mk new file mode 100644 index 0000000..7e0c5fc --- /dev/null +++ b/exynos4/libcodec/video/Android.mk @@ -0,0 +1,5 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +include $(LOCAL_PATH)/v4l2/Android.mk diff --git a/exynos4/libcodec/video/Makefile.am b/exynos4/libcodec/video/Makefile.am new file mode 100644 index 0000000..88fc0f4 --- /dev/null +++ b/exynos4/libcodec/video/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = v4l2 diff --git a/exynos4/libcodec/video/v4l2/Android.mk b/exynos4/libcodec/video/v4l2/Android.mk new file mode 100644 index 0000000..a3142ff --- /dev/null +++ b/exynos4/libcodec/video/v4l2/Android.mk @@ -0,0 +1,24 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +BOARD_USE_DMA_BUF := false + +LOCAL_SRC_FILES := \ + dec/ExynosVideoDecoder.c \ + enc/ExynosVideoEncoder.c + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(TOP)/hardware/samsung_slsi/exynos/include + +LOCAL_MODULE := libExynosVideoApi +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false +LOCAL_ARM_MODE := arm + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/libcodec/video/v4l2/Makefile.am b/exynos4/libcodec/video/v4l2/Makefile.am new file mode 100644 index 0000000..8a25923 --- /dev/null +++ b/exynos4/libcodec/video/v4l2/Makefile.am @@ -0,0 +1,19 @@ +lib_LTLIBRARIES = libExynosVideoApi.la + +libExynosVideoApi_la_SOURCES = dec/ExynosVideoDecoder.c \ + enc/ExynosVideoEncoder.c + +libExynosVideoApi_la_LIBADD = \ + $(MMTA_LIBS) +libExynosVideoApi_la_CFLAGS = -I$(CURDIR)/include \ + -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/openmax/osal \ + $(MMTA_CFLAGS) + +if BOARD_USE_DMA_BUF +libExynosVideoApi_la_CFLAGS += -DUSE_DMA_BUF +endif + +if EXYNOS_3250 +libExynosVideoApi_la_CFLAGS += -DEXYNOS_3250 +endif diff --git a/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c new file mode 100755 index 0000000..1ccd8f6 --- /dev/null +++ b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c @@ -0,0 +1,2094 @@ +/* + * + * 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 ExynosVideoDecoder.c + * @brief + * @author Jinsung Yang (jsgood.yang@samsung.com) + * @version 1.0.0 + * @history + * 2012.01.15: Initial Version + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "ExynosVideoApi.h" +#include "ExynosVideoDec.h" + +#include + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "ExynosVideoDecoder" +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +/* + * [Common] __CodingType_To_V4L2PixelFormat + */ +static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType) +{ + unsigned int pixelformat = V4L2_PIX_FMT_H264; + + switch (codingType) { + case VIDEO_CODING_AVC: + pixelformat = V4L2_PIX_FMT_H264; + break; + case VIDEO_CODING_MPEG4: + pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case VIDEO_CODING_VP8: + pixelformat = V4L2_PIX_FMT_VP8; + break; + case VIDEO_CODING_H263: + pixelformat = V4L2_PIX_FMT_H263; + break; + case VIDEO_CODING_VC1: + pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G; + break; + case VIDEO_CODING_VC1_RCV: + pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L; + break; + case VIDEO_CODING_MPEG2: + pixelformat = V4L2_PIX_FMT_MPEG2; + break; + default: + pixelformat = V4L2_PIX_FMT_H264; + break; + } + + return pixelformat; +} + +/* + * [Common] __ColorFormatType_To_V4L2PixelFormat + */ +static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType) +{ + unsigned int pixelformat = V4L2_PIX_FMT_NV12M; + + switch (colorFormatType) { + case VIDEO_COLORFORMAT_NV12_TILED: +#ifdef EXYNOS_3250 + pixelformat = V4L2_PIX_FMT_NV12MT_16X16; +#else + pixelformat = V4L2_PIX_FMT_NV12MT; +#endif + break; +#if 0 + case VIDEO_COLORFORMAT_NV21: + pixelformat = V4L2_PIX_FMT_NV21M; + break; + case VIDEO_COLORFORMAT_NV12: + default: + pixelformat = V4L2_PIX_FMT_NV12M; + break; +#endif + } + + return pixelformat; +} + +/* + * [Decoder OPS] Init + */ +static void *MFC_Decoder_Init(int nMemoryType) +{ + ExynosVideoDecContext *pCtx = NULL; + pthread_mutex_t *pMutex = NULL; + int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING); + + MMTA_ACUM_ITEM_BEGIN("Video First Frame Coming", 0); + + pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx)); + if (pCtx == NULL) { + ALOGE("%s: Failed to allocate decoder context buffer", __func__); + goto EXIT_ALLOC_FAIL; + } + + memset(pCtx, 0, sizeof(*pCtx)); + + __ta__("exynos_v4l2_open_devname : VIDEO_DECODER_NAME", + pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0); + ); + if (pCtx->hDec < 0) { + ALOGE("%s: Failed to open decoder device", __func__); + goto EXIT_OPEN_FAIL; + } + + __ta__("exynos_v4l2_querycap", + if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) { + ALOGE("%s: Failed to querycap", __func__); + goto EXIT_QUERYCAP_FAIL; + } + ); + + pCtx->bStreamonInbuf = VIDEO_FALSE; + pCtx->bStreamonOutbuf = VIDEO_FALSE; + + pCtx->nMemoryType = nMemoryType; + + pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (pMutex == NULL) { + ALOGE("%s: Failed to allocate mutex about input buffer", __func__); + goto EXIT_QUERYCAP_FAIL; + } + if (pthread_mutex_init(pMutex, NULL) != 0) { + free(pMutex); + goto EXIT_QUERYCAP_FAIL; + } + pCtx->pInMutex = (void*)pMutex; + + pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (pMutex == NULL) { + ALOGE("%s: Failed to allocate mutex about output buffer", __func__); + goto EXIT_QUERYCAP_FAIL; + } + if (pthread_mutex_init(pMutex, NULL) != 0) { + free(pMutex); + goto EXIT_QUERYCAP_FAIL; + } + pCtx->pOutMutex = (void*)pMutex; + + return (void *)pCtx; + +EXIT_QUERYCAP_FAIL: + if (pCtx->pInMutex != NULL) { + pthread_mutex_destroy(pCtx->pInMutex); + free(pCtx->pInMutex); + } + + if (pCtx->pOutMutex != NULL) { + pthread_mutex_destroy(pCtx->pOutMutex); + free(pCtx->pOutMutex); + } + + close(pCtx->hDec); + +EXIT_OPEN_FAIL: + free(pCtx); + +EXIT_ALLOC_FAIL: + return NULL; +} + +/* + * [Decoder OPS] Finalize + */ +static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + pthread_mutex_t *pMutex = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->pOutMutex != NULL) { + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_destroy(pMutex); + free(pMutex); + pCtx->pOutMutex = NULL; + } + + if (pCtx->pInMutex != NULL) { + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_destroy(pMutex); + free(pMutex); + pCtx->pInMutex = NULL; + } + + if (pCtx->bShareInbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nInbufs; i++) { + for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) { + pVideoPlane = &pCtx->pInbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pInbuf[i].pGeometry = NULL; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nOutbufs; i++) { + for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pOutbuf[i].pGeometry = NULL; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + if (pCtx->pInbuf != NULL) + free(pCtx->pInbuf); + + if (pCtx->pOutbuf != NULL) + free(pCtx->pOutbuf); + + if (pCtx->hDec > 0) + close(pCtx->hDec); + + free(pCtx); + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Set Frame Tag + */ +static ExynosVideoErrorType MFC_Decoder_Set_FrameTag( + void *pHandle, + int frameTag) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Get Frame Tag + */ +static int MFC_Decoder_Get_FrameTag(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int frameTag = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", + exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag); + ); + +EXIT: + return frameTag; +} + +/* + * [Decoder OPS] Get Buffer Count + */ +static int MFC_Decoder_Get_ActualBufferCount(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int bufferCount = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MIN_BUFFERS_FOR_CAPTURE", + exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount); + ); + +EXIT: + return bufferCount; +} + +/* + * [Decoder OPS] Set Display Delay + */ +static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay( + void *pHandle, + int delay) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY", + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + /* + * [Decoder OPS] Set Immediate Display + */ +static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY", + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} +/* + * [Decoder OPS] Enable Packed PB + */ +static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB", + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Enable Loop Filter + */ +static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Enable Slice Mode + */ +static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Enable SEI Parsing + */ +static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Get Frame Packing information + */ +static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo( + void *pHandle, + ExynosVideoFramePacking *pFramePacking) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM]; + struct v4l2_ext_controls ext_ctrls; + + int seiAvailable, seiInfo, seiGridPos, i; + unsigned int seiArgmtId; + + + if ((pCtx == NULL) || (pFramePacking == NULL)) { + ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(pFramePacking, 0, sizeof(*pFramePacking)); + memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM)); + + ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM; + ext_ctrls.controls = ext_ctrl; + ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL; + ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID; + ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO; + ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS; + + __ta__("exynos_v4l2_g_ext_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FP_XX(AVAIL,ARRGMENT_ID,INFO,GRID_POS)" , + if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + seiAvailable = ext_ctrl[0].value; + seiArgmtId = ext_ctrl[1].value; + seiInfo = ext_ctrl[2].value; + seiGridPos = ext_ctrl[3].value; + + pFramePacking->available = seiAvailable; + pFramePacking->arrangement_id = seiArgmtId; + + pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0); + pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1); + pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8); + pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9); + pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15); + pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16); + pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17); + pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18); + + pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0); + pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4); + pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8); + pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12); + +EXIT: + return ret; +} + + + /* + * [Decoder OPS] Enable Decode waiting for share Mode, + * to make sure destination support is completed and + * reset when Destination streamoff +*/ +static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + +/* + * [Decoder Buffer OPS] Enable Cacheable (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Enable Cacheable (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" , + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Set Shareable Buffer (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + pCtx->bShareInbuf = VIDEO_TRUE; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Set Shareable Buffer (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + pCtx->bShareOutbuf = VIDEO_TRUE; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Get Buffer (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf( + void *pHandle, + int nIndex, + ExynosVideoBuffer **pBuffer) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->nInbufs <= nIndex) { + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex]; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Get Buffer (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf( + void *pHandle, + int nIndex, + ExynosVideoBuffer **pBuffer) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->nOutbufs <= nIndex) { + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex]; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Set Geometry (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat); + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage; + +__ta__("exynos_v4l2_s_fmt" , + if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry)); + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Set Geometry (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat); + + __ta__("exynos_v4l2_s_fmt" , + if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry)); + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Get Geometry (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + struct v4l2_crop crop; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + memset(&crop, 0, sizeof(crop)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + __ta__("exynos_v4l2_g_fmt" , + if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) { + ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + __ta__("exynos_v4l2_g_crop" , + if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) { + ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + bufferConf->nFrameWidth = fmt.fmt.pix_mp.width; + bufferConf->nFrameHeight = fmt.fmt.pix_mp.height; + + bufferConf->cropRect.nTop = crop.c.top; + bufferConf->cropRect.nLeft = crop.c.left; + bufferConf->cropRect.nWidth = crop.c.width; + bufferConf->cropRect.nHeight = crop.c.height; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Setup (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf( + void *pHandle, + unsigned int nBufferCount) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES]; + int i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (nBufferCount == 0) { + ALOGE("%s: Buffer count must be greater than 0", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount, + pCtx->bShareInbuf ? "true" : "false"); + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareInbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + if (req.count != nBufferCount) { + ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + + pCtx->nInbufs = (int)req.count; + + pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs); + if (pCtx->pInbuf == NULL) { + ALOGE("Failed to allocate input buffer context"); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs); + + memset(&buf, 0, sizeof(buf)); + + if (pCtx->bShareInbuf == VIDEO_FALSE) { + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = VIDEO_DECODER_INBUF_PLANES; + + ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__); + for (i = 0; i < pCtx->nInbufs; i++) { + buf.index = i; + __ta__("INBUF : exynos_v4l2_querybuf", + if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + pVideoPlane = &pCtx->pInbuf[i].planes[0]; + + __ta__("mmap : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + pVideoPlane->addr = mmap(NULL, + buf.m.planes[0].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset); + ); + + if (pVideoPlane->addr == MAP_FAILED) { + ret = VIDEO_ERROR_MAPFAIL; + goto EXIT; + } + + pVideoPlane->allocSize = buf.m.planes[0].length; + pVideoPlane->dataSize = 0; + + pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_TRUE; + } + } + + return ret; + +EXIT: + if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) { + if (pCtx->bShareInbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nInbufs; i++) { + pVideoPlane = &pCtx->pInbuf[i].planes[0]; + if (pVideoPlane->addr == MAP_FAILED) { + pVideoPlane->addr = NULL; + break; + } + + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + } + } + + free(pCtx->pInbuf); + } + + return ret; +} + +/* + * [Decoder Buffer OPS] Setup (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( + void *pHandle, + unsigned int nBufferCount) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; + int i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (nBufferCount == 0) { + ALOGE("%s: Buffer count must be greater than 0", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount, + pCtx->bShareOutbuf ? "true" : "false"); + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , + if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + if (req.count != nBufferCount) { + ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + + pCtx->nOutbufs = req.count; + + pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); + if (pCtx->pOutbuf == NULL) { + ALOGE("Failed to allocate output buffer context"); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); + + memset(&buf, 0, sizeof(buf)); + + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = VIDEO_DECODER_OUTBUF_PLANES; + + ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__); + for (i = 0; i < pCtx->nOutbufs; i++) { + buf.index = i; + __ta__("exynos_v4l2_querybuf" , + if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + __ta__("mmap : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + pVideoPlane->addr = mmap(NULL, + buf.m.planes[j].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset); + ); + + if (pVideoPlane->addr == MAP_FAILED) { + ret = VIDEO_ERROR_MAPFAIL; + goto EXIT; + } + + pVideoPlane->allocSize = buf.m.planes[j].length; + pVideoPlane->dataSize = 0; + +#ifdef SLP_PLATFORM /* dmabuf */ + __ta__("exynos_v4l2_expbuf" , +// if (pCtx->bufShareMethod == BUF_SHARE_FD) { + exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset); + ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd); +// } + ) +#endif + } + + pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE; + } + } + + return ret; + +EXIT: + if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) { + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nOutbufs; i++) { + for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + if (pVideoPlane->addr == MAP_FAILED) { + pVideoPlane->addr = NULL; + break; + } + + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + } + } + } + + free(pCtx->pOutbuf); + } + + return ret; +} + +/* + * [Decoder Buffer OPS] Run (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_FALSE) { + __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , + if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { + ALOGE("%s: Failed to streamon for input buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + pCtx->bStreamonInbuf = VIDEO_TRUE; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Run (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , + if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { + ALOGE("%s: Failed to streamon for output buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + pCtx->bStreamonOutbuf = VIDEO_TRUE; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Stop (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_TRUE) { + __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , + if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { + ALOGE("%s: Failed to streamoff for input buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + pCtx->bStreamonInbuf = VIDEO_FALSE; + } + + for (i = 0; i < pCtx->nInbufs; i++) { + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Stop (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_TRUE) { + __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , + if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { + ALOGE("%s: Failed to streamoff for output buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + pCtx->bStreamonOutbuf = VIDEO_FALSE; + } + + for (i = 0; i < pCtx->nOutbufs; i++) { + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Wait (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct pollfd poll_events; + int poll_state; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + poll_events.fd = pCtx->hDec; + poll_events.events = POLLOUT | POLLERR; + poll_events.revents = 0; + + do { + poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT); + if (poll_state > 0) { + if (poll_events.revents & POLLOUT) { + break; + } else { + ALOGE("%s: Poll return error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } + } else if (poll_state < 0) { + ALOGE("%s: Poll state error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } + } while (poll_state == 0); + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Decoder_Register_Inbuf( + void *pHandle, + ExynosVideoPlane *planes, + int nPlanes) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex, plane; + + if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) { + ALOGE("%s: params must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) { + for (plane = 0; plane < nPlanes; plane++) { + pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr; + pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; + pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd; + ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex, + planes[plane].addr, planes[plane].allocSize, planes[plane].fd); + } + pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE; + break; + } + } + + if (nIndex == pCtx->nInbufs) { + ALOGE("%s: can not find non-registered input buffer", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Decoder_Register_Outbuf( + void *pHandle, + ExynosVideoPlane *planes, + int nPlanes) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex, plane; + + if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) { + ALOGE("%s: params must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) { + for (plane = 0; plane < nPlanes; plane++) { + pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr; + pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; + pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd; + } + pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE; + ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n", + __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd, + planes[1].addr, planes[1].allocSize, planes[1].fd); + break; + } + } + + if (nIndex == pCtx->nOutbufs) { + ALOGE("%s: can not find non-registered output buffer", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + pCtx->pInbuf[nIndex].planes[0].addr = NULL; + pCtx->pInbuf[nIndex].planes[0].fd = -1; + pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + pCtx->pOutbuf[nIndex].planes[0].addr = NULL; + pCtx->pOutbuf[nIndex].planes[0].fd = -1; + pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Find (Input) + */ +static int MFC_Decoder_Find_Inbuf( + void *pHandle, + unsigned char *pBuffer) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) { + if ((pBuffer == NULL) || + (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer)) + break; + } + } + + if (nIndex == pCtx->nInbufs) + nIndex = -1; + +EXIT: + return nIndex; +} + +/* + * [Decoder Buffer OPS] Find (Outnput) + */ +static int MFC_Decoder_Find_Outbuf( + void *pHandle, + unsigned char *pBuffer) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) { + if ((pBuffer == NULL) || + (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer)) + break; + } + } + + if (nIndex == pCtx->nOutbufs) + nIndex = -1; + +EXIT: + return nIndex; +} + +/* + * [Decoder Buffer OPS] Enqueue (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( + void *pHandle, + unsigned char *pBuffer[], + unsigned int dataSize[], + int nPlanes, + void *pPrivate) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + + struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES]; + struct v4l2_buffer buf; + int index, i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (VIDEO_DECODER_INBUF_PLANES < nPlanes) { + ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, + VIDEO_DECODER_INBUF_PLANES, nPlanes); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.m.planes = planes; + buf.length = VIDEO_DECODER_INBUF_PLANES; + + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_lock(pMutex); + index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]); + if (index == -1) { + pthread_mutex_unlock(pMutex); + ALOGE("%s: Failed to get index", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + + buf.index = index; + pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; + pthread_mutex_unlock(pMutex); + + if (pCtx->bShareInbuf == VIDEO_TRUE) { + buf.memory = pCtx->nMemoryType; + for (i = 0; i < nPlanes; i++) { + /* V4L2_MEMORY_USERPTR */ + buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; + /* V4L2_MEMORY_DMABUF */ +#ifdef USE_DMA_BUF + buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd; +#endif + buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize; + buf.m.planes[i].bytesused = dataSize[i]; + ALOGV("%s: shared INBUF(%d) plane(%d) data_offset= %x addr=%p len=%d used=%d\n", __func__, + index, i, + buf.m.planes[i].data_offset, + buf.m.planes[i].m.userptr, + buf.m.planes[i].length, + buf.m.planes[i].bytesused); + } + } else { + buf.memory = V4L2_MEMORY_MMAP; + for (i = 0; i < nPlanes; i++) + buf.m.planes[i].bytesused = dataSize[i]; + } + + __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { + ALOGE("%s: Failed to enqueue input buffer", __func__); + pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + pCtx->pInbuf[buf.index].pPrivate = pPrivate; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Enqueue (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf( + void *pHandle, + unsigned char *pBuffer[], + unsigned int dataSize[], + int nPlanes, + void *pPrivate) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + + struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; + struct v4l2_buffer buf; + int i, index; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) { + ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, + VIDEO_DECODER_OUTBUF_PLANES, nPlanes); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.m.planes = planes; + buf.length = VIDEO_DECODER_OUTBUF_PLANES; + + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]); + if (index == -1) { + pthread_mutex_unlock(pMutex); + ALOGE("%s: Failed to get index", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + buf.index = index; + pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; + pthread_mutex_unlock(pMutex); + + if (pCtx->bShareOutbuf == VIDEO_TRUE) { + buf.memory = pCtx->nMemoryType; + for (i = 0; i < nPlanes; i++) { + /* V4L2_MEMORY_USERPTR */ + buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; + /* V4L2_MEMORY_DMABUF */ +#ifdef USE_DMA_BUF + buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd; +#endif + buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize; + buf.m.planes[i].bytesused = dataSize[i]; + ALOGV("%s: shared OUTBUF(%d) plane=%d data_offset= %x addr=0x%lx len=%d used=%d\n", __func__, + index, i, + buf.m.planes[i].data_offset, + buf.m.planes[i].m.userptr, + buf.m.planes[i].length, + buf.m.planes[i].bytesused); + } + } else { + ALOGV("%s: non-shared outbuf(%d)\n", __func__, index); + buf.memory = V4L2_MEMORY_MMAP; + } + + __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { + ALOGE("%s: Failed to enqueue output buffer", __func__); + pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + pCtx->pOutbuf[buf.index].pPrivate = pPrivate; + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Dequeue (Input) + */ +static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoBuffer *pInbuf = NULL; + + struct v4l2_buffer buf; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_FALSE) { + pInbuf = NULL; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (pCtx->bShareInbuf == VIDEO_TRUE) + buf.memory = pCtx->nMemoryType; + else + buf.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , + if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { + pInbuf = NULL; + goto EXIT; + } + ) + + pInbuf = &pCtx->pInbuf[buf.index]; + pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + + if (pCtx->bStreamonInbuf == VIDEO_FALSE) + pInbuf = NULL; + +EXIT: + return pInbuf; +} + +/* + * [Decoder Buffer OPS] Dequeue (Output) + */ +static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoBuffer *pOutbuf = NULL; + + struct v4l2_buffer buf; + + int value, state; + int ret = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + pOutbuf = NULL; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + buf.memory = pCtx->nMemoryType; + else + buf.memory = V4L2_MEMORY_MMAP; + + /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */ + __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf); + ); + if (ret != 0) { + if (errno == EIO) + pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO; + else + pOutbuf = NULL; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + pOutbuf = NULL; + goto EXIT; + } + + pOutbuf = &pCtx->pOutbuf[buf.index]; + + __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS", + exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); + ); + + ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value); + switch (value) { + case 0: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY; + break; + case 1: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING; + break; + case 2: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; + break; + case 3: + __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE", + exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state); + ); + if (state == 1) /* Resolution change is detected */ + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; + else /* Decoding is finished */ + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED; + break; + default: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + break; + } + + switch (buf.flags & (0x7 << 3)) { + ALOGV("%s: frameType: %d", __func__, buf.flags & (0x7 << 3)); + case V4L2_BUF_FLAG_KEYFRAME: + pOutbuf->frameType = VIDEO_FRAME_I; + break; + case V4L2_BUF_FLAG_PFRAME: + pOutbuf->frameType = VIDEO_FRAME_P; + break; + case V4L2_BUF_FLAG_BFRAME: + pOutbuf->frameType = VIDEO_FRAME_B; + break; + default: + pOutbuf->frameType = VIDEO_FRAME_OTHERS; + break; + }; + + pOutbuf->bQueued = VIDEO_FALSE; + +EXIT: + return pOutbuf; +} + +static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (i = 0; i < pCtx->nInbufs; i++) { + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (i = 0; i < pCtx->nOutbufs; i++) { + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* [Decoder Buffer OPS] Cleanup (Input) + */ +static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + int nBufferCount, i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + nBufferCount = 0; /* for Clean-up */ + + if (pCtx->bShareInbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nInbufs; i++) { + for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) { + pVideoPlane = &pCtx->pInbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pInbuf[i].pGeometry = NULL; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareInbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , + if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + pCtx->nInbufs = (int)req.count; + + if (pCtx->pInbuf != NULL) + free(pCtx->pInbuf); + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Cleanup (Output) + */ +static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + int nBufferCount, i ,j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + nBufferCount = 0; /* for Clean-up */ + + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nOutbufs; i++) { + for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pOutbuf[i].pGeometry = NULL; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , + if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { + ALOGE("reqbuf fail"); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ) + + pCtx->nOutbufs = req.count; + + if (pCtx->pOutbuf != NULL) + free(pCtx->pOutbuf); + +EXIT: + return ret; +} + +/* + * [Decoder OPS] Common + */ +static ExynosVideoDecOps defDecOps = { + .nSize = 0, + .Init = MFC_Decoder_Init, + .Finalize = MFC_Decoder_Finalize, + .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay, + .Enable_PackedPB = MFC_Decoder_Enable_PackedPB, + .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter, + .Enable_SliceMode = MFC_Decoder_Enable_SliceMode, + .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount, + .Set_FrameTag = MFC_Decoder_Set_FrameTag, + .Get_FrameTag = MFC_Decoder_Get_FrameTag, + .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing, + .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo, + .Set_ImmediateDisplay = MFC_Decoder_Set_ImmediateDisplay, + .Enable_DecodeWait = MFC_Decoder_Enable_DecodeWait, +}; + +/* + * [Decoder Buffer OPS] Input + */ +static ExynosVideoDecBufferOps defInbufOps = { + .nSize = 0, + .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf, + .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf, + .Get_Buffer = MFC_Decoder_Get_Buffer_Inbuf, + .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf, + .Get_Geometry = NULL, + .Setup = MFC_Decoder_Setup_Inbuf, + .Run = MFC_Decoder_Run_Inbuf, + .Stop = MFC_Decoder_Stop_Inbuf, + .Enqueue = MFC_Decoder_Enqueue_Inbuf, + .Enqueue_All = NULL, + .Dequeue = MFC_Decoder_Dequeue_Inbuf, + .Register = MFC_Decoder_Register_Inbuf, + .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf, + .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf, + .Cleanup = MFC_Decoder_Cleanup_Inbuf, +}; + +/* + * [Decoder Buffer OPS] Output + */ +static ExynosVideoDecBufferOps defOutbufOps = { + .nSize = 0, + .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf, + .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf, + .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf, + .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf, + .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf, + .Setup = MFC_Decoder_Setup_Outbuf, + .Run = MFC_Decoder_Run_Outbuf, + .Stop = MFC_Decoder_Stop_Outbuf, + .Enqueue = MFC_Decoder_Enqueue_Outbuf, + .Enqueue_All = NULL, + .Dequeue = MFC_Decoder_Dequeue_Outbuf, + .Register = MFC_Decoder_Register_Outbuf, + .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf, + .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf, + .Cleanup = MFC_Decoder_Cleanup_Outbuf, +}; + +int Exynos_Video_Register_Decoder( + ExynosVideoDecOps *pDecOps, + ExynosVideoDecBufferOps *pInbufOps, + ExynosVideoDecBufferOps *pOutbufOps) +{ + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + defDecOps.nSize = sizeof(defDecOps); + defInbufOps.nSize = sizeof(defInbufOps); + defOutbufOps.nSize = sizeof(defOutbufOps); + + memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize), + pDecOps->nSize - sizeof(pDecOps->nSize)); + + memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize), + pInbufOps->nSize - sizeof(pInbufOps->nSize)); + + memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize), + pOutbufOps->nSize - sizeof(pOutbufOps->nSize)); + +EXIT: + return ret; +} diff --git a/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c b/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c new file mode 100755 index 0000000..dba248f --- /dev/null +++ b/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c @@ -0,0 +1,2298 @@ +/* + * + * 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 ExynosVideoEncoder.c + * @brief + * @author Hyeyeon Chung (hyeon.chung@samsung.com) + * @author Jinsung Yang (jsgood.yang@samsung.com) + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0.0 + * @history + * 2012.02.09: Initial Version + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "ExynosVideoApi.h" +#include "ExynosVideoEnc.h" + +#include + +/* #define LOG_NDEBUG 0 */ +#define LOG_TAG "ExynosVideoEncoder" +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#include "Exynos_OSAL_Log.h" +#endif + +#define MAX_CTRL_NUM 91 +#define H264_CTRL_NUM 91 +#define MPEG4_CTRL_NUM 26 +#define H263_CTRL_NUM 18 + +/* FIXME: build error related with kernel-header pkg */ +#ifndef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR +#define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46) +#endif + +/* + * [Common] __CodingType_To_V4L2PixelFormat + */ +static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType) +{ + unsigned int pixelformat = V4L2_PIX_FMT_H264; + + switch (codingType) { + case VIDEO_CODING_AVC: + pixelformat = V4L2_PIX_FMT_H264; + break; + case VIDEO_CODING_MPEG4: + pixelformat = V4L2_PIX_FMT_MPEG4; + break; + case VIDEO_CODING_VP8: + pixelformat = V4L2_PIX_FMT_VP8; + break; + case VIDEO_CODING_H263: + pixelformat = V4L2_PIX_FMT_H263; + break; + case VIDEO_CODING_VC1: + pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G; + break; + case VIDEO_CODING_VC1_RCV: + pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L; + break; + case VIDEO_CODING_MPEG2: + pixelformat = V4L2_PIX_FMT_MPEG2; + break; + default: + pixelformat = V4L2_PIX_FMT_H264; + break; + } + + return pixelformat; +} + +/* + * [Common] __ColorFormatType_To_V4L2PixelFormat + */ +static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType) +{ + unsigned int pixelformat = V4L2_PIX_FMT_NV12M; + + switch (colorFormatType) { + case VIDEO_COLORFORMAT_NV12_TILED: +#ifdef EXYNOS_3250 + pixelformat = V4L2_PIX_FMT_NV12MT_16X16; +#else + pixelformat = V4L2_PIX_FMT_NV12MT; +#endif + break; +#if 0 + case VIDEO_COLORFORMAT_NV21: + pixelformat = V4L2_PIX_FMT_NV21M; + break; +#endif + case VIDEO_COLORFORMAT_NV12: + default: + pixelformat = V4L2_PIX_FMT_NV12M; + break; + } + + return pixelformat; +} + +/* + * [Encoder OPS] Init + */ +static void *MFC_Encoder_Init(int nMemoryType) +{ + ExynosVideoEncContext *pCtx = NULL; + pthread_mutex_t *pMutex = NULL; + int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING); + + pCtx = (ExynosVideoEncContext *)malloc(sizeof(*pCtx)); + if (pCtx == NULL) { + ALOGE("%s: Failed to allocate encoder context buffer", __func__); + goto EXIT_ALLOC_FAIL; + } + + memset(pCtx, 0, sizeof(*pCtx)); + + __ta__("exynos_v4l2_open_devname : VIDEO_ENCODER_NAME", + pCtx->hEnc = exynos_v4l2_open_devname(VIDEO_ENCODER_NAME, O_RDWR, 0); + ); + if (pCtx->hEnc < 0) { + ALOGE("%s: Failed to open encoder device", __func__); + goto EXIT_OPEN_FAIL; + } + + __ta__("exynos_v4l2_querycap", + if (!exynos_v4l2_querycap(pCtx->hEnc, needCaps)) { + ALOGE("%s: Failed to querycap", __func__); + goto EXIT_QUERYCAP_FAIL; + } + ); + + pCtx->bStreamonInbuf = VIDEO_FALSE; + pCtx->bStreamonOutbuf = VIDEO_FALSE; + + pCtx->nMemoryType = nMemoryType; + + pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (pMutex == NULL) { + ALOGE("%s: Failed to allocate mutex about input buffer", __func__); + goto EXIT_QUERYCAP_FAIL; + } + if (pthread_mutex_init(pMutex, NULL) != 0) { + free(pMutex); + goto EXIT_QUERYCAP_FAIL; + } + pCtx->pInMutex = (void*)pMutex; + + pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (pMutex == NULL) { + ALOGE("%s: Failed to allocate mutex about output buffer", __func__); + goto EXIT_QUERYCAP_FAIL; + } + if (pthread_mutex_init(pMutex, NULL) != 0) { + free(pMutex); + goto EXIT_QUERYCAP_FAIL; + } + pCtx->pOutMutex = (void*)pMutex; + + return (void *)pCtx; + +EXIT_QUERYCAP_FAIL: + if (pCtx->pInMutex != NULL) { + pthread_mutex_destroy(pCtx->pInMutex); + free(pCtx->pInMutex); + } + + if (pCtx->pOutMutex != NULL) { + pthread_mutex_destroy(pCtx->pOutMutex); + free(pCtx->pOutMutex); + } + + close(pCtx->hEnc); + +EXIT_OPEN_FAIL: + free(pCtx); + +EXIT_ALLOC_FAIL: + return NULL; +} + +/* + * [Encoder OPS] Finalize + */ +static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + pthread_mutex_t *pMutex = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->pOutMutex != NULL) { + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_destroy(pMutex); + free(pMutex); + pCtx->pOutMutex = NULL; + } + + if (pCtx->pInMutex != NULL) { + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_destroy(pMutex); + free(pMutex); + pCtx->pInMutex = NULL; + } + + if (pCtx->bShareInbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nInbufs; i++) { + for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) { + pVideoPlane = &pCtx->pInbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pInbuf[i].pGeometry = NULL; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nOutbufs; i++) { + for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + if (pVideoPlane->addr != NULL) { + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + pVideoPlane->addr = NULL; + pVideoPlane->allocSize = 0; + pVideoPlane->dataSize = 0; + } + + pCtx->pOutbuf[i].pGeometry = NULL; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE; + } + } + } + + if (pCtx->pInbuf != NULL) + free(pCtx->pInbuf); + + if (pCtx->pOutbuf != NULL) + free(pCtx->pOutbuf); + + if (pCtx->hEnc > 0) + close(pCtx->hEnc); + + free(pCtx); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set Extended Control + */ +static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( + void *pHandle, + ExynosVideoEncParam *pEncParam) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoEncInitParam *pInitParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + int i; + struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM]; + struct v4l2_ext_controls ext_ctrls; + int k = 0; + + if ((pCtx == NULL) || (pEncParam == NULL)) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + pInitParam = &pEncParam->initParam; + pCommonParam = &pEncParam->commonParam; + + /* common parameters */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE; + ext_ctrl[k++].value = pCommonParam->IDRPeriod; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + ext_ctrl[k++].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB; + ext_ctrl[k++].value = pCommonParam->RandomIntraMBRefresh; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING; + ext_ctrl[k++].value = pCommonParam->PadControlOn; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV; + ext_ctrl[k].value = pCommonParam->CrPadVal; + ext_ctrl[k].value |= (pCommonParam->CbPadVal << 8); + ext_ctrl[k++].value |= (pCommonParam->LumaPadVal << 16); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE; + ext_ctrl[k++].value = pCommonParam->EnableFRMRateControl; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE; + ext_ctrl[k++].value = pCommonParam->EnableMBRateControl; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_BITRATE; + + /* FIXME temporary fix */ + if (pCommonParam->Bitrate) + ext_ctrl[k++].value = pCommonParam->Bitrate; + else + ext_ctrl[k++].value = 1; /* just for testing Movie studio */ + + /* codec specific parameters */ + switch (pEncParam->eCompressionFormat) { + case VIDEO_CODING_AVC: + { + ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264; + + /* common parameters but id is depends on codec */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp_P; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMax; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMin; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF; + ext_ctrl[k++].value = pCommonParam->CBRPeriodRf; + + /* H.264 specific parameters */ + switch (pCommonParam->SliceMode) { + case 0: + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = 1; /* default */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = 2800; /* based on MFC6.x */ + break; + case 1: + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = pH264Param->SliceArgument; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = 2800; /* based on MFC6.x */ + break; + case 2: /* Fixed Byte number Slice mode */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = 1; /* default */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = pH264Param->SliceArgument; + break; + default: + break; + } + + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; + ext_ctrl[k++].value = pH264Param->ProfileIDC; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; + ext_ctrl[k++].value = pH264Param->LevelIDC; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P; + ext_ctrl[k++].value = pH264Param->NumberRefForPframes; + /* + * It should be set using h264Param->NumberBFrames after being handled by appl. + */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES; + ext_ctrl[k++].value = pH264Param->NumberBFrames; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; + ext_ctrl[k++].value = pH264Param->LoopFilterDisable; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; + ext_ctrl[k++].value = pH264Param->LoopFilterAlphaC0Offset; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; + ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; + ext_ctrl[k++].value = pH264Param->SymbolMode; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE; + ext_ctrl[k++].value = pH264Param->PictureInterlace; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM; + ext_ctrl[k++].value = pH264Param->Transform8x8Mode; + + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE; + ext_ctrl[k++].value = pH264Param->FrameRate; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; + ext_ctrl[k++].value = pH264Param->FrameQp_B; + + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK; + ext_ctrl[k++].value = pH264Param->DarkDisable; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH; + ext_ctrl[k++].value = pH264Param->SmoothDisable; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC; + ext_ctrl[k++].value = pH264Param->StaticDisable; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY; + ext_ctrl[k++].value = pH264Param->ActivityDisable; + + /* doesn't have to be set */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE; + ext_ctrl[k++].value = 1; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD; + ext_ctrl[k++].value = 10; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header, 1: header + first frame */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT; + ext_ctrl[k++].value = 0; + + /* Initial parameters : Frame Skip */ + switch (pInitParam->FrameSkip) { + case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT: + + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT; + break; + case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT: + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT; + break; + default: + /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED; + break; + } + + /* SVC is not supported yet */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER; + ext_ctrl[k++].value = 3; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP; + ext_ctrl[k++].value = (0 << 16 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP; + ext_ctrl[k++].value = (1 << 16 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP; + ext_ctrl[k++].value = (2 << 16 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE; + + /* FMO is not supported yet */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP; + ext_ctrl[k++].value = 4; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH; + ext_ctrl[k++].value = (0 << 30 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH; + ext_ctrl[k++].value = (1 << 30 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH; + ext_ctrl[k++].value = (2 << 30 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH; + ext_ctrl[k++].value = (3 << 30 | 0); + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE; + ext_ctrl[k++].value = 0; + + /* ASO is not supported yet */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO; + ext_ctrl[k++].value = 0; + + for (i = 0; i < 32; i++) { + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER; + ext_ctrl[k++].value = (i << 16 | 0); + } + + ext_ctrls.count = H264_CTRL_NUM; + break; + } + + case VIDEO_CODING_MPEG4: + { + ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4; + + /* common parameters but id is depends on codec */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp_P; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMax; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMin; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF; + ext_ctrl[k++].value = pCommonParam->CBRPeriodRf; + + /* MPEG4 specific parameters */ + switch (pCommonParam->SliceMode) { + case 0: + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = 1; /* default */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = 2800; /* based on MFC6.x */ + break; + case 1: + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = pMpeg4Param->SliceArgument; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = 2800; /* based on MFC6.x */ + break; + case 2: + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + ext_ctrl[k++].value = 1; /* default */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + ext_ctrl[k++].value = pMpeg4Param->SliceArgument; + break; + default: + break; + } + + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; + ext_ctrl[k++].value = pMpeg4Param->ProfileIDC; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; + ext_ctrl[k++].value = pMpeg4Param->LevelIDC; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL; + ext_ctrl[k++].value = pMpeg4Param->DisableQpelME; + + /* + * It should be set using mpeg4Param->NumberBFrames after being handled by appl. + */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES; + ext_ctrl[k++].value = pMpeg4Param->NumberBFrames; + + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES; + ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA; + ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament; + + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP; + ext_ctrl[k++].value = pMpeg4Param->FrameQp_B; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT; + ext_ctrl[k++].value = 1; + + /* Initial parameters : Frame Skip */ + switch (pInitParam->FrameSkip) { + case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT: + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT; + break; + case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT: + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT; + break; + default: + /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED; + break; + } + + ext_ctrls.count = MPEG4_CTRL_NUM; + break; + } + + case VIDEO_CODING_H263: + { + ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263; + + /* common parameters but id is depends on codec */ + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP; + ext_ctrl[k++].value = pCommonParam->FrameQp_P; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMax; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP; + ext_ctrl[k++].value = pCommonParam->QSCodeMin; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF; + ext_ctrl[k++].value = pCommonParam->CBRPeriodRf; + + /* H263 specific parameters */ + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE; + ext_ctrl[k++].value = pH263Param->FrameRate; + + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE; + ext_ctrl[k++].value = 0; + ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; + ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT; + ext_ctrl[k++].value = 1; + + /* Initial parameters : Frame Skip */ + switch (pInitParam->FrameSkip) { + case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT: + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT; + break; + case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT: + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT; + break; + default: + /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */ + ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE; + ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED; + break; + } + ext_ctrls.count = H263_CTRL_NUM; + break; + } + + default: + ALOGE("[%s] Undefined codec type",__func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ext_ctrls.controls = ext_ctrl; + + __ta__("exynos_v4l2_s_ext_ctrl", + if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) { + ALOGE("%s: Failed to s_ext_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set Frame Tag + */ +static ExynosVideoErrorType MFC_Encoder_Set_FrameTag( + void *pHandle, + int frameTag) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Get Frame Tag + */ +static int MFC_Encoder_Get_FrameTag(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + int frameTag = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", + if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) { + ALOGE("%s: Failed to g_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return frameTag; +} + +/* + * [Encoder OPS] Set Frame Type + */ +static ExynosVideoErrorType MFC_Encoder_Set_FrameType( + void *pHandle, + ExynosVideoFrameType frameType) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set Frame Rate + */ +static ExynosVideoErrorType MFC_Encoder_Set_FrameRate( + void *pHandle, + int frameRate) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set Bit Rate + */ +static ExynosVideoErrorType MFC_Encoder_Set_BitRate( + void *pHandle, + int bitRate) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set Frame Skip + */ +static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip( + void *pHandle, + int frameSkip) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Set IDR Period + */ +static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod( + void *pHandle, + int IDRPeriod) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_I_PERIOD", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames + */ +static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) { + ALOGE("%s: Failed to s_ctrl", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Enable Cacheable (Input) + */ +static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) { + ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Enable Cacheable (Output) + */ +static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) { + ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Set Shareable Buffer (Input) + */ +static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + pCtx->bShareInbuf = VIDEO_TRUE; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Set Shareable Buffer (Output) + */ +static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + pCtx->bShareOutbuf = VIDEO_TRUE; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Get Buffer (Input) + */ +static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf( + void *pHandle, + int nIndex, + ExynosVideoBuffer **pBuffer) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + *pBuffer = NULL; + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + + if (pCtx->nInbufs <= nIndex) { + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex]; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Get Buffer (Output) + */ +static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf( + void *pHandle, + int nIndex, + ExynosVideoBuffer **pBuffer) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + *pBuffer = NULL; + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + + if (pCtx->nOutbufs <= nIndex) { + *pBuffer = NULL; + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex]; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Set Geometry (Src) + */ +static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat); + fmt.fmt.pix_mp.width = bufferConf->nFrameWidth; + fmt.fmt.pix_mp.height = bufferConf->nFrameHeight; + fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES; + + __ta__("exynos_v4l2_s_fmt : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) { + ALOGE("%s: Failed to s_fmt", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry)); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Get Geometry (Src) + */ +static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + __ta__("exynos_v4l2_g_fmt : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) { + ALOGE("%s: Failed to g_fmt", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + bufferConf->nFrameHeight = fmt.fmt.pix_mp.width; + bufferConf->nFrameHeight = fmt.fmt.pix_mp.height; + bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Set Geometry (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat); + fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage; + + __ta__("exynos_v4l2_s_fmt : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) { + ALOGE("%s: Failed to s_fmt", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry)); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Get Geometry (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf( + void *pHandle, + ExynosVideoGeometry *bufferConf) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_format fmt; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (bufferConf == NULL) { + ALOGE("%s: Buffer geometry must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&fmt, 0, sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + __ta__("exynos_v4l2_g_fmt : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) { + ALOGE("%s: Failed to g_fmt", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Setup (Src) + */ +static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf( + void *pHandle, + unsigned int nBufferCount) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES]; + int i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (nBufferCount == 0) { + ALOGE("%s: Buffer count must be greater than 0", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareInbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) { + ALOGE("Failed to require buffer"); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + pCtx->nInbufs = (int)req.count; + + pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs); + if (pCtx->pInbuf == NULL) { + ALOGE("%s: Failed to allocate input buffer context", __func__); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs); + + memset(&buf, 0, sizeof(buf)); + + if (pCtx->bShareInbuf == VIDEO_FALSE) { + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = VIDEO_ENCODER_INBUF_PLANES; + + for (i = 0; i < pCtx->nInbufs; i++) { + buf.index = i; + __ta__("exynos_v4l2_querybuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) { + ALOGE("%s: Failed to querybuf", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) { + pVideoPlane = &pCtx->pInbuf[i].planes[j]; + __ta__("mmap : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + pVideoPlane->addr = mmap(NULL, + buf.m.planes[j].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset); + ); + + if (pVideoPlane->addr == MAP_FAILED) { + ALOGE("%s: Failed to map", __func__); + ret = VIDEO_ERROR_MAPFAIL; + goto EXIT; + } + + pVideoPlane->allocSize = buf.m.planes[j].length; + pVideoPlane->dataSize = 0; + } + + pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_TRUE; + + } + } else { + for (i = 0; i < pCtx->nInbufs; i++) { + pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry; + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + pCtx->pInbuf[i].bRegistered = VIDEO_FALSE; + } + } + + return ret; + +EXIT: + if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) { + if (pCtx->bShareInbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nInbufs; i++) { + for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) { + pVideoPlane = &pCtx->pInbuf[i].planes[j]; + if (pVideoPlane->addr == MAP_FAILED) { + pVideoPlane->addr = NULL; + break; + } + + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + } + } + } + + free(pCtx->pInbuf); + } + + return ret; +} + +/* + * [Encoder Buffer OPS] Setup (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf( + void *pHandle, + unsigned int nBufferCount) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoPlane *pVideoPlane = NULL; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct v4l2_requestbuffers req; + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES]; + int i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (nBufferCount == 0) { + ALOGE("%s: Buffer count must be greater than 0", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&req, 0, sizeof(req)); + + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + req.count = nBufferCount; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + req.memory = pCtx->nMemoryType; + else + req.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) { + ALOGE("%s: Failed to reqbuf", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + pCtx->nOutbufs = req.count; + + pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); + if (pCtx->pOutbuf == NULL) { + ALOGE("%s: Failed to allocate output buffer context", __func__); + ret = VIDEO_ERROR_NOMEM; + goto EXIT; + } + memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); + + memset(&buf, 0, sizeof(buf)); + + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_MMAP; + buf.m.planes = planes; + buf.length = VIDEO_ENCODER_OUTBUF_PLANES; + + for (i = 0; i < pCtx->nOutbufs; i++) { + buf.index = i; + __ta__("exynos_v4l2_querybuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) { + ALOGE("%s: Failed to querybuf", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + __ta__("mmap : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + pVideoPlane->addr = mmap(NULL, + buf.m.planes[j].length, PROT_READ | PROT_WRITE, + MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset); + ); + + if (pVideoPlane->addr == MAP_FAILED) { + ALOGE("%s: Failed to map", __func__); + ret = VIDEO_ERROR_MAPFAIL; + goto EXIT; + } + + pVideoPlane->allocSize = buf.m.planes[j].length; + pVideoPlane->dataSize = 0; + } + + pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE; + } + } else { + for (i = 0; i < pCtx->nOutbufs; i++ ) { + pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE; + } + } + + return ret; + +EXIT: + if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) { + if (pCtx->bShareOutbuf == VIDEO_FALSE) { + for (i = 0; i < pCtx->nOutbufs; i++) { + for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) { + pVideoPlane = &pCtx->pOutbuf[i].planes[j]; + if (pVideoPlane->addr == MAP_FAILED) { + pVideoPlane->addr = NULL; + break; + } + + munmap(pVideoPlane->addr, pVideoPlane->allocSize); + } + } + } + + free(pCtx->pOutbuf); + } + + return ret; +} + +/* + * [Encoder Buffer OPS] Run (src) + */ +static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_FALSE) { + __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { + ALOGE("%s: Failed to streamon for input buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + pCtx->bStreamonInbuf = VIDEO_TRUE; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Run (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { + ALOGE("%s: Failed to streamon for output buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + pCtx->bStreamonOutbuf = VIDEO_TRUE; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Stop (Src) + */ +static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_TRUE) { + __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { + ALOGE("%s: Failed to streamoff for input buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + pCtx->bStreamonInbuf = VIDEO_FALSE; + } + + for (i = 0; i < pCtx->nInbufs; i++) { + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Stop (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_TRUE) { + __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { + ALOGE("%s: Failed to streamoff for output buffer", __func__); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + pCtx->bStreamonOutbuf = VIDEO_FALSE; + } + + for (i = 0; i < pCtx->nOutbufs; i++) { + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Wait (Src) + */ +static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct pollfd poll_events; + int poll_state; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + poll_events.fd = pCtx->hEnc; + poll_events.events = POLLOUT | POLLERR; + poll_events.revents = 0; + + do { + poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT); + if (poll_state > 0) { + if (poll_events.revents & POLLOUT) { + break; + } else { + ALOGE("%s: Poll return error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } + } else if (poll_state < 0) { + ALOGE("%s: Poll state error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } + } while (poll_state == 0); + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Wait (Dst) + */ +static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + struct pollfd poll_events; + int poll_state; + int bframe_count = 0; // FIXME + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + poll_events.fd = pCtx->hEnc; + poll_events.events = POLLIN | POLLERR; + poll_events.revents = 0; + + do { + poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT); + if (poll_state > 0) { + if (poll_events.revents & POLLIN) { + break; + } else { + ALOGE("%s: Poll return error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } + } else if (poll_state < 0) { + ALOGE("%s: Poll state error", __func__); + ret = VIDEO_ERROR_POLL; + break; + } else { + bframe_count++; // FIXME + } + } while (poll_state == 0 && bframe_count < 5); // FIXME + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Encoder_Register_Inbuf( + void *pHandle, + ExynosVideoPlane *planes, + int nPlanes) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex; + + if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_INBUF_PLANES)) { + ALOGE("%s: input params must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) { + int plane; + for (plane = 0; plane < nPlanes; plane++) { + pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr; + pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; + pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd; + ALOGE("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr); + } + pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE; + break; + } + } + + if (nIndex == pCtx->nInbufs) { + ALOGE("%s: can not find non-registered input buffer", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Encoder_Register_Outbuf( + void *pHandle, + ExynosVideoPlane *planes, + int nPlanes) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex; + + if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_OUTBUF_PLANES)) { + ALOGE("%s: params must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) { + int plane; + for (plane = 0; plane < nPlanes; plane++) { + pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr; + pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; + pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd; + } + pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE; + break; + } + } + + if (nIndex == pCtx->nOutbufs) { + ALOGE("%s: can not find non-registered output buffer", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + pCtx->pInbuf[nIndex].planes[0].addr = NULL; + pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + pCtx->pOutbuf[nIndex].planes[0].addr = NULL; + pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Find (Input) + */ +static int MFC_Encoder_Find_Inbuf( + void *pHandle, + unsigned char *pBuffer) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { + if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) { + if ((pBuffer == NULL) || + (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer)) + break; + } + } + + if (nIndex == pCtx->nInbufs) + nIndex = -1; + +EXIT: + return nIndex; +} + +/* + * [Encoder Buffer OPS] Find (Output) + */ +static int MFC_Encoder_Find_Outbuf( + void *pHandle, + unsigned char *pBuffer) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) { + if ((pBuffer == NULL) || + (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer)) + break; + } + } + + if (nIndex == pCtx->nOutbufs) + nIndex = -1; + +EXIT: + return nIndex; +} + +/* + * [Encoder Buffer OPS] Enqueue (Input) + */ +static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf( + void *pHandle, + unsigned char *pBuffer[], + unsigned int dataSize[], + int nPlanes, + void *pPrivate) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + + struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES]; + struct v4l2_buffer buf; + int index, i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) { + ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, + VIDEO_ENCODER_INBUF_PLANES, nPlanes); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.m.planes = planes; + buf.length = VIDEO_ENCODER_INBUF_PLANES; + + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_lock(pMutex); + index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]); + if (index == -1) { + pthread_mutex_unlock(pMutex); + ALOGE("%s: Failed to get index", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + + buf.index = index; + pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; + pthread_mutex_unlock(pMutex); + + if (pCtx->bShareInbuf == VIDEO_TRUE) { + buf.memory = pCtx->nMemoryType; + + for (i = 0; i < nPlanes; i++) { + /* V4L2_MEMORY_USERPTR */ + buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; + buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize; + /* V4L2_MEMORY_DMABUF */ +#ifdef SLP_PLATFORM /* #ifdef USE_DMA_BUF */ + buf.m.planes[i].m.fd = pCtx->pInbuf[buf.index].planes[i].fd; + buf.m.planes[i].length = 0; /* kernel give the length */ +#endif + buf.m.planes[i].bytesused = dataSize[i]; + } + } else { + buf.memory = V4L2_MEMORY_MMAP; + for (i = 0; i < nPlanes; i++) + buf.m.planes[i].bytesused = dataSize[i]; + } + + __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { + ALOGE("%s: Failed to enqueue input buffer", __func__); + pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + pCtx->pInbuf[buf.index].pPrivate = pPrivate; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Enqueue (Output) + */ +static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf( + void *pHandle, + unsigned char *pBuffer[], + unsigned int dataSize[], + int nPlanes, + void *pPrivate) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + + struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES]; + struct v4l2_buffer buf; + int i, index; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (VIDEO_ENCODER_OUTBUF_PLANES < nPlanes) { + ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, + VIDEO_ENCODER_OUTBUF_PLANES, nPlanes); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.m.planes = planes; + buf.length = VIDEO_ENCODER_OUTBUF_PLANES; + + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]); + if (index == -1) { + pthread_mutex_unlock(pMutex); + ALOGE("%s: Failed to get index", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + buf.index = index; + pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; + pthread_mutex_unlock(pMutex); + + if (pCtx->bShareOutbuf == VIDEO_TRUE) { + buf.memory = pCtx->nMemoryType; + for (i = 0; i < nPlanes; i++) { + /* V4L2_MEMORY_USERPTR */ + buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; + buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize; + /* V4L2_MEMORY_DMABUF */ +#ifdef USE_DMA_BUF + buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd; + buf.m.planes[i].length = 0; /* kernel give the length */ +#endif + buf.m.planes[i].bytesused = dataSize[i]; + } + } else { + buf.memory = V4L2_MEMORY_MMAP; + } + + __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { + ALOGE("%s: Failed to enqueue output buffer", __func__); + pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + ); + + pCtx->pOutbuf[buf.index].pPrivate = pPrivate; + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Enqueue All (Output) + */ +static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + unsigned char *pBuffer[VIDEO_BUFFER_MAX_PLANES] = {NULL, }; + unsigned int dataSize[VIDEO_BUFFER_MAX_PLANES] = {0, }; + + int i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (i = 0; i < pCtx->nOutbufs; i++) { + ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, dataSize, 1, NULL); + if (ret != VIDEO_ERROR_NONE) + goto EXIT; + } + +EXIT: + return ret; +} + +/* + * [Encoder Buffer OPS] Dequeue (Input) + */ +static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoBuffer *pInbuf = NULL; + + struct v4l2_buffer buf; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + if (pCtx->bStreamonInbuf == VIDEO_FALSE) { + pInbuf = NULL; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + if (pCtx->bShareInbuf == VIDEO_TRUE) + buf.memory = pCtx->nMemoryType; + else + buf.memory = V4L2_MEMORY_MMAP; + + __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) { + pInbuf = NULL; + goto EXIT; + } + ); + + pInbuf = &pCtx->pInbuf[buf.index]; + pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + +EXIT: + return pInbuf; +} + +/* + * [Encoder Buffer OPS] Dequeue (Output) + */ +static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoBuffer *pOutbuf = NULL; + + struct v4l2_buffer buf; + struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES]; + int value; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + pOutbuf = NULL; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.m.planes = planes; + buf.length = 1; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + buf.memory = pCtx->nMemoryType; + else + buf.memory = V4L2_MEMORY_MMAP; + + /* no error case for output buffer dequeue in encoder */ + __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", + if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) { + goto EXIT; + } + ); + + pOutbuf = &pCtx->pOutbuf[buf.index]; + pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused; + + switch (buf.flags & (0x7 << 3)) { + case V4L2_BUF_FLAG_KEYFRAME: + pOutbuf->frameType = VIDEO_FRAME_I; + break; + case V4L2_BUF_FLAG_PFRAME: + pOutbuf->frameType = VIDEO_FRAME_P; + break; + case V4L2_BUF_FLAG_BFRAME: + pOutbuf->frameType = VIDEO_FRAME_B; + break; + default: + ALOGI("%s: encoded frame type is = %d",__func__, (buf.flags & (0x7 << 3))); + pOutbuf->frameType = VIDEO_FRAME_OTHERS; + break; + }; + + pOutbuf->bQueued = VIDEO_FALSE; + +EXIT: + return pOutbuf; +} + +static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (i = 0; i < pCtx->nInbufs; i++) { + pCtx->pInbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle) +{ + ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + int i = 0; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + for (i = 0; i < pCtx->nOutbufs; i++) { + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + } + +EXIT: + return ret; +} + +/* + * [Encoder OPS] Common + */ +static ExynosVideoEncOps defEncOps = { + .nSize = 0, + .Init = MFC_Encoder_Init, + .Finalize = MFC_Encoder_Finalize, + .Set_EncParam = MFC_Encoder_Set_EncParam, + .Set_FrameType = MFC_Encoder_Set_FrameType, + .Set_FrameRate = MFC_Encoder_Set_FrameRate, + .Set_BitRate = MFC_Encoder_Set_BitRate, + .Set_FrameSkip = MFC_Encoder_Set_FrameSkip, + .Set_IDRPeriod = MFC_Encoder_Set_IDRPeriod, + .Set_FrameTag = MFC_Encoder_Set_FrameTag, + .Get_FrameTag = MFC_Encoder_Get_FrameTag, + .Enable_PrependSpsPpsToIdr = MFC_Encoder_Enable_PrependSpsPpsToIdr, +}; + +/* + * [Encoder Buffer OPS] Input + */ +static ExynosVideoEncBufferOps defInbufOps = { + .nSize = 0, + .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Inbuf, + .Set_Shareable = MFC_Encoder_Set_Shareable_Inbuf, + .Get_Buffer = MFC_Encoder_Get_Buffer_Inbuf, + .Set_Geometry = MFC_Encoder_Set_Geometry_Inbuf, + .Get_Geometry = MFC_Encoder_Get_Geometry_Inbuf, + .Setup = MFC_Encoder_Setup_Inbuf, + .Run = MFC_Encoder_Run_Inbuf, + .Stop = MFC_Encoder_Stop_Inbuf, + .Enqueue = MFC_Encoder_Enqueue_Inbuf, + .Enqueue_All = NULL, + .Dequeue = MFC_Encoder_Dequeue_Inbuf, + .Register = MFC_Encoder_Register_Inbuf, + .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf, + .Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf, +}; + +/* + * [Encoder Buffer OPS] Output + */ +static ExynosVideoEncBufferOps defOutbufOps = { + .nSize = 0, + .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Outbuf, + .Set_Shareable = MFC_Encoder_Set_Shareable_Outbuf, + .Get_Buffer = MFC_Encoder_Get_Buffer_Outbuf, + .Set_Geometry = MFC_Encoder_Set_Geometry_Outbuf, + .Get_Geometry = MFC_Encoder_Get_Geometry_Outbuf, + .Setup = MFC_Encoder_Setup_Outbuf, + .Run = MFC_Encoder_Run_Outbuf, + .Stop = MFC_Encoder_Stop_Outbuf, + .Enqueue = MFC_Encoder_Enqueue_Outbuf, + .Enqueue_All = NULL, + .Dequeue = MFC_Encoder_Dequeue_Outbuf, + .Register = MFC_Encoder_Register_Outbuf, + .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf, + .Clear_Queue = MFC_Encoder_Clear_Queued_Outbuf, +}; + +int Exynos_Video_Register_Encoder( + ExynosVideoEncOps *pEncOps, + ExynosVideoEncBufferOps *pInbufOps, + ExynosVideoEncBufferOps *pOutbufOps) +{ + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + defEncOps.nSize = sizeof(defEncOps); + defInbufOps.nSize = sizeof(defInbufOps); + defOutbufOps.nSize = sizeof(defOutbufOps); + + memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize), + pEncOps->nSize - sizeof(pEncOps->nSize)); + + memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize), + pInbufOps->nSize - sizeof(pInbufOps->nSize)); + + memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize), + pOutbufOps->nSize - sizeof(pOutbufOps->nSize)); + +EXIT: + return ret; +} diff --git a/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h b/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h new file mode 100644 index 0000000..8132417 --- /dev/null +++ b/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h @@ -0,0 +1,308 @@ +/* + * + * 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. + */ + +#ifndef _EXYNOS_VIDEO_API_H_ +#define _EXYNOS_VIDEO_API_H_ + +#include "exynos_v4l2.h" + +/* Fixed */ +#define VIDEO_BUFFER_MAX_PLANES 3 + +typedef enum _ExynosVideoBoolType { + VIDEO_FALSE = 0, + VIDEO_TRUE = 1, +} ExynosVideoBoolType; + +typedef enum _ExynosVideoErrorType { + VIDEO_ERROR_NONE = 1, + VIDEO_ERROR_BADPARAM = -1, + VIDEO_ERROR_OPENFAIL = -2, + VIDEO_ERROR_NOMEM = -3, + VIDEO_ERROR_APIFAIL = -4, + VIDEO_ERROR_MAPFAIL = -5, + VIDEO_ERROR_NOBUFFERS = -6, + VIDEO_ERROR_POLL = -7, + VIDEO_ERROR_DQBUF_EIO = -8, +} ExynosVideoErrorType; + +typedef enum _ExynosVideoCodingType { + VIDEO_CODING_UNKNOWN = 0, + VIDEO_CODING_MPEG2, + VIDEO_CODING_H263, + VIDEO_CODING_MPEG4, + VIDEO_CODING_VC1, + VIDEO_CODING_VC1_RCV, + VIDEO_CODING_AVC, + VIDEO_CODING_MVC, + VIDEO_CODING_VP8, + VIDEO_CODING_RESERVED, +} ExynosVideoCodingType; + +typedef enum _ExynosVideoColorFormatType { + VIDEO_COLORFORMAT_UNKNOWN = 0, + VIDEO_COLORFORMAT_NV12, + VIDEO_COLORFORMAT_NV21, + VIDEO_COLORFORMAT_NV12_TILED, + VIDEO_COLORFORMAT_RESERVED, +} ExynosVideoColorFormatType; + +typedef enum _ExynosVideoFrameType { + VIDEO_FRAME_NOT_CODED = 0, + VIDEO_FRAME_I, + VIDEO_FRAME_P, + VIDEO_FRAME_B, + VIDEO_FRAME_SKIPPED, + VIDEO_FRAME_OTHERS, +} ExynosVideoFrameType; + +typedef enum _ExynosVideoFrameStatusType { + VIDEO_FRAME_STATUS_UNKNOWN = 0, + VIDEO_FRAME_STATUS_DECODING_ONLY, + VIDEO_FRAME_STATUS_DISPLAY_DECODING, + VIDEO_FRAME_STATUS_DISPLAY_ONLY, + VIDEO_FRAME_STATUS_DECODING_FINISHED, + VIDEO_FRAME_STATUS_CHANGE_RESOL, +} ExynosVideoFrameStatusType; + +typedef enum _ExynosVideoFrameSkipMode { + VIDEO_FRAME_SKIP_DISABLED = 0, + VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT, + VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, +} ExynosVideoFrameSkipMode; + +typedef struct _ExynosVideoRect { + unsigned int nTop; + unsigned int nLeft; + unsigned int nWidth; + unsigned int nHeight; +} ExynosVideoRect; + +typedef struct _ExynosVideoGeometry { + unsigned int nFrameWidth; + unsigned int nFrameHeight; + unsigned int nSizeImage; + ExynosVideoRect cropRect; + ExynosVideoCodingType eCompressionFormat; + ExynosVideoColorFormatType eColorFormat; +} ExynosVideoGeometry; + +typedef struct _ExynosVideoPlane { + void *addr; + unsigned int allocSize; + unsigned int dataSize; + unsigned long offset; + int fd; +} ExynosVideoPlane; + +typedef struct _ExynosVideoBuffer { + ExynosVideoPlane planes[VIDEO_BUFFER_MAX_PLANES]; + ExynosVideoGeometry *pGeometry; + ExynosVideoFrameStatusType displayStatus; + ExynosVideoFrameType frameType; + ExynosVideoBoolType bQueued; + ExynosVideoBoolType bRegistered; + void *pPrivate; +} ExynosVideoBuffer; + +typedef struct _ExynosVideoFramePacking{ + 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; +} ExynosVideoFramePacking; + +typedef struct _ExynosVideoEncInitParam{ + /* Initial parameters */ + ExynosVideoFrameSkipMode FrameSkip; /* [IN] frame skip mode */ + int FMO; + int ASO; +}ExynosVideoEncInitParam; + +typedef struct _ExynosVideoEncCommonParam{ + /* common parameters */ + 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 EnableMBRateControl; /* [IN] Enable macroblock-level rate control */ + 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) */ +}ExynosVideoEncCommonParam; + +typedef struct _ExynosVideoEncH264Param{ + /* 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 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 */ +} ExynosVideoEncH264Param; + +typedef struct _ExynosVideoEncMpeg4Param { + /* 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 */ +} ExynosVideoEncMpeg4Param; + +typedef struct _ExynosVideoEncH263Param { + /* H.263 specific parameters */ + int FrameRate; /* [IN] rate control parameter(frame rate) */ +} ExynosVideoEncH263Param; + +typedef union _ExynosVideoEncCodecParam { + ExynosVideoEncH264Param h264; + ExynosVideoEncMpeg4Param mpeg4; + ExynosVideoEncH263Param h263; +} ExynosVideoEncCodecParam; + +typedef struct _ExynosVideoEncParam { + ExynosVideoCodingType eCompressionFormat; + ExynosVideoEncInitParam initParam; + ExynosVideoEncCommonParam commonParam; + ExynosVideoEncCodecParam codecParam; +} ExynosVideoEncParam; + +typedef struct _ExynosVideoDecOps { + unsigned int nSize; + + void * (*Init)(int nMemoryType); + ExynosVideoErrorType (*Finalize)(void *pHandle); + + /* Add new ops at the end of structure, no order change */ + ExynosVideoErrorType (*Set_FrameTag)(void *pHandle, int frameTag); + int (*Get_FrameTag)(void *pHandle); + int (*Get_ActualBufferCount)(void *pHandle); + ExynosVideoErrorType (*Set_DisplayDelay)(void *pHandle, int delay); + ExynosVideoErrorType (*Enable_PackedPB)(void *pHandle); + ExynosVideoErrorType (*Enable_LoopFilter)(void *pHandle); + ExynosVideoErrorType (*Enable_SliceMode)(void *pHandle); + ExynosVideoErrorType (*Enable_SEIParsing)(void *pHandle); + ExynosVideoErrorType (*Get_FramePackingInfo)(void *pHandle, ExynosVideoFramePacking *pFramepacking); + ExynosVideoErrorType (*Set_ImmediateDisplay)(void *pHandle); + ExynosVideoErrorType (*Enable_DecodeWait)(void *pHandle); +} ExynosVideoDecOps; + +typedef struct _ExynosVideoEncOps { + unsigned int nSize; + void * (*Init)(int nMemoryType); + ExynosVideoErrorType (*Finalize)(void *pHandle); + + /* Add new ops at the end of structure, no order change */ + ExynosVideoErrorType (*Set_EncParam)(void *pHandle, ExynosVideoEncParam*encParam); + ExynosVideoErrorType (*Set_FrameTag)(void *pHandle, int frameTag); + int (*Get_FrameTag)(void *pHandle); + ExynosVideoErrorType (*Set_FrameType)(void *pHandle, int frameType); + ExynosVideoErrorType (*Set_FrameRate)(void *pHandle, int frameRate); + ExynosVideoErrorType (*Set_BitRate)(void *pHandle, int bitRate); + ExynosVideoErrorType (*Set_FrameSkip)(void *pHandle, int frameSkip); + ExynosVideoErrorType (*Set_IDRPeriod)(void *pHandle, int period); + ExynosVideoErrorType (*Enable_PrependSpsPpsToIdr)(void *pHandle); +} ExynosVideoEncOps; + +typedef struct _ExynosVideoDecBufferOps { + unsigned int nSize; + + /* Add new ops at the end of structure, no order change */ + ExynosVideoErrorType (*Enable_Cacheable)(void *pHandle); + ExynosVideoErrorType (*Set_Shareable)(void *pHandle); + ExynosVideoErrorType (*Get_Buffer)(void *pHandle, int nIndex, ExynosVideoBuffer **pBuffer); + ExynosVideoErrorType (*Set_Geometry)(void *pHandle, ExynosVideoGeometry *bufferConf); + ExynosVideoErrorType (*Get_Geometry)(void *pHandle, ExynosVideoGeometry *bufferConf); + ExynosVideoErrorType (*Setup)(void *pHandle, unsigned int nBufferCount); + ExynosVideoErrorType (*Run)(void *pHandle); + ExynosVideoErrorType (*Stop)(void *pHandle); + ExynosVideoErrorType (*Enqueue)(void *pHandle, unsigned char *pBuffer[], unsigned int dataSize[], int nPlanes, void *pPrivate); + ExynosVideoErrorType (*Enqueue_All)(void *pHandle); + ExynosVideoBuffer * (*Dequeue)(void *pHandle); + ExynosVideoErrorType (*Register)(void *pHandle, ExynosVideoPlane *planes, int nPlanes); + ExynosVideoErrorType (*Clear_RegisteredBuffer)(void *pHandle); + ExynosVideoErrorType (*Clear_Queue)(void *pHandle); + ExynosVideoErrorType (*Cleanup)(void *pHandle); +} ExynosVideoDecBufferOps; + +typedef struct _ExynosVideoEncBufferOps { + unsigned int nSize; + + /* Add new ops at the end of structure, no order change */ + ExynosVideoErrorType (*Enable_Cacheable)(void *pHandle); + ExynosVideoErrorType (*Set_Shareable)(void *pHandle); + ExynosVideoErrorType (*Get_Buffer)(void *pHandle, int nIndex, ExynosVideoBuffer **pBuffer); + ExynosVideoErrorType (*Set_Geometry)(void *pHandle, ExynosVideoGeometry *bufferConf); + ExynosVideoErrorType (*Get_Geometry)(void *pHandle, ExynosVideoGeometry *bufferConf); + ExynosVideoErrorType (*Setup)(void *pHandle, unsigned int nBufferCount); + ExynosVideoErrorType (*Run)(void *pHandle); + ExynosVideoErrorType (*Stop)(void *pHandle); + ExynosVideoErrorType (*Enqueue)(void *pHandle, unsigned char *pBuffer[], unsigned int dataSize[], int nPlanes, void *pPrivate); + ExynosVideoErrorType (*Enqueue_All)(void *pHandle); + ExynosVideoBuffer * (*Dequeue)(void *pHandle); + ExynosVideoErrorType (*Register)(void *pHandle, ExynosVideoPlane *planes, int nPlanes); + ExynosVideoErrorType (*Clear_RegisteredBuffer)(void *pHandle); + ExynosVideoErrorType (*Clear_Queue)(void *pHandle); +} ExynosVideoEncBufferOps; + +int Exynos_Video_Register_Decoder( + ExynosVideoDecOps *pDecOps, + ExynosVideoDecBufferOps *pInbufOps, + ExynosVideoDecBufferOps *pOutbufOps); + +int Exynos_Video_Register_Encoder( + ExynosVideoEncOps *pEncOps, + ExynosVideoEncBufferOps *pInbufOps, + ExynosVideoEncBufferOps *pOutbufOps); + +#endif /* _EXYNOS_VIDEO_API_H_ */ diff --git a/exynos4/libcodec/video/v4l2/include/ExynosVideoDec.h b/exynos4/libcodec/video/v4l2/include/ExynosVideoDec.h new file mode 100644 index 0000000..45287b0 --- /dev/null +++ b/exynos4/libcodec/video/v4l2/include/ExynosVideoDec.h @@ -0,0 +1,50 @@ +/* + * + * 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. + */ + +#ifndef _EXYNOS_VIDEO_DEC_H_ +#define _EXYNOS_VIDEO_DEC_H_ + +/* Configurable */ +#define VIDEO_DECODER_NAME "s5p-mfc-dec" +#define VIDEO_DECODER_INBUF_SIZE (1920 * 1080 * 3 / 2) +#define VIDEO_DECODER_INBUF_PLANES 1 +#define VIDEO_DECODER_OUTBUF_PLANES 2 +#define VIDEO_DECODER_POLL_TIMEOUT 25 + +#define OPERATE_BIT(x, mask, shift) ((x & (mask << shift)) >> shift) +#define FRAME_PACK_SEI_INFO_NUM 4 + + +typedef struct _ExynosVideoDecContext { + int hDec; + ExynosVideoBoolType bShareInbuf; + ExynosVideoBoolType bShareOutbuf; + ExynosVideoBuffer *pInbuf; + ExynosVideoBuffer *pOutbuf; + ExynosVideoGeometry inbufGeometry; + ExynosVideoGeometry outbufGeometry; + int nInbufs; + int nOutbufs; + ExynosVideoBoolType bStreamonInbuf; + ExynosVideoBoolType bStreamonOutbuf; + void *pPrivate; + void *pInMutex; + void *pOutMutex; + int nMemoryType; +} ExynosVideoDecContext; + +#endif /* _EXYNOS_VIDEO_DEC_H_ */ diff --git a/exynos4/libcodec/video/v4l2/include/ExynosVideoEnc.h b/exynos4/libcodec/video/v4l2/include/ExynosVideoEnc.h new file mode 100644 index 0000000..5a70fb1 --- /dev/null +++ b/exynos4/libcodec/video/v4l2/include/ExynosVideoEnc.h @@ -0,0 +1,47 @@ +/* + * + * 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. + */ + +#ifndef _EXYNOS_VIDEO_ENC_H_ +#define _EXYNOS_VIDEO_ENC_H_ + +/* Configurable */ +#define VIDEO_ENCODER_NAME "s5p-mfc-enc" +#define VIDEO_ENCODER_INBUF_PLANES 2 +#define VIDEO_ENCODER_OUTBUF_PLANES 1 +#define VIDEO_ENCODER_POLL_TIMEOUT 25 + +typedef struct _ExynosVideoEncContext { + int hEnc; + ExynosVideoBoolType bShareInbuf; + ExynosVideoBoolType bShareOutbuf; + ExynosVideoBuffer *pInbuf; + ExynosVideoBuffer *pOutbuf; + + /* FIXME : temp */ + ExynosVideoGeometry inbufGeometry; + ExynosVideoGeometry outbufGeometry; + int nInbufs; + int nOutbufs; + ExynosVideoBoolType bStreamonInbuf; + ExynosVideoBoolType bStreamonOutbuf; + void *pPrivate; + void *pInMutex; + void *pOutMutex; + int nMemoryType; +} ExynosVideoEncContext; + +#endif /* _EXYNOS_VIDEO_ENC_H_ */ diff --git a/exynos4/libion_exynos/Android.mk b/exynos4/libion_exynos/Android.mk new file mode 100644 index 0000000..1a032fb --- /dev/null +++ b/exynos4/libion_exynos/Android.mk @@ -0,0 +1,33 @@ +# 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. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# HAL module implemenation stored in +# hw/..so +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES:= \ + libion.cpp + +LOCAL_CFLAGS += -DGAIA_FW_BETA + +LOCAL_MODULE := libion_exynos + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/exynos4/libion_exynos/Makefile.am b/exynos4/libion_exynos/Makefile.am new file mode 100644 index 0000000..6ad6f6b --- /dev/null +++ b/exynos4/libion_exynos/Makefile.am @@ -0,0 +1,9 @@ +lib_LTLIBRARIES = libion_exynos.la + +libion_exynos_la_SOURCES = libion.c + +libion_exynos_la_LIBADD = +libion_exynos_la_CFLAGS = -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/openmax/osal + + diff --git a/exynos4/libion_exynos/libion.c b/exynos4/libion_exynos/libion.c new file mode 100644 index 0000000..799593d --- /dev/null +++ b/exynos4/libion_exynos/libion.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 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 +#ifndef SLP_PLATFORM /* build env */ +#include +#endif + +typedef unsigned long ion_handle; + +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_mask; + unsigned int flags; + ion_handle handle; +}; + +struct ion_fd_data { + ion_handle handle; + int fd; +}; + +struct ion_handle_data { + ion_handle handle; +}; + +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define ION_IOC_MAGIC 'I' +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_allocation_data) +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) + +struct ion_msync_data { + long flags; + ion_buffer buf; + size_t size; + off_t offset; +}; + +enum ION_EXYNOS_CUSTOM_CMD { + ION_EXYNOS_CUSTOM_MSYNC +}; + +ion_client ion_client_create(void) +{ + return open("/dev/ion", O_RDWR); +} + +void ion_client_destroy(ion_client client) +{ + close(client); +} + +ion_buffer ion_alloc(ion_client client, size_t len, size_t align, + unsigned int heap_mask, unsigned int flags) +{ + int ret; + struct ion_handle_data arg_free; + struct ion_fd_data arg_share; + struct ion_allocation_data arg_alloc; + + arg_alloc.len = len; + arg_alloc.align = align; + arg_alloc.heap_mask = heap_mask; + arg_alloc.flags = flags; + + ret = ioctl(client, ION_IOC_ALLOC, &arg_alloc); + if (ret < 0) + return ret; + + arg_share.handle = arg_alloc.handle; + ret = ioctl(client, ION_IOC_SHARE, &arg_share); + + arg_free.handle = arg_alloc.handle; + ioctl(client, ION_IOC_FREE, &arg_free); + + if (ret < 0) + return ret; + + return arg_share.fd; +} + +void ion_free(ion_buffer buffer) +{ + close(buffer); +} + +void *ion_map(ion_buffer buffer, size_t len, off_t offset) +{ + return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + buffer, offset); +} + +int ion_unmap(void *addr, size_t len) +{ + return munmap(addr, len); +} + +int ion_sync(ion_client client, ion_buffer buffer) +{ + struct ion_fd_data data; + + data.fd = buffer; + + return ioctl(client, ION_IOC_SYNC, &data); +} diff --git a/exynos4/libswconverter/Android.mk b/exynos4/libswconverter/Android.mk new file mode 100644 index 0000000..089858c --- /dev/null +++ b/exynos4/libswconverter/Android.mk @@ -0,0 +1,31 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + swconvertor.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_ARGB8888_to_YUV420SP_NEON.s + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include \ + $(TOP)/hardware/samsung_slsi/exynos/include + +LOCAL_MODULE := libswconverter + +LOCAL_PRELINK_MODULE := false + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := liblog + +include $(BUILD_STATIC_LIBRARY) diff --git a/exynos4/libswconverter/Makefile.am b/exynos4/libswconverter/Makefile.am new file mode 100644 index 0000000..18adaa3 --- /dev/null +++ b/exynos4/libswconverter/Makefile.am @@ -0,0 +1,17 @@ +lib_LTLIBRARIES = libswconverter.la + +libswconverter_la_SOURCES = swconvertor.c \ + csc_ARGB8888_to_YUV420SP_NEON.s \ + csc_interleave_memcpy_neon.s \ + 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 + + +libswconverter_la_LIBADD = +libswconverter_la_CFLAGS = -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos/include + +libswconverter_la_LDFLAGS = "-Wl,-z,noexecstack" + diff --git a/exynos4/libswconverter/csc_ARGB8888_to_YUV420SP_NEON.s b/exynos4/libswconverter/csc_ARGB8888_to_YUV420SP_NEON.s new file mode 100644 index 0000000..62ccf97 --- /dev/null +++ b/exynos4/libswconverter/csc_ARGB8888_to_YUV420SP_NEON.s @@ -0,0 +1,365 @@ + + .arch armv7-a + .text + .global csc_ARGB8888_to_YUV420SP_NEON + .type csc_ARGB8888_to_YUV420SP_NEON, %function +csc_ARGB8888_to_YUV420SP_NEON: + .fnstart + + @r0 pDstY + @r1 pDstUV + @r2 pSrcRGB + @r3 nWidth + @r4 pDstY2 = pDstY + nWidth + @r5 pSrcRGB2 = pSrcRGB + nWidthx2 + @r6 temp7, nWidth16m + @r7 temp6, accumilator + @r8 temp5, nWidthTemp + @r9 temp4, Raw RGB565 + @r10 temp3, r,g,b + @r11 temp2, immediate operand + @r12 temp1, nHeight + @r14 temp0, debugging pointer + + .equ CACHE_LINE_SIZE, 32 + .equ PRE_LOAD_OFFSET, 6 + + stmfd sp!, {r4-r12,r14} @ backup registers + ldr r12, [sp, #40] @ load nHeight + @ldr r14, [sp, #44] @ load pTest + add r4, r0, r3 @r4: pDstY2 = pDstY + nWidth + add r5, r2, r3, lsl #2 @r5: pSrcRGB2 = tmpSrcRGB + nWidthx4 + sub r8, r3, #16 @r8: nWidthTmp = nWidth -16 + + @q0: temp1, R + @q1: temp2, GB + @q2: R + @q3: G + @q4: B + @q5: temp3, output + + + vmov.u16 q6, #66 @coefficient assignment + vmov.u16 q7, #129 + vmov.u16 q8, #25 + vmov.u16 q9, #0x8080 @ 128<<8 + 128 + + vmov.u16 q10, #0x1000 @ 16<<8 + 128 + vorr.u16 q10, #0x0080 + + vmov.u16 q11, #38 @#-38 + vmov.u16 q12, #74 @#-74 + vmov.u16 q13, #112 + vmov.u16 q14, #94 @#-94 + vmov.u16 q15, #18 @#-18 + + + + +LOOP_NHEIGHT2: + stmfd sp!, {r12} @ backup registers + +LOOP_NWIDTH16: + pld [r2, #(CACHE_LINE_SIZE*PRE_LOAD_OFFSET)] + @-------------------------------------------YUV ------------------------------------------ + vmov.u16 q14, #94 @#94 + vmov.u16 q15, #18 @#18 + vld4.8 {d0,d1,d2,d3}, [r2]! @loadRGB interleavely + vld4.8 {d4,d5,d6,d7}, [r2]! @loadRGB interleavely + + + vmov.u16 d8,d2 + vmov.u16 d9,d6 + vmov.u16 d10,d1 + vmov.u16 d11,d5 + vmov.u16 d12,d0 + vmov.u16 d13,d4 + + vand.u16 q4,#0x00FF @R + vand.u16 q5,#0x00FF @G + vand.u16 q6,#0x00FF @B + + vmov.u16 q8,q9 @ CalcU() + vmla.u16 q8,q6,q13 @112 * B[k] + vmls.u16 q8,q4,q11 @q0:U -(38 * R[k]) @128<<6+ 32 + u>>2 + vmls.u16 q8,q5,q12 @-(74 * G[k]) + vshr.u16 q8,q8, #8 @(128<<8+ 128 + u)>>8 + + vmov.u16 q7,q9 @CalcV() + vmla.u16 q7,q4,q13 @112 * R[k] + vmls.u16 q7,q5,q14 @q0:U -(94 * G[k]) @128<<6+ 32 + v>>2 + vmls.u16 q7,q6,q15 @-(18 * B[k]) + vshr.u16 q7,q7, #8 @(128<<8+ 128 + v)>>8 + + + vtrn.8 q8,q7 + vst1.8 {q8}, [r1]! @write UV component to yuv420_buffer+linear_ylanesiez + + @-------------------------------------------Y ------------------------------------------ + + vmov.u16 q14, #66 @#66 + vmov.u16 q15, #129 @#129 + vmov.u16 q8, #25 @#25 + + @CalcY_Y() + + vmul.u16 q7,q4,q14 @q0 = 66 *R[k] + vmla.u16 q7,q5,q15 @q0 += 129 *G[k] + vmla.u16 q7,q6,q8 @q0 += 25 *B[k] + + vadd.u16 q7,q7,q10 + vshr.u16 q7,q7, #8 + + vmov.u16 d8,d2 + vmov.u16 d9,d6 + vmov.u16 d10,d1 + vmov.u16 d11,d5 + vmov.u16 d12,d0 + vmov.u16 d13,d4 + + vshr.u16 q4,q4,#8 @R + vshr.u16 q5,q5,#8 @G + vshr.u16 q6,q6,#8 @B + + vmul.u16 q0,q4,q14 @q0 = 66 *R[k] + vmla.u16 q0,q5,q15 @q0 += 129 *G[k] + vmla.u16 q0,q6,q8 @q0 += 25 *B[k] + vadd.u16 q0,q0,q10 + vshr.u16 q0,q0, #8 + + vtrn.8 q7,q0 + vst1.8 {q7}, [r0]!@write to Y to yuv420_buffer + + + + @-------------------------------------------Y ------------------------------------------ + + @---------------------------------------------Y1------------------------------------------- + + pld [r5, #(CACHE_LINE_SIZE*PRE_LOAD_OFFSET)] + vld4.8 {d0,d1,d2,d3}, [r5]! @loadRGB interleavely + vld4.8 {d4,d5,d6,d7}, [r5]! @loadRGB interleavely + + vmov.u16 d8,d2 + vmov.u16 d9,d6 + vmov.u16 d10,d1 + vmov.u16 d11,d5 + vmov.u16 d12,d0 + vmov.u16 d13,d4 + + + vand.u16 q4,#0x00FF @R + vand.u16 q5,#0x00FF @G + vand.u16 q6,#0x00FF @B + + + + vmul.u16 q7,q4,q14 @q0 = 66 *R[k] + vmla.u16 q7,q5,q15 @q0 += 129 *G[k] + vmla.u16 q7,q6,q8 @q0 += 25 *B[k] + vadd.u16 q7,q7,q10 + vshr.u16 q7,q7, #8 + + vmov.u16 d8,d2 + vmov.u16 d9,d6 + vmov.u16 d10,d1 + vmov.u16 d11,d5 + vmov.u16 d12,d0 + vmov.u16 d13,d4 + + vshr.u16 q4,q4,#8 @R + vshr.u16 q5,q5,#8 @G + vshr.u16 q6,q6,#8 @B + + vmul.u16 q0,q4,q14 @q0 = 66 *R[k] + vmla.u16 q0,q5,q15 @q0 += 129 *G[k] + vmla.u16 q0,q6,q8 @q0 += 25 *B[k] + vadd.u16 q0,q0,q10 + vshr.u16 q0,q0, #8 + + vtrn.8 q7,q0 + vst1.8 {q7}, [r4]!@write to Y to yuv420_buffer + + subs r8,r8,#16 @nWidth16-- + BPL LOOP_NWIDTH16 @if nWidth16>0 + @-----------------------------------unaligned --------------------------------------- + + adds r8,r8,#16 @ + 16 - 2 + BEQ NO_UNALIGNED @in case that nWidht is multiple of 16 +LOOP_NWIDTH2: + @----------------------------------pDstRGB1--Y------------------------------------------ + @stmfd sp!, {r14} @backup r14 + + + ldr r9, [r2], #4 @loadRGB int + ldr r12, [r2], #4 @loadRGB int + + mov r10, r9,lsr #16 @copy to r10 + mov r14, r12 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; + ldr r6, =0x00FF0000 + and r14, r14, r6 @R: (rgbIn[k] & 0xF800) >> 10; + add r10,r10,r14 + + mov r11, #66 @accumilator += R*66 + mul r7, r10, r11 + + mov r10, r9,lsr #8 @copy to r10 + mov r14, r12,lsl #8 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @G: + ldr r6, =0x00FF0000 + and r14, r14, r6 @G: + add r10,r10,r14 + + mov r11, #129 @accumilator += G *129 + mla r7, r10, r11, r7 + + mov r10, r9 @copy to r10 + mov r14, r12,lsl #16 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @B + ldr r6, =0x00FF0000 + and r14, r14, r6 @B + add r10,r10,r14 + + mov r11, #25 @accumilator 1 -= B *25 + mla r7, r10, r11, r7 + + ldr r6, =0x10801080 + add r7, r6 + + lsr r7, #8 + strb r7, [r0],#1 + lsr r7,#16 + strb r7, [r0],#1 + @ldmfd sp!, {r14} @load r14 + + + @----------------------------------pDstRGB2--UV------------------------------------------ + + mov r10, r9 @copy to r10 + ldr r7,=0x00008080 + mov r12,r7 + + ldr r6, =0x000000FF + and r10, r10, r6 @B: + + mov r11, #112 @accumilator += B*112 + mla r7, r10, r11, r7 + + + mov r11, #18 @accumilator -= B*18 + mul r11, r10, r11 + sub r12, r12, r11 + + + + + mov r10, r9, lsr #16 @copy to r10 + ldr r6, =0x000000FF + and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; + + mov r11, #38 @accumilator -= R *38 + mul r11, r10, r11 + sub r7, r7, r11 + + mov r11, #112 @accumilator = R *112 + mla r12, r10, r11, r12 + + mov r10, r9,lsr #8 @copy to r10 + ldr r6, =0x000000FF + and r10, r10, r6 @G: (rgbIn[k] & 0x07E0) >> 5; + + mov r11, #74 @accumilator -= G*74 + mul r11, r10, r11 + sub r7, r7, r11 + + mov r11, #94 @accumilator -= G*94 + mul r11, r10, r11 + sub r12, r12, r11 + + lsr r7, #8 @ >>8 + strb r7, [r1],#1 + lsr r12, #8 @ >>8 + strb r12, [r1],#1 + + @----------------------------------pDstRGB2--Y------------------------------------------ + @stmfd sp!, {r14} @backup r14 + + + ldr r9, [r5], #4 @loadRGB int + ldr r12, [r5], #4 @loadRGB int + + mov r10, r9,lsr #16 @copy to r10 + mov r14, r12 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; + ldr r6, =0x00FF0000 + and r14, r14, r6 @R: (rgbIn[k] & 0xF800) >> 10; + add r10,r10,r14 + + mov r11, #66 @accumilator += R*66 + mul r7, r10, r11 + + mov r10, r9,lsr #8 @copy to r10 + mov r14, r12,lsl #8 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @G: + ldr r6, =0x00FF0000 + and r14, r14, r6 @G: + add r10,r10,r14 + + mov r11, #129 @accumilator += G *129 + mla r7, r10, r11, r7 + + mov r10, r9 @copy to r10 + mov r14, r12,lsl #16 @copy to r10 + + ldr r6, =0x000000FF + and r10, r10, r6 @B + ldr r6, =0x00FF0000 + and r14, r14, r6 @B + add r10,r10,r14 + + + + + mov r11, #25 @accumilator 1 -= B *25 + mla r7, r10, r11, r7 + + ldr r6, =0x10801080 + add r7, r6 + lsr r7, #8 + + strb r7, [r4],#1 + lsr r7,#16 + strb r7, [r4],#1 + @ldmfd sp!, {r14} @load r14 + + + subs r8,r8,#2 @ nWidth2 -= 2 + BGT LOOP_NWIDTH2 @ if nWidth2>0 + + +NO_UNALIGNED: @in case that nWidht is multiple of 16 + + @----------------------------------------------------------------------------- + sub r8, r3, #16 @r8: nWidthTmp = nWidth -16 + add r0, r0, r3 @pDstY + nwidth + add r2, r2, r3, lsl #2 @pSrcRGB + nwidthx4 + add r4, r4, r3 @pDstY2 + nwidth + add r5, r5, r3, lsl #2 @pSrcRGB2 + nwidthx4 + + ldmfd sp!, {r12} + subs r12,r12,#2 @nHeight -=2 + BGT LOOP_NHEIGHT2 @if nHeight2>0 + + ldmfd sp!, {r4-r12,pc} @ backup registers + .fnend diff --git a/exynos4/libswconverter/csc_interleave_memcpy_neon.s b/exynos4/libswconverter/csc_interleave_memcpy_neon.s new file mode 100644 index 0000000..1ab25b6 --- /dev/null +++ b/exynos4/libswconverter/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.02.01 : 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/exynos4/libswconverter/csc_linear_to_tiled_crop_neon.s b/exynos4/libswconverter/csc_linear_to_tiled_crop_neon.s new file mode 100644 index 0000000..8f59826 --- /dev/null +++ b/exynos4/libswconverter/csc_linear_to_tiled_crop_neon.s @@ -0,0 +1,492 @@ +/* + * + * 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.02.01 : 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/exynos4/libswconverter/csc_linear_to_tiled_interleave_crop_neon.s b/exynos4/libswconverter/csc_linear_to_tiled_interleave_crop_neon.s new file mode 100644 index 0000000..33a31da --- /dev/null +++ b/exynos4/libswconverter/csc_linear_to_tiled_interleave_crop_neon.s @@ -0,0 +1,563 @@ +/* + * + * 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_interleave_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2012.02.01 : 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/exynos4/libswconverter/csc_tiled_to_linear_crop_neon.s b/exynos4/libswconverter/csc_tiled_to_linear_crop_neon.s new file mode 100644 index 0000000..9cb81b5 --- /dev/null +++ b/exynos4/libswconverter/csc_tiled_to_linear_crop_neon.s @@ -0,0 +1,701 @@ +/* + * + * 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_tiled_to_linear_crop_neon.s + * @brief SEC_OMX specific define + * @author ShinWon Lee (shinwon.lee@samsung.com) + * @version 1.0 + * @history + * 2012.02.01 : 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> 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] + */ +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; + } + } + } +} + +/* + * 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) +{ + 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 int *pSrc = (unsigned 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 & 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; + + pDstU[uIndex++] = (unsigned char)U; + pDstV[vIndex++] = (unsigned char)V; + } + } + } +} + + +/* + * Converts ARGB8888 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) +{ + 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/libomxil-e3250-v4l2.manifest b/libomxil-e3250-v4l2.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/libomxil-e3250-v4l2.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/omxil-e3250-v4l2.pc.in b/omxil-e3250-v4l2.pc.in new file mode 100644 index 0000000..dca2cac --- /dev/null +++ b/omxil-e3250-v4l2.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +libdir=@prefix@/lib +includedir=@prefix@/include + +Name: Samsung OpenMAX IL package +Description: Samsung E4X12 codec +Version: @VERSION@ +Requires: +Libs: -L${libdir} -lExynosOMX_Core + +Cflags: -I${includedir}/libomxil-e3250-v4l2 -DUSE_SAMSUNG_COLORFORMAT -DNONBLOCK_MODE_PROCESS + diff --git a/openmax/Android.mk b/openmax/Android.mk new file mode 100644 index 0000000..5fe9faa --- /dev/null +++ b/openmax/Android.mk @@ -0,0 +1,42 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +include device/samsung/$(TARGET_DEVICE)/BoardConfig.mk + +BOARD_USE_ANB := false +BOARD_USE_DMA_BUF := false + +# Set to false to use Android's OMX header files +BOARD_USE_KHRONOS_OMX_HEADER := false + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), false) +ANDROID_MEDIA_INC := $(TOP)/frameworks/native/include/media +endif + +EXYNOS_OMX_TOP := $(LOCAL_PATH) +EXYNOS_OMX_INC := $(EXYNOS_OMX_TOP)/include +EXYNOS_OMX_COMPONENT := $(EXYNOS_OMX_TOP)/component + +EXYNOS_VIDEO_CODEC := \ + hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/libcodec/video +EXYNOS_AUDIO_CODEC := \ + hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/libcodec/audio + +include $(EXYNOS_OMX_TOP)/osal/Android.mk +include $(EXYNOS_OMX_TOP)/core/Android.mk + +include $(EXYNOS_OMX_COMPONENT)/common/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/dec/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/dec/h264/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/dec/mpeg4/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/dec/vc1/Android.mk + +include $(EXYNOS_OMX_COMPONENT)/video/enc/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/enc/h264/Android.mk +include $(EXYNOS_OMX_COMPONENT)/video/enc/mpeg4/Android.mk + +ifeq ($(BOARD_USE_ALP_AUDIO), true) +include $(EXYNOS_OMX_COMPONENT)/audio/dec/Android.mk +include $(EXYNOS_OMX_COMPONENT)/audio/dec/mp3/Android.mk +endif diff --git a/openmax/Makefile.am b/openmax/Makefile.am new file mode 100644 index 0000000..0c89c75 --- /dev/null +++ b/openmax/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = osal component core diff --git a/openmax/component/Makefile.am b/openmax/component/Makefile.am new file mode 100644 index 0000000..fe09772 --- /dev/null +++ b/openmax/component/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = common video audio diff --git a/openmax/component/audio/Makefile.am b/openmax/component/audio/Makefile.am new file mode 100644 index 0000000..8530ec2 --- /dev/null +++ b/openmax/component/audio/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = dec diff --git a/openmax/component/audio/dec/Android.mk b/openmax/component/audio/dec/Android.mk new file mode 100644 index 0000000..ed03cdd --- /dev/null +++ b/openmax/component/audio/dec/Android.mk @@ -0,0 +1,28 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + Exynos_OMX_Adec.c + +LOCAL_MODULE := libExynosOMX_Adec +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_STATIC_LIBRARIES := libsrpapi + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/audio/dec \ + $(EXYNOS_AUDIO_CODEC)/alp/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/openmax/component/audio/dec/Exynos_OMX_Adec.c b/openmax/component/audio/dec/Exynos_OMX_Adec.c new file mode 100755 index 0000000..4708b49 --- /dev/null +++ b/openmax/component/audio/dec/Exynos_OMX_Adec.c @@ -0,0 +1,1566 @@ +/* + * + * 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 Exynos_OMX_Adec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#include +#include +#include +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OMX_Adec.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" +#include "srp_api.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_AUDIO_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + if (nPortIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pExynosPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; + pExynosPort->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; + + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + if (nPortIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pExynosPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = Exynos_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + Exynos_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; + pExynosPort->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; + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(temp_bufferHeader); + Exynos_OSAL_Free(temp_buffer); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pExynosPort->portState != OMX_StateLoaded) && (pExynosPort->portState != OMX_StateInvalid)) { + (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent, + pExynosComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) { + if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) { + if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); + pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pExynosPort->assignedBufferNum--; + if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader); + pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL; + pBufferHdr = NULL; + } + pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pExynosPort->assignedBufferNum == 0) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set"); + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + pExynosPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 Exynos_OMX_FreeTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT* pExynosPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_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 Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + if ((pExynosComponent->currentState == OMX_StateExecuting) && + (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXInputPort->way.port1WayDataBuffer.dataBuffer; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = exynosOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = exynosOMXInputPort->markType.pMarkData; + exynosOMXInputPort->markType.hMarkTargetComponent = NULL; + exynosOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + bufferHeader->nFilledLen = 0; + pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } + + if ((pExynosComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) { + Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pExynosComponent->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 Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *dataBuffer = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + pExynosPort= &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer; + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + Exynos_OSAL_MutexLock(dataBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + Exynos_OSAL_MutexUnlock(dataBuffer->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; + + Exynos_OSAL_Free(message); + +#ifndef SLP_PLATFORM + if (dataBuffer->allocSize <= dataBuffer->dataLen) + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); +#endif + } + Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXOutputPort->way.port1WayDataBuffer.dataBuffer; + 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 (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData; + pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL; + pExynosComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } + + if ((pExynosComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) { + Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pExynosComponent->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 Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *dataBuffer = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + pExynosPort= &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer; + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + Exynos_OSAL_MutexLock(dataBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + Exynos_OSAL_MutexUnlock(dataBuffer->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; */ + pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = dataBuffer->bufferHeader->pBuffer; + pExynosPort->processData.allocSize = dataBuffer->bufferHeader->nAllocLen; + + Exynos_OSAL_Free(message); + } + Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer; + EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData; + 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) + pExynosComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + if (copySize > 0) + Exynos_OSAL_Memcpy(inputData->buffer.singlePlaneBuffer.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 (pExynosComponent->bUseFlagEOF == OMX_TRUE) { + if (pExynosComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } else { + if ((checkedSize == checkInputStreamLen) && (pExynosComponent->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; + pExynosComponent->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; + pExynosComponent->bSaveFlagEOS = OMX_TRUE; + } + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + Exynos_ResetCodecData(inputData); + flagEOF = OMX_FALSE; + } + + if ((inputUseBuffer->remainDataLen == 0) || + (CHECK_PORT_BEING_FLUSHED(exynosInputPort))) + Exynos_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; + } + + if (flagEOF == OMX_TRUE) { + if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + /* Flush SRP buffers */ + SRP_Flush(); + + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pExynosComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + Exynos_OSAL_Log(EXYNOS_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 Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port1WayDataBuffer.dataBuffer; + EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData; + OMX_U32 copySize = 0; + + FunctionIn(); + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if (pExynosComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) { + pExynosComponent->checkTimeStamp.startTimeStamp = -19761123; + pExynosComponent->checkTimeStamp.nStartFlags = 0x0; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + Exynos_ResetCodecData(outputData); + ret = OMX_TRUE; + goto EXIT; + } + } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + Exynos_ResetCodecData(outputData); + 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 */ + Exynos_ResetCodecData(outputData); + + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) || + (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) + Exynos_OutputBufferReturn(pOMXComponent); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); + + ret = OMX_FALSE; + + /* reset outputData */ + Exynos_ResetCodecData(outputData); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer; + EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port1WayDataBuffer.dataBuffer; + EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData; + EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData; + OMX_U32 copySize = 0; + + pExynosComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pAudioDec->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + + if (((pExynosComponent->currentState == OMX_StatePause) || + (pExynosComponent->currentState == OMX_StateIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(exynosInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))) { + Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent); + } + + while ((Exynos_Check_BufferProcess_State(pExynosComponent)) && (!pAudioDec->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = Exynos_OutputBufferGetQueue(pExynosComponent); + if ((ret == OMX_ErrorUndefined) || + (exynosInputPort->portState != OMX_StateIdle) || + (exynosOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pExynosComponent->reInputData == OMX_FALSE) { + Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((Exynos_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { + Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = Exynos_InputBufferGetQueue(pExynosComponent); + break; + } + + Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex); + Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pAudioDec->exynos_codec_bufferProcess(pOMXComponent, inputData, outputData); + Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataDecodeYet) + pExynosComponent->reInputData = OMX_TRUE; + else + pExynosComponent->reInputData = OMX_FALSE; + + Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex); + Exynos_Postprocess_OutputData(pOMXComponent); + Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER **pDataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (pExynosPort->portWayType == WAY2_PORT) { + *pDataBuffer = NULL; + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + OMX_U32 flushNum = 0; + OMX_S32 semValue = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "flushPort idx:%d", portIndex); +#endif + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &semValue); + if (semValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[portIndex].bufferSemID); + Exynos_OSAL_SemaphoreTryWait(pExynosComponent->pExynosPort[portIndex].bufferSemID); + + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message != NULL) { + bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; + bufferHeader->nFilledLen = 0; + + if (portIndex == OUTPUT_PORT_INDEX) { + pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } else { + pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } + + Exynos_OSAL_Free(message); + message = NULL; + } + } + + Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer); + if (flushPortBuffer != NULL) { + if (flushPortBuffer->dataValid == OMX_TRUE) { + if (portIndex == INPUT_PORT_INDEX) + Exynos_InputBufferReturn(pOMXComponent); + else if (portIndex == OUTPUT_PORT_INDEX) + Exynos_OutputBufferReturn(pOMXComponent); + } + } + + while(1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt); + if (cnt <= 0) + break; + Exynos_OSAL_SemaphoreTryWait(pExynosComponent->pExynosPort[portIndex].bufferSemID); + } + Exynos_OSAL_SetElemNum(&pExynosPort->bufferQ, 0); + + pExynosPort->processData.dataLen = 0; + pExynosPort->processData.nFlags = 0; + pExynosPort->processData.remainDataLen = 0; + pExynosPort->processData.timeStamp = 0; + pExynosPort->processData.usedDataLen = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlush idx:%d", nPortIndex); +#endif + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + + pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE; + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer); + + Exynos_OSAL_MutexLock(flushPortBuffer->bufferMutex); + ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex); + Exynos_OSAL_MutexUnlock(flushPortBuffer->bufferMutex); + + pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE; + + if (bEvent == OMX_TRUE && ret == OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandFlush, nPortIndex, NULL); + } + + if (nPortIndex == INPUT_PORT_INDEX) { + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->reInputData = OMX_FALSE; + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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 = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pExynosComponent->portParam.nPorts; + portParam->nStartPortNumber = pExynosComponent->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; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pExynosComponent->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; + } + + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + portDefinition = &pExynosPort->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; + } + + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + portDefinition = &pExynosPort->portDefinition; + + portFormat->eEncoding = portDefinition->format.audio.eEncoding; + } + ret = OMX_ErrorNone; + } + break; + default: + { + ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + portDefinition = &pExynosPort->portDefinition; + + portDefinition->format.audio.eEncoding = portFormat->eEncoding; + ret = OMX_ErrorNone; + } + break; + default: + { + ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigAudioMute: + { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioMute"); + ret = OMX_ErrorUnsupportedIndex; + } + break; + case OMX_IndexConfigAudioVolume: + { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioVolume"); + ret = OMX_ErrorUnsupportedIndex; + } + break; + default: + ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_BufferProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pSECComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pSECComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_BufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + FunctionIn(); + + pAudioDec->bExitBufferProcessThread = OMX_FALSE; + + ret = Exynos_OSAL_ThreadCreate(&pAudioDec->hBufferProcessThread, + Exynos_OMX_BufferProcessThread, + pOMXComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + OMX_S32 countValue = 0; + unsigned int i = 0; + + FunctionIn(); + + pAudioDec->bExitBufferProcessThread = OMX_TRUE; + + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID); + } + + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + Exynos_OSAL_ThreadTerminate(pAudioDec->hBufferProcessThread); + pAudioDec->hBufferProcessThread = NULL; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pAudioDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT)); + if (pAudioDec == NULL) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + Exynos_OSAL_Memset(pAudioDec, 0, sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT)); + pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pAudioDec; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bMultiThreadProcess = OMX_FALSE; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio; + + pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pExynosPort->portDefinition.format.audio.pNativeRender = 0; + pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio; + + pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pExynosPort->portDefinition.format.audio.pNativeRender = 0; + pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused; + + + pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest; + + pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer; + pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer; + pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create; + pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; + pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + Exynos_OSAL_Free(pAudioDec); + pExynosComponent->hComponentHandle = pAudioDec = NULL; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + Exynos_OSAL_Free(pExynosPort->portDefinition.format.audio.cMIMEType); + pExynosPort->portDefinition.format.audio.cMIMEType = NULL; + } + + ret = Exynos_OMX_Port_Destructor(pOMXComponent); + + ret = Exynos_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/audio/dec/Exynos_OMX_Adec.h b/openmax/component/audio/dec/Exynos_OMX_Adec.h new file mode 100644 index 0000000..fe20109 --- /dev/null +++ b/openmax/component/audio/dec/Exynos_OMX_Adec.h @@ -0,0 +1,139 @@ +/* + * + * 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 Exynos_OMX_Adec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#ifndef EXYNOS_OMX_AUDIO_DECODE +#define EXYNOS_OMX_AUDIO_DECODE + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_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 _EXYNOS_OMX_AUDIODEC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + + OMX_BOOL bFirstFrame; + OMX_PTR pInputBuffer; + SRP_DEC_INPUT_BUFFER SRPDecInputBuffer[MAX_AUDIO_INPUTBUFFER_NUM]; + OMX_U32 indexInputBuffer; + + /* Buffer Process */ + OMX_BOOL bExitBufferProcessThread; + OMX_HANDLETYPE hBufferProcessThread; + + OMX_ERRORTYPE (*exynos_codec_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData); + + int (*exynos_checkInputFrame)(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); +} EXYNOS_OMX_AUDIODEC_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_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 Exynos_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 Exynos_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_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 Exynos_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent); + +#ifdef __cplusplus +} +#endif + +#endif /* EXYNOS_OMX_AUDIO_DECODE */ diff --git a/openmax/component/audio/dec/Makefile.am b/openmax/component/audio/dec/Makefile.am new file mode 100644 index 0000000..b817ac4 --- /dev/null +++ b/openmax/component/audio/dec/Makefile.am @@ -0,0 +1,19 @@ +SUBDIRS = . mp3 + +lib_LTLIBRARIES = libExynosOMX_Adec.la + +libExynosOMX_Adec_la_SOURCES = Exynos_OMX_Adec.c\ + Exynos_OMX_Adec.h + +libExynosOMX_Adec_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/audio/alp/libsrpapi.la + +libExynosOMX_Adec_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/exynos4/libcodec/audio/alp/include \ + -I$(top_srcdir)/exynos/include + diff --git a/openmax/component/audio/dec/mp3/Android.mk b/openmax/component/audio/dec/mp3/Android.mk new file mode 100644 index 0000000..31d94ca --- /dev/null +++ b/openmax/component/audio/dec/mp3/Android.mk @@ -0,0 +1,38 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Mp3dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.MP3.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libsrpapi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/audio/dec \ + $(EXYNOS_AUDIO_CODEC)/alp/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.c b/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.c new file mode 100644 index 0000000..b31b748 --- /dev/null +++ b/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.c @@ -0,0 +1,955 @@ +/* + * + * 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 Exynos_OMX_Mp3dec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Adec.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_Mp3dec.h" +#include "srp_api.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MP3_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +//#define SRP_DUMP_TO_FILE +#ifdef SRP_DUMP_TO_FILE +#include "stdio.h" + +FILE *inFile; +FILE *outFile; +#endif + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_MP3_HANDLE *pMp3Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcMp3Param = &pMp3Dec->mp3Param; + + Exynos_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; + EXYNOS_MP3_HANDLE *pMp3Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcPcmParam = &pMp3Dec->pcmParam; + + Exynos_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 = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE); + } + break; + default: + ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_MP3_HANDLE *pMp3Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstMp3Param = &pMp3Dec->mp3Param; + + Exynos_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; + EXYNOS_MP3_HANDLE *pMp3Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstPcmParam = &pMp3Dec->pcmParam; + + Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE)) { + pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + default: + ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle; + + FunctionIn(); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */ + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_FALSE; + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; +#ifdef SLP_PLATFORM + pMp3Dec->nPendingflags = 0; +#endif + pExynosComponent->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 Exynos_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + FunctionIn(); + +#ifdef SRP_DUMP_TO_FILE + fclose(inFile); + fclose(outFile); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_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; + char dummy[2]={0xFF, 0xFF}; + + FunctionIn(); + +#ifdef SRP_DUMP_TO_FILE + if (pExynosComponent->reInputData == OMX_FALSE) { + fwrite(pInputData->buffer.singlePlaneBuffer.dataBuffer, pInputData->dataLen, 1, inFile); + } +#endif + + /* Save timestamp and flags of input data */ +#ifndef SLP_PLATFORM + pOutputData->timeStamp = pInputData->timeStamp; +#else + if (pExynosComponent->checkTimeStamp.startTimeStamp == pInputData->timeStamp) { + pMp3Dec->timeStamp = pInputData->timeStamp; + } +#endif + pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS); + + /* Decoding mp3 frames by SRP */ + if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) { + if (pInputData->dataLen == 0) + returnCodec = SRP_Decode(dummy, sizeof(dummy)); + else + returnCodec = SRP_Decode(pInputData->buffer.singlePlaneBuffer.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) { + if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; + ret = OMX_ErrorNone; + goto EXIT; + } + + returnCodec = SRP_Get_Dec_Info(&codecDecInfo); + if (returnCodec < 0) { + Exynos_OSAL_Log(EXYNOS_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; + pExynosComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + if (isSRPIbufOverflow) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + } + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_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 */ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->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; + pExynosComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + pExynosComponent->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; + Exynos_OSAL_Memcpy(pOutputData->buffer.singlePlaneBuffer.dataBuffer, dataBuffer, dataLen); +#ifdef SLP_PLATFORM + pOutputData->timeStamp = pMp3Dec->timeStamp; + pMp3Dec->timeStamp += 1000000 * (OMX_TICKS)dataLen / (pMp3Dec->pcmParam.nSamplingRate * pMp3Dec->pcmParam.nChannels * pMp3Dec->pcmParam.nBitPerSample / 8); + pOutputData->nFlags |= pMp3Dec->nPendingflags; + pMp3Dec->nPendingflags = 0; +#endif + } else { + pOutputData->dataLen = 0; +#ifdef SLP_PLATFORM + pMp3Dec->nPendingflags = pOutputData->nFlags; +#endif + } + +#ifdef SRP_DUMP_TO_FILE + if (pOutputData->dataLen > 0) + fwrite(pOutputData->buffer.singlePlaneBuffer.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) + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail SRP_STOP_EOS_STATE"); + if (isSRPStopped == 1) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pExynosComponent->getAllDelayBuffer = OMX_FALSE; +#ifdef SLP_PLATFORM + pOutputData->timeStamp = pInputData->timeStamp; /*For ALP EOS Timestamp*/ +#endif + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */ + ret = OMX_ErrorNone; + } else { + pExynosComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } + } else { /* Flush after EOS */ + pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; + } + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[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 == Exynos_Check_BufferProcess_State(pExynosComponent)) { + if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) + ret = OMX_ErrorInputDataDecodeYet; + else + ret = OMX_ErrorNone; + + goto EXIT; + } + + ret = Exynos_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData); + + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->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 Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = NULL; + EXYNOS_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)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP3_DEC, componentName) != 0) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_AUDIO_DEC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorInsufficientResources; + goto EXIT_ERROR_1; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC); + + pMp3Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MP3_HANDLE)); + if (pMp3Dec == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + ret = OMX_ErrorInsufficientResources; + goto EXIT_ERROR_2; + } + Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE)); + pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->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) { + Exynos_OSAL_Log(EXYNOS_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) { + Exynos_OSAL_Log(EXYNOS_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) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_5; + } + + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->processData.allocSize = inputBufferSize; + pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = Exynos_OSAL_Malloc(inputBufferSize); + if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_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) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec); + ret = OMX_ErrorHardware; + goto EXIT_ERROR_6; + } + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = inputBufferNum; + pExynosPort->portDefinition.nBufferCountMin = inputBufferNum; + pExynosPort->portDefinition.nBufferSize = inputBufferSize; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg"); + pExynosPort->portDefinition.format.audio.pNativeRender = 0; + pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + pExynosPort->portWayType = WAY1_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = outputBufferNum; + pExynosPort->portDefinition.nBufferCountMin = outputBufferNum; + pExynosPort->portDefinition.nBufferSize = outputBufferSize; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw"); + pExynosPort->portDefinition.format.audio.pNativeRender = 0; + pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM; + pExynosPort->portWayType = WAY1_PORT; + + /* 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 = &Exynos_SRP_Mp3Dec_GetParameter; + pOMXComponent->SetParameter = &Exynos_SRP_Mp3Dec_SetParameter; + pOMXComponent->GetConfig = &Exynos_SRP_Mp3Dec_GetConfig; + pOMXComponent->SetConfig = &Exynos_SRP_Mp3Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_SRP_Mp3Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_SRP_Mp3Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + /* ToDo: Change the function name associated with a specific codec */ + pExynosComponent->exynos_codec_componentInit = &Exynos_SRP_Mp3Dec_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_SRP_Mp3Dec_Terminate; + pAudioDec->exynos_codec_bufferProcess = &Exynos_SRP_Mp3Dec_bufferProcess; + pAudioDec->exynos_checkInputFrame = NULL; + + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + goto EXIT; /* This function is performed successfully. */ + +EXIT_ERROR_6: + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer); + pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL; + pExynosPort->processData.allocSize = 0; +EXIT_ERROR_5: + SRP_Deinit(); +EXIT_ERROR_4: + SRP_Terminate(); +EXIT_ERROR_3: + Exynos_OSAL_Free(pMp3Dec); + pAudioDec->hCodecHandle = NULL; +EXIT_ERROR_2: + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; +EXIT_ERROR_1: + Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent); +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_MP3_HANDLE *pMp3Dec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + if (pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer) { + Exynos_OSAL_Free(pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer); + pExynosPort->processData.buffer.singlePlaneBuffer.dataBuffer = NULL; + pExynosPort->processData.allocSize = 0; + } + + pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + if (pMp3Dec != NULL) { + if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) { + SRP_Deinit(); + SRP_Terminate(); + } + Exynos_OSAL_Free(pMp3Dec); + ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.h b/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.h new file mode 100644 index 0000000..95e5d3a --- /dev/null +++ b/openmax/component/audio/dec/mp3/Exynos_OMX_Mp3dec.h @@ -0,0 +1,68 @@ +/* + * + * 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 Exynos_OMX_Mp3dec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#ifndef EXYNOS_OMX_MP3_DEC_COMPONENT +#define EXYNOS_OMX_MP3_DEC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" + +typedef struct _EXYNOS_SRP_MP3_HANDLE +{ + OMX_HANDLETYPE hSRPHandle; + OMX_BOOL bConfiguredSRP; + OMX_BOOL bSRPLoaded; + OMX_BOOL bSRPSendEOS; + OMX_S32 returnCodec; +} EXYNOS_SRP_MP3_HANDLE; + +typedef struct _EXYNOS_MP3_HANDLE +{ + /* OMX Codec specific */ + OMX_AUDIO_PARAM_MP3TYPE mp3Param; + OMX_AUDIO_PARAM_PCMMODETYPE pcmParam; + + /* SEC SRP Codec specific */ + EXYNOS_SRP_MP3_HANDLE hSRPMp3Handle; + +#ifdef SLP_PLATFORM + OMX_TICKS timeStamp; + OMX_U32 nPendingflags; +#endif +} EXYNOS_MP3_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif /* EXYNOS_OMX_MP3_DEC_COMPONENT */ diff --git a/openmax/component/audio/dec/mp3/Makefile.am b/openmax/component/audio/dec/mp3/Makefile.am new file mode 100644 index 0000000..eaff551 --- /dev/null +++ b/openmax/component/audio/dec/mp3/Makefile.am @@ -0,0 +1,23 @@ +lib_LTLIBRARIES = libOMX.Exynos.MP3.Decoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_MP3_Decoder_la_SOURCES = Exynos_OMX_Mp3dec.c \ + Exynos_OMX_Mp3dec.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_MP3_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/audio/dec/libExynosOMX_Adec.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/audio/alp/libsrpapi.la + +libOMX_Exynos_MP3_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/exynos4/libcodec/audio/alp/include \ + -I$(top_srcdir)/openmax/component/audio/dec + + +libOMX_Exynos_MP3_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/audio/dec/mp3/library_register.c b/openmax/component/audio/dec/mp3/library_register.c new file mode 100644 index 0000000..f0775cc --- /dev/null +++ b/openmax/component/audio/dec/mp3/library_register.c @@ -0,0 +1,58 @@ +/* + * + * 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 library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MP3_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - audio decoder MP3 */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/openmax/component/audio/dec/mp3/library_register.h b/openmax/component/audio/dec/mp3/library_register.h new file mode 100644 index 0000000..7b9c34a --- /dev/null +++ b/openmax/component/audio/dec/mp3/library_register.h @@ -0,0 +1,54 @@ +/* + * + * 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 library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.1.0 + * @history + * 2012.02.28 : Create + */ + +#ifndef EXYNOS_OMX_MP3_DEC_REG +#define EXYNOS_OMX_MP3_DEC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MP3 */ +#define EXYNOS_OMX_COMPONENT_MP3_DEC "OMX.Exynos.MP3.Decoder" +#define EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE "audio_decoder.mp3" + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif /* EXYNOS_OMX_MP3_DEC_REG */ + diff --git a/openmax/component/common/Android.mk b/openmax/component/common/Android.mk new file mode 100644 index 0000000..05c8d30 --- /dev/null +++ b/openmax/component/common/Android.mk @@ -0,0 +1,56 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Basecomponent.c \ + Exynos_OMX_Baseport.c + +LOCAL_MODULE := libExynosOMX_Basecomponent + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Resourcemanager.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libExynosOMX_Resourcemanager + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/common/Exynos_OMX_Basecomponent.c b/openmax/component/common/Exynos_OMX_Basecomponent.c new file mode 100755 index 0000000..64390c4 --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Basecomponent.c @@ -0,0 +1,1582 @@ +/* + * + * 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 Exynos_OMX_Basecomponent.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Event.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Resourcemanager.h" +#include "Exynos_OMX_Macros.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_BASE_COMP" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + + +/* Change CHECK_SIZE_VERSION Macro */ +OMX_ERRORTYPE Exynos_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 Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName); + Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE)); + Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->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(); + Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID)); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_GetState ( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE *pState) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pState == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + *pState = pExynosComponent->currentState; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_MESSAGE *message; + OMX_STATETYPE destState = messageParam; + OMX_STATETYPE currentState = pExynosComponent->currentState; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 = Exynos_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))) { + Exynos_OMX_Release_Resource(pOMXComponent); + } + +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "destState: %d", destState); +#else + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "destState: %d", destState); +#endif + switch (destState) { + case OMX_StateInvalid: + switch (currentState) { + case OMX_StateWaitForResources: + Exynos_OMX_Out_WaitForResource(pOMXComponent); + case OMX_StateIdle: + case OMX_StateExecuting: + case OMX_StatePause: + case OMX_StateLoaded: + pExynosComponent->currentState = OMX_StateInvalid; + ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent); + + for (i = 0; i < ALL_PORT_NUM; i++) { + if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; + } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; + } + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); + pExynosComponent->pExynosPort[i].hPortMutex = NULL; + } + + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); + pExynosComponent->pauseEvent = NULL; + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); + pExynosComponent->pExynosPort[i].pauseEvent = NULL; + if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; + } + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); + pExynosComponent->pExynosPort[i].bufferSemID = NULL; + } + if (pExynosComponent->exynos_codec_componentTerminate != NULL) + pExynosComponent->exynos_codec_componentTerminate(pOMXComponent); + + ret = OMX_ErrorInvalidState; + break; + default: + ret = OMX_ErrorInvalidState; + break; + } + break; + case OMX_StateLoaded: + switch (currentState) { + case OMX_StateIdle: + ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent); + + for (i = 0; i < ALL_PORT_NUM; i++) { + if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; + } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; + } + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); + pExynosComponent->pExynosPort[i].hPortMutex = NULL; + } + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); + pExynosComponent->pauseEvent = NULL; + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); + pExynosComponent->pExynosPort[i].pauseEvent = NULL; + if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; + } + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); + pExynosComponent->pExynosPort[i].bufferSemID = NULL; + } + + pExynosComponent->exynos_codec_componentTerminate(pOMXComponent); + + for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) { + pExynosPort = (pExynosComponent->pExynosPort + i); + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message != NULL) + Exynos_OSAL_Free(message); + } + ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pExynosPort)) { + Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource); + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message != NULL) + Exynos_OSAL_Free(message); + } + pExynosPort->portDefinition.bPopulated = OMX_FALSE; + } + } + } + pExynosComponent->currentState = OMX_StateLoaded; + break; + case OMX_StateWaitForResources: + ret = Exynos_OMX_Out_WaitForResource(pOMXComponent); + pExynosComponent->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 < pExynosComponent->portParam.nPorts; i++) { + pExynosPort = (pExynosComponent->pExynosPort + i); + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + if (CHECK_PORT_ENABLED(pExynosPort)) { + ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i); + if (ret!=OMX_ErrorNone) + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pExynosPort)) { + Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[i].loadedResource); + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + } + } + } + ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + goto EXIT; + } + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalCreate(&pExynosComponent->pauseEvent); + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent); + if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) + Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { + ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { + ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + } + ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent); + pExynosComponent->pauseEvent = NULL; + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent); + pExynosComponent->pExynosPort[i].pauseEvent = NULL; + if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) { + Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent); + pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL; + } + } + } + for (i = 0; i < ALL_PORT_NUM; i++) { + if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL; + } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) { + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL; + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex); + pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL; + } + Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex); + pExynosComponent->pExynosPort[i].hPortMutex = NULL; + } + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID); + pExynosComponent->pExynosPort[i].bufferSemID = NULL; + } + + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pExynosComponent->currentState = OMX_StateIdle; + break; + case OMX_StateExecuting: + case OMX_StatePause: + Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE); + pExynosComponent->currentState = OMX_StateIdle; + break; + case OMX_StateWaitForResources: + pExynosComponent->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 < pExynosComponent->portParam.nPorts; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) { + for (j = 0; j < pExynosPort->tunnelBufferNum; j++) { + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID); + } + } + } + + pExynosComponent->transientState = EXYNOS_OMX_TransStateMax; + pExynosComponent->currentState = OMX_StateExecuting; + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent); + } + } + break; + case OMX_StatePause: + for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) { + OMX_S32 semaValue = 0, cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue); + if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) { + cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue; + for (k = 0; k < cnt; k++) { + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID); + } + } + } + } + + pExynosComponent->currentState = OMX_StateExecuting; + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + } else { + for (i = 0; i < ALL_PORT_NUM; i++) { + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].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: + pExynosComponent->currentState = OMX_StatePause; + break; + case OMX_StateExecuting: + pExynosComponent->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 = Exynos_OMX_In_WaitForResource(pOMXComponent); + pExynosComponent->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 (pExynosComponent->pCallbacks != NULL) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, OMX_CommandStateSet, + destState, NULL); + } + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__); + if (pExynosComponent->pCallbacks != NULL) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + OMX_U32 messageType = 0, portIndex = 0; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) { + Exynos_OSAL_SemaphoreWait(pExynosComponent->msgSemaphoreHandle); + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ); + if (message != NULL) { + messageType = message->messageType; + switch (messageType) { + case OMX_CommandStateSet: + ret = Exynos_OMX_ComponentStateSet(pOMXComponent, message->messageParam); + break; + case OMX_CommandFlush: + ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, message->messageParam, OMX_TRUE); + break; + case OMX_CommandPortDisable: + ret = Exynos_OMX_PortDisableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandPortEnable: + ret = Exynos_OMX_PortEnableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandMarkBuffer: + portIndex = message->messageParam; + pExynosComponent->pExynosPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent; + pExynosComponent->pExynosPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData; + break; + case (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit: + pExynosComponent->bExitMessageHandlerThread = OMX_TRUE; + break; + default: + break; + } + Exynos_OSAL_Free(message); + message = NULL; + } + } + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_StateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) +{ + OMX_U32 destState = nParam; + OMX_U32 i = 0; + + if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateLoaded)) { + pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle; + for(i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosComponent->pExynosPort[i].portState = OMX_StateIdle; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) { + pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded; + for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosComponent->pExynosPort[i].portState = OMX_StateLoaded; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateLoaded"); + } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) { + pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting"); + } else if (destState == OMX_StateInvalid) { + for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid; + } + } + + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0, index = 0; + + + if ((pExynosComponent->currentState == OMX_StateExecuting) || + (pExynosComponent->currentState == OMX_StatePause)) { + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->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; + pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE; + } + } else { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + if (CHECK_PORT_ENABLED(pExynosPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pExynosPort->portState = OMX_StateIdle; + } + } + } else { + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + if (CHECK_PORT_ENABLED(pExynosPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pExynosPort->portState = OMX_StateIdle; + } + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_S32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pExynosComponent->portParam.nPorts; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + if (!CHECK_PORT_ENABLED(pExynosPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + pExynosPort->portState = OMX_StateLoaded; + pExynosPort->bIsPortDisabled = OMX_TRUE; + } + } else { + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + pExynosPort->portState = OMX_StateLoaded; + pExynosPort->bIsPortDisabled = OMX_TRUE; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + + if (nParam >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pExynosComponent->currentState == OMX_StateExecuting) || + (pExynosComponent->currentState == OMX_StatePause)) { + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorIncorrectStateOperation; + } + +EXIT: + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_CommandQueue( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + OMX_COMMANDTYPE Cmd, + OMX_U32 nParam, + OMX_PTR pCmdData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); + + if (command == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + command->messageType = (OMX_U32)Cmd; + command->messageParam = nParam; + command->pCmdData = pCmdData; + + ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (Cmd) { + case OMX_CommandStateSet : + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandStateSet"); + Exynos_StateSet(pExynosComponent, nParam); + break; + case OMX_CommandFlush : + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush"); + ret = Exynos_SetPortFlush(pExynosComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortDisable : + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable"); + ret = Exynos_SetPortDisable(pExynosComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortEnable : + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable"); + ret = Exynos_SetPortEnable(pExynosComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandMarkBuffer : + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer"); + ret = Exynos_SetMarkBuffer(pExynosComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + default: + break; + } + + ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = Exynos_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; + EXYNOS_OMX_BASEPORT *pExynosPort; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + compPriority->nGroupID = pExynosComponent->compPriority.nGroupID; + compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority; + } + break; + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort; + + if ((pExynosComponent->currentState == OMX_StateLoaded) || + (pExynosComponent->currentState == OMX_StateWaitForResources)) { + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + + if (pExynosPort->portDefinition.eDir == OMX_DirInput) { + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; + } else if (CHECK_PORT_TUNNELED(pExynosPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + } else { + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else if (CHECK_PORT_TUNNELED(pExynosPort)) { + 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 Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->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 = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && + (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorUndefined; + /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */ + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition_backup; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, portDefinition->nSize); + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, portDefinition, portDefinition->nSize); + RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && + (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosComponent->compPriority.nGroupID = compPriority->nGroupID; + pExynosComponent->compPriority.nGroupPriority = compPriority->nGroupPriority; + } + break; + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pExynosPort) == 0) { + ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/ + goto EXIT; + } + + if (pExynosPort->portDefinition.eDir == OMX_DirInput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorNone; + } + */ + pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pExynosPort->tunneledPort; + ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pExynosPort->tunneledPort; + ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + } + goto EXIT; + } + } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER; + ret = OMX_ErrorNone; + } + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorNone; + } + */ + pExynosPort->tunnelFlags |= EXYNOS_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 Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = OMX_ErrorUnsupportedIndex; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = OMX_ErrorUnsupportedIndex; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = OMX_ErrorBadParameter; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pCallbacks == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (pExynosComponent->currentState != OMX_StateLoaded) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pExynosComponent->pCallbacks = pCallbacks; + pExynosComponent->callbackData = pAppData; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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 Exynos_OMX_BaseComponent_Constructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT)); + if (pExynosComponent == NULL) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT)); + pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent; + + ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->msgSemaphoreHandle); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent->bExitMessageHandlerThread = OMX_FALSE; + Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS); + ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent->bMultiThreadProcess = OMX_FALSE; + + pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion; + pOMXComponent->SendCommand = &Exynos_OMX_SendCommand; + pOMXComponent->GetState = &Exynos_OMX_GetState; + pOMXComponent->SetCallbacks = &Exynos_OMX_SetCallbacks; + pOMXComponent->UseEGLImage = &Exynos_OMX_UseEGLImage; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_S32 semaValue = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + Exynos_OMX_CommandQueue(pExynosComponent, EXYNOS_OMX_CommandComponentDeInit, 0, NULL); + Exynos_OSAL_SleepMillisec(0); + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue); + if (semaValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); + Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle); + + Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler); + pExynosComponent->hMessageHandler = NULL; + + Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex); + pExynosComponent->compMutex = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle); + pExynosComponent->msgSemaphoreHandle = NULL; + Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ); + + Exynos_OSAL_Free(pExynosComponent); + pExynosComponent = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + + diff --git a/openmax/component/common/Exynos_OMX_Basecomponent.h b/openmax/component/common/Exynos_OMX_Basecomponent.h new file mode 100644 index 0000000..6e889f8 --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Basecomponent.h @@ -0,0 +1,151 @@ +/* + * + * 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 Exynos_OMX_Basecomponent.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_BASECOMP +#define EXYNOS_OMX_BASECOMP + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" + + +typedef struct _EXYNOS_OMX_MESSAGE +{ + OMX_U32 messageType; + OMX_U32 messageParam; + OMX_PTR pCmdData; +} EXYNOS_OMX_MESSAGE; + +/* for Check TimeStamp after Seek */ +typedef struct _EXYNOS_OMX_TIMESTAMP +{ + OMX_BOOL needSetStartTimeStamp; + OMX_BOOL needCheckStartTimeStamp; + OMX_TICKS startTimeStamp; + OMX_U32 nStartFlags; + OMX_BOOL bImmediateDisplay; +} EXYNOS_OMX_TIMESTAMP; + +typedef struct _EXYNOS_OMX_BASECOMPONENT +{ + OMX_STRING componentName; + OMX_VERSIONTYPE componentVersion; + OMX_VERSIONTYPE specVersion; + + OMX_STATETYPE currentState; + EXYNOS_OMX_TRANS_STATETYPE transientState; + + EXYNOS_CODEC_TYPE codecType; + EXYNOS_OMX_PRIORITYMGMTTYPE compPriority; + OMX_MARKTYPE propagateMarkType; + OMX_HANDLETYPE compMutex; + + OMX_HANDLETYPE hComponentHandle; + + /* Message Handler */ + OMX_BOOL bExitMessageHandlerThread; + OMX_HANDLETYPE hMessageHandler; + OMX_HANDLETYPE msgSemaphoreHandle; + EXYNOS_QUEUE messageQ; + + /* Port */ + OMX_PORT_PARAM_TYPE portParam; + EXYNOS_OMX_BASEPORT *pExynosPort; + + OMX_HANDLETYPE pauseEvent; + + /* Callback function */ + OMX_CALLBACKTYPE *pCallbacks; + OMX_PTR callbackData; + + /* Save Timestamp */ + OMX_TICKS timeStamp[MAX_TIMESTAMP]; + EXYNOS_OMX_TIMESTAMP checkTimeStamp; + + /* Save Flags */ + OMX_U32 nFlags[MAX_FLAGS]; + + OMX_BOOL getAllDelayBuffer; + OMX_BOOL reInputData; + + OMX_BOOL bUseFlagEOF; + OMX_BOOL bSaveFlagEOS; + + /* Check for Old & New OMX Process type switch */ + OMX_BOOL bMultiThreadProcess; + + OMX_ERRORTYPE (*exynos_codec_componentInit)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*exynos_codec_componentTerminate)(OMX_COMPONENTTYPE *pOMXComponent); + + OMX_ERRORTYPE (*exynos_AllocateTunnelBuffer)(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_FreeTunnelBuffer)(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_BufferProcessCreate)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*exynos_BufferProcessTerminate)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*exynos_BufferFlush)(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent); +} EXYNOS_OMX_BASECOMPONENT; + +OMX_ERRORTYPE Exynos_OMX_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE Exynos_OMX_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE Exynos_OMX_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + +OMX_ERRORTYPE Exynos_OMX_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + +OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); + +OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +extern "C" { +#endif + + OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size); + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/common/Exynos_OMX_Baseport.c b/openmax/component/common/Exynos_OMX_Baseport.c new file mode 100755 index 0000000..c0f0af8 --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Baseport.c @@ -0,0 +1,933 @@ +/* + * + * 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 Exynos_OMX_Baseport.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" + +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Basecomponent.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_BASE_PORT" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + + +OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + OMX_U32 i = 0; + + Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { + pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE; + break; + } + } + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + + if ((bufferHeader != NULL) && (bufferHeader->pBuffer != NULL)) + { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d EmptyBufferDone", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 i = 0; + + Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { + pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE; + break; + } + } + + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + + if ((bufferHeader != NULL) && (bufferHeader->pBuffer != NULL)) + { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d FillBufferDone", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader); + } + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_S32 portIndex = 0; + EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL}; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlushProcess cnt:%d port:%d", cnt, nPortIndex); +#endif + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + pExynosComponent->exynos_BufferFlush(pOMXComponent, portIndex, bEvent); + } + +EXIT: + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__); + + if ((pOMXComponent != NULL) && (pExynosComponent != NULL)) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, pExynosComponent->callbackData, OMX_EventError, ret, 0, NULL); + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "enablePort idx:%d", portIndex); +#endif + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + Exynos_OSAL_SemaphoreWait(pExynosPort->loadedResource); + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + } + pExynosPort->exceptionFlag = GENERAL_STATE; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; + +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "portEnableProcess cnt:%d port:%d", cnt, nPortIndex); +#endif + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = Exynos_OMX_EnablePort(pOMXComponent, portIndex); + if (ret == OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortEnable, portIndex, NULL); + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_U32 i = 0, elemNum = 0; + EXYNOS_OMX_MESSAGE *message; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "disablePort idx:%d", portIndex); +#endif + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if (!CHECK_PORT_ENABLED(pExynosPort)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosComponent->currentState != OMX_StateLoaded) { + if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + Exynos_OSAL_Free(message); + } + } + pExynosPort->portDefinition.bPopulated = OMX_FALSE; + Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource); + } + pExynosPort->portDefinition.bEnabled = OMX_FALSE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL}; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "portDisableProcess cnt:%d port:%d", cnt, nPortIndex); +#endif + + /* port flush*/ + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE); + } + + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = Exynos_OMX_DisablePort(pOMXComponent, portIndex); + pExynosComponent->pExynosPort[portIndex].bIsPortDisabled = OMX_FALSE; + if (ret == OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortDisable, portIndex, NULL); + } + } + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + EXYNOS_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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 = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateIdle) && + (pExynosComponent->currentState != OMX_StateExecuting) && + (pExynosComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pExynosPort)) || + ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) && + (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) || + ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { + pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE; + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + + message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + message->messageType = EXYNOS_OMX_CommandEmptyBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message); + if (ret != 0) { + ret = OMX_ErrorUndefined; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_FillThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + EXYNOS_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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 = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateIdle) && + (pExynosComponent->currentState != OMX_StateExecuting) && + (pExynosComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pExynosPort)) || + ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) && + (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) || + ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + Exynos_OSAL_MutexLock(pExynosPort->hPortMutex); + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) { + pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE; + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + + message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + message->messageType = EXYNOS_OMX_CommandFillBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message); + if (ret != 0) { + ret = OMX_ErrorUndefined; + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + goto EXIT; + } + + ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE); + pExynosComponent->portParam.nPorts = ALL_PORT_NUM; + pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; + + pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM); + if (pExynosPort == NULL) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM); + pExynosComponent->pExynosPort = pExynosPort; + + /* Input Port */ + pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX]; + + Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS); + + pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); + if (pExynosInputPort->extendBufferHeader == NULL) { + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); + + pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pExynosInputPort->bufferStateAllocate == NULL) { + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pExynosInputPort->bufferSemID = NULL; + pExynosInputPort->assignedBufferNum = 0; + pExynosInputPort->portState = OMX_StateMax; + pExynosInputPort->bIsPortFlushed = OMX_FALSE; + pExynosInputPort->bIsPortDisabled = OMX_FALSE; + pExynosInputPort->tunneledComponent = NULL; + pExynosInputPort->tunneledPort = 0; + pExynosInputPort->tunnelBufferNum = 0; + pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pExynosInputPort->tunnelFlags = 0; + ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + goto EXIT; + } + ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); + pExynosInputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; + pExynosInputPort->portDefinition.eDir = OMX_DirInput; + pExynosInputPort->portDefinition.nBufferCountActual = 0; + pExynosInputPort->portDefinition.nBufferCountMin = 0; + pExynosInputPort->portDefinition.nBufferSize = 0; + pExynosInputPort->portDefinition.bEnabled = OMX_FALSE; + pExynosInputPort->portDefinition.bPopulated = OMX_FALSE; + pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax; + pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pExynosInputPort->portDefinition.nBufferAlignment = 0; + pExynosInputPort->markType.hMarkTargetComponent = NULL; + pExynosInputPort->markType.pMarkData = NULL; + pExynosInputPort->exceptionFlag = GENERAL_STATE; + + /* Output Port */ + pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX]; + + Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */ + + pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); + if (pExynosOutputPort->extendBufferHeader == NULL) { + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); + pExynosInputPort->unloadedResource = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); + pExynosInputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM); + + pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pExynosOutputPort->bufferStateAllocate == NULL) { + Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); + pExynosOutputPort->extendBufferHeader = NULL; + + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); + pExynosInputPort->unloadedResource = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); + pExynosInputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pExynosOutputPort->bufferSemID = NULL; + pExynosOutputPort->assignedBufferNum = 0; + pExynosOutputPort->portState = OMX_StateMax; + pExynosOutputPort->bIsPortFlushed = OMX_FALSE; + pExynosOutputPort->bIsPortDisabled = OMX_FALSE; + pExynosOutputPort->tunneledComponent = NULL; + pExynosOutputPort->tunneledPort = 0; + pExynosOutputPort->tunnelBufferNum = 0; + pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pExynosOutputPort->tunnelFlags = 0; + ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate); + pExynosOutputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); + pExynosOutputPort->extendBufferHeader = NULL; + + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); + pExynosInputPort->unloadedResource = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); + pExynosInputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + goto EXIT; + } + ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->loadedResource); + pExynosOutputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate); + pExynosOutputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader); + pExynosOutputPort->extendBufferHeader = NULL; + + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource); + pExynosInputPort->unloadedResource = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource); + pExynosInputPort->loadedResource = NULL; + Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate); + pExynosInputPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader); + pExynosInputPort->extendBufferHeader = NULL; + Exynos_OSAL_Free(pExynosPort); + pExynosPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; + pExynosOutputPort->portDefinition.eDir = OMX_DirOutput; + pExynosOutputPort->portDefinition.nBufferCountActual = 0; + pExynosOutputPort->portDefinition.nBufferCountMin = 0; + pExynosOutputPort->portDefinition.nBufferSize = 0; + pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE; + pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE; + pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax; + pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pExynosOutputPort->portDefinition.nBufferAlignment = 0; + pExynosOutputPort->markType.hMarkTargetComponent = NULL; + pExynosOutputPort->markType.pMarkData = NULL; + pExynosOutputPort->exceptionFlag = GENERAL_STATE; + + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.startTimeStamp = 0; + pExynosComponent->checkTimeStamp.nStartFlags = 0x0; + + pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer; + pOMXComponent->FillThisBuffer = &Exynos_OMX_FillThisBuffer; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + int i = 0; + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + for (i = 0; i < ALL_PORT_NUM; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + + Exynos_OSAL_SemaphoreTerminate(pExynosPort->loadedResource); + pExynosPort->loadedResource = NULL; + Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource); + pExynosPort->unloadedResource = NULL; + Exynos_OSAL_Free(pExynosPort->bufferStateAllocate); + pExynosPort->bufferStateAllocate = NULL; + Exynos_OSAL_Free(pExynosPort->extendBufferHeader); + pExynosPort->extendBufferHeader = NULL; + + Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ); + } + Exynos_OSAL_Free(pExynosComponent->pExynosPort); + pExynosComponent->pExynosPort = NULL; + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pDataBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pDataBuffer->dataValid = OMX_FALSE; + pDataBuffer->dataLen = 0; + pDataBuffer->remainDataLen = 0; + pDataBuffer->usedDataLen = 0; + pDataBuffer->bufferHeader = NULL; + pDataBuffer->nFlags = 0; + pDataBuffer->timeStamp = 0; + pDataBuffer->pPrivate = NULL; + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pData->dataLen = 0; + pData->usedDataLen = 0; + pData->remainDataLen = 0; + pData->nFlags = 0; + pData->timeStamp = 0; + pData->pPrivate = NULL; + pData->bufferHeader = NULL; + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (nPlane == ONE_PLANE) { + /* Case of Shared Buffer, Only support singlePlaneBuffer */ + pData->buffer.singlePlaneBuffer.dataBuffer = pUseBuffer->bufferHeader->pBuffer; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane"); + ret = OMX_ErrorNotImplemented; + goto EXIT; + } + + pData->allocSize = pUseBuffer->allocSize; + pData->dataLen = pUseBuffer->dataLen; + pData->usedDataLen = pUseBuffer->usedDataLen; + pData->remainDataLen = pUseBuffer->remainDataLen; + pData->timeStamp = pUseBuffer->timeStamp; + pData->nFlags = pUseBuffer->nFlags; + pData->pPrivate = pUseBuffer->pPrivate; + pData->bufferHeader = pUseBuffer->bufferHeader; + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + pUseBuffer->bufferHeader = pData->bufferHeader; + pUseBuffer->allocSize = pData->allocSize; + pUseBuffer->dataLen = pData->dataLen; + pUseBuffer->usedDataLen = pData->usedDataLen; + pUseBuffer->remainDataLen = pData->remainDataLen; + pUseBuffer->timeStamp = pData->timeStamp; + pUseBuffer->nFlags = pData->nFlags; + pUseBuffer->pPrivate = pData->pPrivate; + + return ret; +} diff --git a/openmax/component/common/Exynos_OMX_Baseport.h b/openmax/component/common/Exynos_OMX_Baseport.h new file mode 100644 index 0000000..1b46f7b --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Baseport.h @@ -0,0 +1,215 @@ +/* + * + * 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 Exynos_OMX_Baseport.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_BASE_PORT +#define EXYNOS_OMX_BASE_PORT + + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Def.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 40 + +#define INPUT_PORT_INDEX 0 +#define OUTPUT_PORT_INDEX 1 +#define ALL_PORT_INDEX -1 +#define ALL_PORT_NUM 2 + + +typedef struct _EXYNOS_OMX_BUFFERHEADERTYPE +{ + OMX_BUFFERHEADERTYPE *OMXBufferHeader; + OMX_BOOL bBufferInOMX; + OMX_HANDLETYPE ANBHandle; + void *pYUVBuf[MAX_BUFFER_PLANE]; + int buf_fd[MAX_BUFFER_PLANE]; +} EXYNOS_OMX_BUFFERHEADERTYPE; + +typedef struct _EXYNOS_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; + OMX_PTR pPrivate; +} EXYNOS_OMX_DATABUFFER; + +typedef void* CODEC_EXTRA_BUFFERINFO; + +typedef struct _EXYNOS_OMX_SINGLEPLANE_DATA +{ + OMX_PTR dataBuffer; + int fd; +} EXYNOS_OMX_SINGLEPLANE_DATA; + +typedef struct _EXYNOS_OMX_MULTIPLANE_DATA +{ + OMX_U32 validPlaneNum; + OMX_PTR dataBuffer[MAX_BUFFER_PLANE]; + int fd[MAX_BUFFER_PLANE]; +} EXYNOS_OMX_MULTIPLANE_DATA; + +typedef struct _EXYNOS_OMX_DATA +{ + union { + EXYNOS_OMX_SINGLEPLANE_DATA singlePlaneBuffer; + EXYNOS_OMX_MULTIPLANE_DATA multiPlaneBuffer; + } buffer; + OMX_U32 allocSize; + OMX_U32 dataLen; + OMX_U32 usedDataLen; + OMX_U32 remainDataLen; + OMX_U32 nFlags; + OMX_TICKS timeStamp; + OMX_PTR pPrivate; + CODEC_EXTRA_BUFFERINFO extInfo; + + /* For Share Buffer */ + OMX_BUFFERHEADERTYPE* bufferHeader; +} EXYNOS_OMX_DATA; + +typedef struct _EXYNOS_OMX_WAY1_PORT_DATABUFFER +{ + EXYNOS_OMX_DATABUFFER dataBuffer; +} EXYNOS_OMX_PORT_1WAY_DATABUFFER; + +typedef struct _EXYNOS_OMX_WAY2_PORT_DATABUFFER +{ + EXYNOS_OMX_DATABUFFER inputDataBuffer; + EXYNOS_OMX_DATABUFFER outputDataBuffer; +} EXYNOS_OMX_PORT_2WAY_DATABUFFER; + +typedef enum _EXYNOS_OMX_PORT_WAY_TYPE +{ + WAY1_PORT = 0x00, + WAY2_PORT +} EXYNOS_OMX_PORT_WAY_TYPE; + +typedef enum _EXYNOS_OMX_EXCEPTION_STATE +{ + GENERAL_STATE = 0x00, + NEED_PORT_FLUSH, + NEED_PORT_DISABLE, +} EXYNOS_OMX_EXCEPTION_STATE; + +typedef enum _EXYNOS_OMX_PLANE +{ + ONE_PLANE = 0x01, + TWO_PLANE = 0x02, + THREE_PLANE = 0x03, +/* + ANB_START_PLANE = 0x10, + ANB_ONE_PLANE = 0x11, + ANB_TWO_PLANE = 0x12, + ANB_THREE_PLANE = 0x13, +*/ +} EXYNOS_OMX_PLANE; + +typedef struct _EXYNOS_OMX_BASEPORT +{ + EXYNOS_OMX_BUFFERHEADERTYPE *extendBufferHeader; + OMX_U32 *bufferStateAllocate; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + OMX_HANDLETYPE bufferSemID; + EXYNOS_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 bIsPBEnabled; + OMX_BOOL bStoreMetaData; + + EXYNOS_OMX_BUFFERPROCESS_TYPE bufferProcessType; + EXYNOS_OMX_PORT_WAY_TYPE portWayType; + OMX_HANDLETYPE codecSemID; + EXYNOS_QUEUE codecBufferQ; + + OMX_HANDLETYPE pauseEvent; + + /* Buffer */ + union { + EXYNOS_OMX_PORT_1WAY_DATABUFFER port1WayDataBuffer; + EXYNOS_OMX_PORT_2WAY_DATABUFFER port2WayDataBuffer; + } way; + + /* Data */ + EXYNOS_OMX_DATA processData; + + /* for flush of Shared buffer scheme */ + OMX_HANDLETYPE hAllCodecBufferReturnEvent; + OMX_HANDLETYPE hPortMutex; + EXYNOS_OMX_EXCEPTION_STATE exceptionFlag; +} EXYNOS_OMX_BASEPORT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent); +OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer); +OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData); +OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane); +OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer); + +#ifdef __cplusplus +}; +#endif + + +#endif diff --git a/openmax/component/common/Exynos_OMX_Resourcemanager.c b/openmax/component/common/Exynos_OMX_Resourcemanager.c new file mode 100644 index 0000000..6383566 --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Resourcemanager.c @@ -0,0 +1,482 @@ +/* + * + * 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 Exynos_OMX_Resourcemanager.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Resourcemanager.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Mutex.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_RM" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +#ifdef SLP_PLATFORM +#define MAX_RESOURCE_VIDEO_DEC 8 /* for SLP */ +#define MAX_RESOURCE_VIDEO_ENC 2 /* for SLP */ +#else +#define MAX_RESOURCE_VIDEO_DEC 3 /* for Android */ +#define MAX_RESOURCE_VIDEO_ENC 1 /* for Android */ +#endif + +/* Max allowable video scheduler component instance */ +static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL; +static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL; +static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL; +static EXYNOS_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL; +static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; + + +OMX_ERRORTYPE addElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (*ppList != NULL) { + pTempComp = *ppList; + while (pTempComp->pNext != NULL) { + pTempComp = pTempComp->pNext; + } + pTempComp->pNext = (EXYNOS_OMX_RM_COMPONENT_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_RM_COMPONENT_LIST)); + if (pTempComp->pNext == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL; + ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent; + ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pExynosComponent->compPriority.nGroupPriority; + goto EXIT; + } else { + *ppList = (EXYNOS_OMX_RM_COMPONENT_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_RM_COMPONENT_LIST)); + if (*ppList == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pTempComp = *ppList; + pTempComp->pNext = NULL; + pTempComp->pOMXStandComp = pOMXComponent; + pTempComp->groupPriority = pExynosComponent->compPriority.nGroupPriority; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE removeElementList(EXYNOS_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; + EXYNOS_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; + Exynos_OSAL_Free(pCurrComp); + } else { + if (pPrevComp != NULL) + pPrevComp->pNext = pCurrComp->pNext; + + Exynos_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(EXYNOS_OMX_RM_COMPONENT_LIST *RMComp_list, OMX_U32 inComp_priority, EXYNOS_OMX_RM_COMPONENT_LIST **outLowComp) +{ + int ret = 0; + EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + EXYNOS_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateIdle) { + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, pExynosComponent->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 ((pExynosComponent->currentState == OMX_StateExecuting) || (pExynosComponent->currentState == OMX_StatePause)) { + /* Todo */ + } + + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + + +OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init() +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + ret = Exynos_OSAL_MutexCreate(&ghVideoRMComponentListMutex); + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit() +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComponent; + EXYNOS_OMX_RM_COMPONENT_LIST *pNextComponent; + + FunctionIn(); + + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + + if (gpVideoDecRMComponentList) { + pCurrComponent = gpVideoDecRMComponentList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoDecRMComponentList = NULL; + } + if (gpVideoDecRMWaitingList) { + pCurrComponent = gpVideoDecRMWaitingList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoDecRMWaitingList = NULL; + } + + if (gpVideoEncRMComponentList) { + pCurrComponent = gpVideoEncRMComponentList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoEncRMComponentList = NULL; + } + if (gpVideoEncRMWaitingList) { + pCurrComponent = gpVideoEncRMWaitingList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + Exynos_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoEncRMWaitingList = NULL; + } + + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + Exynos_OSAL_MutexTerminate(ghVideoRMComponentListMutex); + ghVideoRMComponentListMutex = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; + int numElem = 0; + int lowCompDetect = 0; + + FunctionIn(); + + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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, pExynosComponent->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 (pExynosComponent->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, pExynosComponent->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: + + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; + int numElem = 0; + + FunctionIn(); + + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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 (pExynosComponent->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: + + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) + ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent); + else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) + ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent); + + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) + ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent); + else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) + ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent); + + Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + diff --git a/openmax/component/common/Exynos_OMX_Resourcemanager.h b/openmax/component/common/Exynos_OMX_Resourcemanager.h new file mode 100644 index 0000000..e9db7c4 --- /dev/null +++ b/openmax/component/common/Exynos_OMX_Resourcemanager.h @@ -0,0 +1,59 @@ +/* + * + * 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 Exynos_OMX_Resourcemanager.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_RESOURCEMANAGER +#define EXYNOS_OMX_RESOURCEMANAGER + + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" + + +struct EXYNOS_OMX_RM_COMPONENT_LIST; +typedef struct _EXYNOS_OMX_RM_COMPONENT_LIST +{ + OMX_COMPONENTTYPE *pOMXStandComp; + OMX_U32 groupPriority; + struct _EXYNOS_OMX_RM_COMPONENT_LIST *pNext; +} EXYNOS_OMX_RM_COMPONENT_LIST; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init(); +OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit(); +OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/common/Makefile.am b/openmax/component/common/Makefile.am new file mode 100644 index 0000000..742f6f5 --- /dev/null +++ b/openmax/component/common/Makefile.am @@ -0,0 +1,24 @@ +lib_LTLIBRARIES = libExynosOMX_Resourcemanager.la \ + libExynosOMX_Basecomponent.la + + +libExynosOMX_Resourcemanager_la_SOURCES = Exynos_OMX_Resourcemanager.c \ + Exynos_OMX_Resourcemanager.h + +libExynosOMX_Resourcemanager_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la +libExynosOMX_Resourcemanager_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal + + +libExynosOMX_Basecomponent_la_SOURCES = Exynos_OMX_Basecomponent.c \ + Exynos_OMX_Basecomponent.h \ + Exynos_OMX_Baseport.c \ + Exynos_OMX_Baseport.h + +libExynosOMX_Basecomponent_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la + +libExynosOMX_Basecomponent_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal diff --git a/openmax/component/video/Makefile.am b/openmax/component/video/Makefile.am new file mode 100644 index 0000000..5b86dc8 --- /dev/null +++ b/openmax/component/video/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = dec enc diff --git a/openmax/component/video/dec/Android.mk b/openmax/component/video/dec/Android.mk new file mode 100644 index 0000000..5d3ff78 --- /dev/null +++ b/openmax/component/video/dec/Android.mk @@ -0,0 +1,40 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + Exynos_OMX_VdecControl.c \ + Exynos_OMX_Vdec.c + +LOCAL_MODULE := libExynosOMX_Vdec +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +LOCAL_STATIC_LIBRARIES := libExynosVideoApi + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_STATIC_LIBRARIES += libExynosOMX_OSAL libcsc_helper +LOCAL_CFLAGS += -DUSE_ANB +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.c b/openmax/component/video/dec/Exynos_OMX_Vdec.c new file mode 100755 index 0000000..1c1dddf --- /dev/null +++ b/openmax/component/video/dec/Exynos_OMX_Vdec.c @@ -0,0 +1,1342 @@ +/* + * + * 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 Exynos_OMX_Vdec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +#include "ExynosVideoApi.h" +#include "csc.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DEC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +int calc_plane(int width, int height) +{ + int mbX, mbY; + + mbX = ALIGN(width, S5P_FIMV_NV12MT_HALIGN); + mbY = ALIGN(height, S5P_FIMV_NV12MT_VALIGN); + + return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN); +} + +int calc_yplane(int width, int height) +{ + int mbX, mbY; + + mbX = ALIGN(width + 24, S5P_FIMV_NV12MT_HALIGN); + mbY = ALIGN(height + 16, S5P_FIMV_NV12MT_VALIGN); + + return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN); +} + +int calc_uvplane(int width, int height) +{ + int mbX, mbY; + + mbX = ALIGN(width + 16, S5P_FIMV_NV12MT_HALIGN); + mbY = ALIGN(height + 4, S5P_FIMV_NV12MT_VALIGN); + + return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN); +} + +inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + if ((exynosOutputPort->portDefinition.format.video.nFrameWidth != + exynosInputPort->portDefinition.format.video.nFrameWidth) || + (exynosOutputPort->portDefinition.format.video.nFrameHeight != + exynosInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + exynosOutputPort->portDefinition.format.video.nFrameWidth = + exynosInputPort->portDefinition.format.video.nFrameWidth; + exynosOutputPort->portDefinition.format.video.nFrameHeight = + exynosInputPort->portDefinition.format.video.nFrameHeight; + width = exynosOutputPort->portDefinition.format.video.nStride = + exynosInputPort->portDefinition.format.video.nStride; + height = exynosOutputPort->portDefinition.format.video.nSliceHeight = + exynosInputPort->portDefinition.format.video.nSliceHeight; + + switch(exynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + if (width && height) + exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; +#ifdef SLP_PLATFORM /* nv12t fd */ + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + if (width && height) + exynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + break; +#endif + case OMX_SEC_COLOR_FormatNV12Tiled: + width = exynosOutputPort->portDefinition.format.video.nFrameWidth; + height = exynosOutputPort->portDefinition.format.video.nFrameHeight; + if (width && height) { + int YBufferSize = calc_plane(width, height); + int CBufferSize = calc_plane(width, height >> 1); + exynosOutputPort->portDefinition.nBufferSize = YBufferSize + CBufferSize; + } + break; + default: + if (width && height) + exynosOutputPort->portDefinition.nBufferSize = width * height * 2; + break; + } + } + + return; +} + +OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) +{ + OMX_BOOL ret = OMX_FALSE; +#ifdef SLP_PLATFORM /* check state */ + if (pExynosComponent->currentState != OMX_StateExecuting) + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateExecuting"); + + if (pExynosComponent->pExynosPort[nPortIndex].portState != OMX_StateIdle) + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateIdle"); + + if (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateExecutingToIdle"); + + if (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToExecuting) + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateIdleToExecuting"); + + if ((pExynosComponent->currentState == OMX_StateExecuting) && + (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) { + ret = OMX_TRUE; +#else + if ((pExynosComponent->currentState == OMX_StateExecuting) && + (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) { + ret = OMX_TRUE; +#endif + } else { + ret = OMX_FALSE; + } + + return ret; +} + +OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + CODEC_DEC_BUFFER *pInputCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer; + + pData->buffer.singlePlaneBuffer.dataBuffer = pInputCodecBuffer->pVirAddr[0]; + pData->buffer.singlePlaneBuffer.fd = pInputCodecBuffer->fd[0]; + pData->allocSize = pInputCodecBuffer->bufferSize[0]; + pData->dataLen = pInputCodecBuffer->dataSize; + pData->usedDataLen = 0; + pData->remainDataLen = pInputCodecBuffer->dataSize; + + pData->nFlags = 0; + pData->timeStamp = 0; + pData->pPrivate = codecBuffer; + pData->bufferHeader = NULL; + + return ret; +} + +OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + OMX_PTR pSrcBuf[MAX_BUFFER_PLANE]; + OMX_U32 allocSize[MAX_BUFFER_PLANE]; + + pVideoDec->exynos_codec_getCodecOutputPrivateData(codecBuffer, pSrcBuf, allocSize); + pData->buffer.multiPlaneBuffer.dataBuffer[0] = pSrcBuf[0]; + pData->buffer.multiPlaneBuffer.dataBuffer[1] = pSrcBuf[1]; + pData->buffer.multiPlaneBuffer.dataBuffer[2] = pSrcBuf[2]; + pData->allocSize = allocSize[0] + allocSize[1] + allocSize[2]; + pData->dataLen = 0; + pData->usedDataLen = 0; + pData->remainDataLen = 0; + + pData->nFlags = 0; + pData->timeStamp = 0; + pData->pPrivate = codecBuffer; + pData->bufferHeader = NULL; + + return ret; +} + +void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) +{ + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL; + + FunctionIn(); + + exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (((pExynosComponent->currentState == OMX_StatePause) || + (pExynosComponent->currentState == OMX_StateIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) && + (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) { + Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent); + } + + FunctionOut(); + + return; +} + +OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_U32 copySize = 0; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; +#ifdef SLP_PLATFORM + SCMN_IMGB *pSlpOutBuf = NULL; +#endif + + FunctionIn(); + + OMX_U32 width = 0, height = 0; + int imageSize = 0; + OMX_COLOR_FORMATTYPE colorFormat; + + void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer; + void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, }; + void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, }; + + CSC_ERRORCODE cscRet = CSC_ErrorNone; + CSC_METHOD csc_method = CSC_METHOD_SW; + unsigned int cacheable = 1; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo; + + width = pBufferInfo->imageWidth; + height = pBufferInfo->imageHeight; + imageSize = width * height; + colorFormat = pBufferInfo->ColorFormat; + +#ifdef SLP_PLATFORM + pSlpOutBuf = (SCMN_IMGB *)pOutputBuf; + pSlpOutBuf->w[0] = width; + pSlpOutBuf->w[1] = width; + pSlpOutBuf->h[0] = height; + pSlpOutBuf->h[1] = height/2; + pSlpOutBuf->s[0] = width; /* need to check. stride */ + pSlpOutBuf->s[1] = width; + pSlpOutBuf->e[0] = height; /* need to check. elevation */ + pSlpOutBuf->e[1] = height/2; + + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { + pSlpOutBuf->a[0] = 0; + pSlpOutBuf->a[1] = 0; + } else { + pSlpOutBuf->a[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0]; + pSlpOutBuf->a[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1]; + } + pSlpOutBuf->a[2] = 0; /* omx do not use this plane */ + + + pSlpOutBuf->fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; + pSlpOutBuf->fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; + pSlpOutBuf->fd[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2]; + + pSlpOutBuf->buf_share_method = MEMORY_DMABUF; + dstOutputData->dataLen = sizeof(SCMN_IMGB); + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->fd[2]); + + ret = OMX_TRUE; + goto EXIT; +#endif + + pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0]; + pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1]; + pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2]; + + pYUVBuf[0] = (unsigned char *)pOutputBuf; + pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; + pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; + + csc_get_method(pVideoDec->csc_handle, &csc_method); +#ifdef USE_DMA_BUF + if (csc_method == CSC_METHOD_HW) { + pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; + pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; + pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2]; + } +#endif + +#ifdef USE_PB + if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) { + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + OMX_U32 stride; + Exynos_OSAL_LockPB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes); + width = stride; + outputUseBuffer->dataLen = sizeof(void *); + + pYUVBuf[0] = (unsigned char *)planes[0].addr; + pYUVBuf[1] = (unsigned char *)planes[1].addr; + pYUVBuf[2] = (unsigned char *)planes[2].addr; +#ifdef USE_DMA_BUF + if (csc_method == CSC_METHOD_HW) { + pYUVBuf[0] = (unsigned char *)planes[0].fd; + pYUVBuf[1] = (unsigned char *)planes[1].fd; + pYUVBuf[2] = (unsigned char *)planes[2].fd; + } +#endif + } +#endif +#ifdef USE_DMA_BUF + if ((exynosOutputPort->bIsPBEnabled == OMX_FALSE) && + (csc_method == CSC_METHOD_HW)) { + pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf); + pYUVBuf[1] = NULL; + pYUVBuf[2] = NULL; + } +#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 */ + omx_2_hal_pixel_format(colorFormat), /* 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 */ + omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* 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 */ + cscRet = csc_convert(pVideoDec->csc_handle); + if (cscRet != CSC_ErrorNone) + ret = OMX_FALSE; + else + ret = OMX_TRUE; + +#ifdef USE_PB + if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) { +#ifdef SLP_PLATFORM + Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData, exynosOutputPort, exynosInputPort); +#else + Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData); +#endif + } +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + + FunctionIn(); + + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || + (srcInputData->pPrivate == NULL)) { + ret = OMX_FALSE; + goto EXIT; + } + } + + if (inputUseBuffer->dataValid == OMX_TRUE) { + if (exynosInputPort->bufferProcessType & BUFFER_SHARE) { + Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE); + +#ifndef SLP_PLATFORM + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { + OMX_PTR dataBuffer = NULL; + + dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, + srcInputData->buffer.singlePlaneBuffer.dataBuffer); + if (dataBuffer == NULL) { + ret = OMX_FALSE; + goto EXIT; + } + + srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer; + } +#endif + /* reset dataBuffer */ + Exynos_ResetDataBuffer(inputUseBuffer); + } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + pExynosComponent->bUseFlagEOF = OMX_TRUE; + + copySize = checkInputStreamLen; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE"); + + if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) { + if (copySize > 0) { + Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen, + checkInputStream, copySize); + } + + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + srcInputData->dataLen += copySize; + srcInputData->remainDataLen += copySize; + + srcInputData->timeStamp = inputUseBuffer->timeStamp; + srcInputData->nFlags = inputUseBuffer->nFlags; + srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ret = OMX_FALSE; + } + + Exynos_InputBufferReturn(pOMXComponent); + } + + if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE"); + srcInputData->dataLen = 0; + srcInputData->remainDataLen = 0; + pExynosComponent->bSaveFlagEOS = OMX_TRUE; + } + + if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp; + pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", + srcInputData->timeStamp, srcInputData->timeStamp / 1E6); + } + + ret = OMX_TRUE; + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_U32 copySize = 0; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + + FunctionIn(); + + if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) { + if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone) + outputUseBuffer->dataValid = OMX_TRUE; + } else { +#ifdef USE_PB +#ifdef SLP_PLATFORM + if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort,exynosInputPort) == OMX_ErrorNone) { +#else + if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) { +#endif + outputUseBuffer->dataValid = OMX_TRUE; + } else { + ret = OMX_FALSE; + goto EXIT; + } +#else + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s Should not come here", __FUNCTION__); + ret = OMX_FALSE; + goto EXIT; +#endif + } + } + + if (outputUseBuffer->dataValid == OMX_TRUE) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)", + dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6); + if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) && + ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) && + (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){ + pExynosComponent->checkTimeStamp.startTimeStamp = -19761123; + pExynosComponent->checkTimeStamp.nStartFlags = 0x0; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent); + if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) + Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader); + ret = OMX_TRUE; + goto EXIT; + } + } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) { + ret = OMX_TRUE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking"); + goto EXIT; + } + + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_U32 width = 0, height = 0; + int imageSize = 0; + void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo; + + width = pBufferInfo->imageWidth; + height = pBufferInfo->imageHeight; + imageSize = width * height; + + if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + copySize = dstOutputData->remainDataLen; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize); + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = dstOutputData->nFlags; + outputUseBuffer->timeStamp = dstOutputData->timeStamp; + + if (outputUseBuffer->remainDataLen > 0) { + ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData); + } else { + ret = OMX_TRUE; + } + + if (ret == OMX_TRUE) { + if ((outputUseBuffer->remainDataLen > 0) || + ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || + (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + Exynos_OutputBufferReturn(pOMXComponent); + } + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ret = OMX_FALSE; + } + } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) { + outputUseBuffer->dataLen = 0; + outputUseBuffer->remainDataLen = 0; + outputUseBuffer->nFlags = dstOutputData->nFlags; + outputUseBuffer->timeStamp = dstOutputData->timeStamp; + Exynos_OutputBufferReturn(pOMXComponent); + } else { +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is SCMN_IMGB type."); + copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen; + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = 0; /* need to check */ + outputUseBuffer->timeStamp = dstOutputData->timeStamp; + + if (outputUseBuffer->remainDataLen > 0) { + ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData); + } else { + ret = OMX_TRUE; + } + + dstOutputData->remainDataLen -= copySize; /* need to check */ + dstOutputData->usedDataLen += copySize; + + Exynos_OutputBufferReturn(pOMXComponent); +#else + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ret = OMX_FALSE; +#endif + } + } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((outputUseBuffer->remainDataLen > 0) || + ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || + (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) + Exynos_OutputBufferReturn(pOMXComponent); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; + OMX_BOOL bCheckInputData = OMX_FALSE; + OMX_BOOL bValidCodecData = OMX_FALSE; + OMX_BOOL bCodecConfigured = OMX_FALSE; + + FunctionIn(); + + while (!pVideoDec->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) && + (!pVideoDec->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) || + ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet))) + break; + if (exynosInputPort->portState != OMX_StateIdle) + break; + + Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex); + if (ret != OMX_ErrorInputDataDecodeYet) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + + if ((pVideoDec->exynos_process_codecConfigData) && !bCodecConfigured) { + EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL; + ret = Exynos_InputBufferGetQueue(pExynosComponent); + + inputUseBuffer = &(exynosInputPort->way.port2WayDataBuffer.inputDataBuffer); + pVideoDec->exynos_process_codecConfigData(pOMXComponent, inputUseBuffer); /* SLP_PLATFORM */ +// pVideoDec->exynos_process_codecConfigData(pOMXComponent, pSrcInputData); + + bCodecConfigured = OMX_TRUE; + } + + if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) { + Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer); + if (codecBuffer != NULL) { + Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData); + } + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + } + + if (srcInputUseBuffer->dataValid == OMX_TRUE) { + bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData); + } else { + bCheckInputData = OMX_FALSE; + } + + if ((bCheckInputData == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { + ret = Exynos_InputBufferGetQueue(pExynosComponent); + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + + if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) { + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + } + + ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData); + + if (ret == OMX_ErrorCorruptedFrame) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + codecBuffer = pSrcInputData->pPrivate; + if (codecBuffer != NULL) + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer); + } + + if (exynosInputPort->bufferProcessType & BUFFER_SHARE) { + Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader); + } + } + + if (ret != OMX_ErrorInputDataDecodeYet) { + Exynos_ResetCodecData(pSrcInputData); + } + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + if (ret == OMX_ErrorCodecInit) + pVideoDec->bExitBufferProcessThread = OMX_TRUE; + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer; + EXYNOS_OMX_DATA srcOutputData; + + FunctionIn(); + + while (!pVideoDec->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + + while (!pVideoDec->bExitBufferProcessThread) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE) + break; + } + Exynos_OSAL_SleepMillisec(0); + + if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) + break; + + Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex); + ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData); + + if (ret == OMX_ErrorNone) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + codecBuffer = srcOutputData.pPrivate; + if (codecBuffer != NULL) + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer); + } + if (exynosInputPort->bufferProcessType & BUFFER_SHARE) { + Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer); + Exynos_InputBufferReturn(pOMXComponent); + } + Exynos_ResetCodecData(&srcOutputData); + } + Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer; + EXYNOS_OMX_DATA dstInputData; + + FunctionIn(); + + while (!pVideoDec->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && + (!pVideoDec->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) || + (!CHECK_PORT_POPULATED(exynosOutputPort))) + break; + if (exynosOutputPort->portState != OMX_StateIdle) + break; + + Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex); + if (ret != OMX_ErrorOutputBufferUseYet) { + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData); + } + + if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((dstInputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + ret = Exynos_OutputBufferGetQueue(pExynosComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) { + Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE); + } else { +#ifdef USE_PB + ret = Exynos_Shared_PlatformBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE); +#endif + if (ret != OMX_ErrorNone) { + dstInputUseBuffer->dataValid = OMX_FALSE; + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + } + Exynos_ResetDataBuffer(dstInputUseBuffer); + } + } + + if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + } + + ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData); + if (ret != OMX_ErrorOutputBufferUseYet) { + Exynos_ResetCodecData(&dstInputData); + } + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData; + + FunctionIn(); + + while (!pVideoDec->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && + (!pVideoDec->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) + break; + + Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex); + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((dstOutputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + ret = Exynos_OutputBufferGetQueue(pExynosComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); + break; + } + } + } + + if ((dstOutputUseBuffer->dataValid == OMX_TRUE) || + (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) + ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData); + + if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) || + (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) { + Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData); + } + + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + codecBuffer = pDstOutputData->pPrivate; + if (codecBuffer != NULL) { + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer); + pDstOutputData->pPrivate = NULL; + } + } + + /* reset outputData */ + Exynos_ResetCodecData(pDstOutputData); + Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_SrcInputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_SrcOutputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_DstInputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_DstOutputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + FunctionIn(); + + pVideoDec->bExitBufferProcessThread = OMX_FALSE; + + ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread, + Exynos_OMX_DstOutputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread, + Exynos_OMX_SrcOutputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread, + Exynos_OMX_DstInputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread, + Exynos_OMX_SrcInputProcessThread, + pOMXComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + OMX_S32 countValue = 0; + unsigned int i = 0; + + FunctionIn(); + + pVideoDec->bExitBufferProcessThread = OMX_TRUE; + + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID); + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread); + pVideoDec->hSrcInputThread = NULL; + + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID); + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread); + pVideoDec->hDstInputThread = NULL; + + pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX); + pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread); + pVideoDec->hSrcOutputThread = NULL; + + pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX); + pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread); + pVideoDec->hDstOutputThread = NULL; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT)); + if (pVideoDec == NULL) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT)); + pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec; + + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->bMultiThreadProcess = OMX_TRUE; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = 0; + pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pExynosPort->portDefinition.format.video.nFrameWidth = 0; + pExynosPort->portDefinition.format.video.nFrameHeight= 0; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.format.video.pNativeWindow = NULL; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pExynosPort->portDefinition.format.video.nFrameWidth = 0; + pExynosPort->portDefinition.format.video.nFrameHeight= 0; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.format.video.pNativeWindow = NULL; + + pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO)); + + pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest; + + pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer; + pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer; + pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create; + pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; + pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_Free(pVideoDec); + pExynosComponent->hComponentHandle = pVideoDec = NULL; + + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + if (pExynosPort->processData.extInfo != NULL) { + Exynos_OSAL_Free(pExynosPort->processData.extInfo); + pExynosPort->processData.extInfo = NULL; + } + + for(i = 0; i < ALL_PORT_NUM; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType); + pExynosPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = Exynos_OMX_Port_Destructor(pOMXComponent); + + ret = Exynos_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.h b/openmax/component/video/dec/Exynos_OMX_Vdec.h new file mode 100755 index 0000000..851c5b9 --- /dev/null +++ b/openmax/component/video/dec/Exynos_OMX_Vdec.h @@ -0,0 +1,175 @@ +/* + * + * 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 Exynos_OMX_Vdec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_VIDEO_DECODE +#define EXYNOS_OMX_VIDEO_DECODE + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_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 3 + /*For memory Optimization */ +#define DEFAULT_MFC_INPUT_BUFFER_SIZE 1024*1024*2 +//#define DEFAULT_MFC_INPUT_BUFFER_SIZE 1920 * 1080 * 3 / 2 + +#define MFC_OUTPUT_BUFFER_NUM_MAX 16 * 2 +#define DEFAULT_MFC_OUTPUT_YBUFFER_SIZE 1920 * 1080 +#define DEFAULT_MFC_OUTPUT_CBUFFER_SIZE 1920 * 1080 / 2 + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 4 + +#ifdef SLP_PLATFORM /* exrta dpb number */ +#define EXTRA_DPB_NUM 5 +#else +#define EXTRA_DPB_NUM 5 +#endif + +#define MFC_INPUT_BUFFER_PLANE 1 +#define MFC_OUTPUT_BUFFER_PLANE 2 + +/*MFC Buffer alignment macros*/ +#define S5P_FIMV_DEC_BUF_ALIGN (8 * 1024) +#define S5P_FIMV_ENC_BUF_ALIGN (8 * 1024) +#define S5P_FIMV_NV12M_HALIGN 16 +#define S5P_FIMV_NV12M_LVALIGN 16 +#define S5P_FIMV_NV12M_CVALIGN 8 +#define S5P_FIMV_NV12MT_HALIGN 16 /* This value is changed on e3250, 128 to 16 */ +#define S5P_FIMV_NV12MT_VALIGN 16 /* This value is changed on e3250, 64 to 16 */ +#define S5P_FIMV_NV12M_SALIGN 2048 +#define S5P_FIMV_NV12MT_SALIGN 8192 + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} CODEC_DEC_ADDR_INFO; + +typedef struct _CODEC_DEC_BUFFER +{ + void *pVirAddr[MAX_BUFFER_PLANE]; /* virtual address */ + int bufferSize[MAX_BUFFER_PLANE]; /* buffer alloc size */ + int fd[MAX_BUFFER_PLANE]; /* buffer FD */ + int dataSize; /* total data length */ +} CODEC_DEC_BUFFER; + +typedef struct _DECODE_CODEC_EXTRA_BUFFERINFO +{ + /* For Decode Output */ + OMX_U32 imageWidth; + OMX_U32 imageHeight; + OMX_COLOR_FORMATTYPE ColorFormat; +} DECODE_CODEC_EXTRA_BUFFERINFO; + +typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + OMX_BOOL bThumbnailMode; + OMX_BOOL bFirstFrame; + CODEC_DEC_BUFFER *pMFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + CODEC_DEC_BUFFER *pMFCDecOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX]; + + /* Buffer Process */ + OMX_BOOL bExitBufferProcessThread; + OMX_HANDLETYPE hSrcInputThread; + OMX_HANDLETYPE hSrcOutputThread; + OMX_HANDLETYPE hDstInputThread; + OMX_HANDLETYPE hDstOutputThread; + + /* Shared Memory Handle */ + OMX_HANDLETYPE hSharedMemory; + + /* For DRM Play */ + OMX_BOOL bDRMPlayerMode; + + /* For Resolution Change */ + OMX_BOOL bDRCProcessing; + OMX_U32 nDRCSavedBufferCount; + + /* CSC handle */ + OMX_PTR csc_handle; + OMX_U32 csc_set_format; + +#ifdef SLP_PLATFORM + OMX_BOOL bNeedTimestampReorder; +#endif + + OMX_ERRORTYPE (*exynos_codec_srcInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); + OMX_ERRORTYPE (*exynos_codec_srcOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); + OMX_ERRORTYPE (*exynos_codec_dstInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData); + OMX_ERRORTYPE (*exynos_codec_dstOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData); + + OMX_ERRORTYPE (*exynos_codec_start)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_stop)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_bufferProcessRun)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_enqueueAllBuffer)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_resetupAllElement)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + + int (*exynos_checkInputFrame) (OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, + OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); + OMX_ERRORTYPE (*exynos_codec_getCodecInputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr, OMX_U32 *size); + OMX_ERRORTYPE (*exynos_codec_getCodecOutputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]); + OMX_ERRORTYPE (*exynos_process_codecConfigData)(OMX_COMPONENTTYPE *pOMXComponent, void *pConfig); +} EXYNOS_OMX_VIDEODEC_COMPONENT; + +#ifdef __cplusplus +extern "C" { +#endif + +int calc_plane(int width, int height); +int calc_yplane(int width, int height); +int calc_uvplane(int width, int height); +inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); +OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData); +OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData); + +OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.c b/openmax/component/video/dec/Exynos_OMX_VdecControl.c new file mode 100644 index 0000000..c1f81a2 --- /dev/null +++ b/openmax/component/video/dec/Exynos_OMX_VdecControl.c @@ -0,0 +1,1584 @@ +/* + * + * 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 Exynos_OMX_VdecControl.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OMX_VdecControl.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_SharedMemory.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +#include "ExynosVideoApi.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DECCONTROL" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + if (nPortIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pExynosPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; + pExynosPort->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; +#ifdef SLP_PLATFORM + if (nPortIndex == OUTPUT_PORT_INDEX) { + SCMN_IMGB * pSlpOutBuf = (SCMN_IMGB *)pBuffer; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd[0] =%d, fd[1] =%d, vaddr[0] =%p, vaddr[1] = %p", + pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->a[0], pSlpOutBuf->a[1]); + + pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->fd[0]; + pExynosPort->extendBufferHeader[i].buf_fd[1] = pSlpOutBuf->fd[1]; + pExynosPort->extendBufferHeader[i].buf_fd[2] = 0; + + pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->a[0]; + pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->a[1]; + pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PlatformBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ", + i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], pExynosPort->extendBufferHeader[i].pYUVBuf[1]); + } else if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { + pExynosPort->extendBufferHeader[i].buf_fd[0] = pBuffer; + } +#endif + *ppBufferHdr = temp_bufferHeader; + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + int temp_buffer_fd = -1; + OMX_U32 i = 0; + MEMORY_TYPE mem_type; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + if (nPortIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pExynosPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { + mem_type = SECURE_MEMORY; + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + mem_type = NORMAL_MEMORY; + } else { + mem_type = SYSTEM_MEMORY; + } + temp_buffer = Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nSizeBytes, mem_type); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + temp_buffer_fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, temp_buffer); + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; + pExynosPort->extendBufferHeader[i].buf_fd[0] = temp_buffer_fd; + pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + if (mem_type == SECURE_MEMORY) + temp_bufferHeader->pBuffer = temp_buffer_fd; + else + 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; + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(temp_bufferHeader); + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer); + + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pExynosPort->portState != OMX_StateLoaded) && (pExynosPort->portState != OMX_StateInvalid)) { + (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent, + pExynosComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) { + if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) { + if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) { + if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { + OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, (int)pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, mapBuffer); + } else { + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); + } + pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pExynosPort->assignedBufferNum--; + if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader); + pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL; + pBufferHdr = NULL; + } + pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pExynosPort->assignedBufferNum == 0) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set"); + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + pExynosPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = 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 Exynos_OMX_FreeTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT* pExynosPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_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_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pDataBuffer[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + *pDataBuffer = NULL; + + if (pExynosPort->portWayType == WAY1_PORT) { + *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer; + } else if (pExynosPort->portWayType == WAY2_PORT) { + pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + EXYNOS_OMX_DATABUFFER *pDataPortBuffer[2] = {NULL, NULL}; + EXYNOS_OMX_MESSAGE *message = NULL; + OMX_U32 flushNum = 0; + OMX_S32 semValue = 0; + int i = 0, maxBufferNum = 0; + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "flushPort idx:%d", portIndex); +#endif + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &semValue); + if (semValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[portIndex].bufferSemID); + + Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID); + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if ((message != NULL) && (message->messageType != EXYNOS_OMX_CommandFakeBuffer)) { + bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; + bufferHeader->nFilledLen = 0; + + if (portIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader); + } else if (portIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader); + } + } + Exynos_OSAL_Free(message); + message = NULL; + } + + Exynos_OMX_GetFlushBuffer(pExynosPort, pDataPortBuffer); + if (portIndex == INPUT_PORT_INDEX) { + if (pDataPortBuffer[0]->dataValid == OMX_TRUE) + Exynos_FlushInputBufferReturn(pOMXComponent, pDataPortBuffer[0]); + if (pDataPortBuffer[1]->dataValid == OMX_TRUE) + Exynos_FlushInputBufferReturn(pOMXComponent, pDataPortBuffer[1]); + } else if (portIndex == OUTPUT_PORT_INDEX) { + if (pDataPortBuffer[0]->dataValid == OMX_TRUE) + Exynos_FlushOutputBufferReturn(pOMXComponent, pDataPortBuffer[0]); + if (pDataPortBuffer[1]->dataValid == OMX_TRUE) + Exynos_FlushOutputBufferReturn(pOMXComponent, pDataPortBuffer[1]); + } + + if (pExynosComponent->bMultiThreadProcess == OMX_TRUE) { + if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + if (pExynosPort->processData.bufferHeader != NULL) { + if (portIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader); + } else if (portIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader); + } + } + Exynos_ResetCodecData(&pExynosPort->processData); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) + maxBufferNum = pVideoDec->nDRCSavedBufferCount; + else + maxBufferNum = pExynosPort->portDefinition.nBufferCountActual; + + for (i = 0; i < maxBufferNum; i++) { + if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) { + if (portIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader); + } else if (portIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader); + } + } + } + } + } else { + Exynos_ResetCodecData(&pExynosPort->processData); + } + + while(1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt); + if (cnt <= 0) + break; + Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID); + } + Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL}; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlush idx:%d", nPortIndex); +#endif + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex); + + pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE; + + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + } else { + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[nPortIndex].pauseEvent); + } + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + Exynos_OMX_GetFlushBuffer(pExynosPort, flushPortBuffer); + + if (pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) + Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + + pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex); + Exynos_OSAL_MutexLock(flushPortBuffer[0]->bufferMutex); + pVideoDec->exynos_codec_stop(pOMXComponent, nPortIndex); + Exynos_OSAL_MutexLock(flushPortBuffer[1]->bufferMutex); + ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + /* pVideoDec->bDRCProcess == OMX_TRUE + the case of dynamic resolution change */ + pVideoDec->exynos_codec_resetupAllElement(pOMXComponent, nPortIndex); + } else if (pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) { + pVideoDec->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex); + } + + Exynos_ResetCodecData(&pExynosPort->processData); + + if (ret == OMX_ErrorNone) { + if (nPortIndex == INPUT_PORT_INDEX) { + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE; + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->reInputData = OMX_FALSE; + } + + pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex); + if (bEvent == OMX_TRUE) + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandFlush, nPortIndex, NULL); + } + Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex); + Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex); + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dataBuffer = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + + FunctionIn(); + + if (exynosOMXInputPort->bufferProcessType & BUFFER_COPY) { + dataBuffer = &(exynosOMXInputPort->way.port2WayDataBuffer.inputDataBuffer); + } else if (exynosOMXInputPort->bufferProcessType & BUFFER_SHARE) { + dataBuffer = &(exynosOMXInputPort->way.port2WayDataBuffer.outputDataBuffer); + } + + bufferHeader = dataBuffer->bufferHeader; + + if (bufferHeader != NULL) { + if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = exynosOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = exynosOMXInputPort->markType.pMarkData; + exynosOMXInputPort->markType.hMarkTargetComponent = NULL; + exynosOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + bufferHeader->nFilledLen = 0; + bufferHeader->nOffset = 0; + Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(dataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_FlushInputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + + FunctionIn(); + + bufferHeader = dataBuffer->bufferHeader; + + if (bufferHeader != NULL) { + if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = exynosOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = exynosOMXInputPort->markType.pMarkData; + exynosOMXInputPort->markType.hMarkTargetComponent = NULL; + exynosOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + bufferHeader->nFilledLen = 0; + bufferHeader->nOffset = 0; + Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(dataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorUndefined; + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_MESSAGE *message = NULL; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL; + + FunctionIn(); + + inputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + if (inputUseBuffer->dataValid != OMX_TRUE) { + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(message); + ret = OMX_ErrorCodecFlush; + goto EXIT; + } + + inputUseBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + inputUseBuffer->allocSize = inputUseBuffer->bufferHeader->nAllocLen; + inputUseBuffer->dataLen = inputUseBuffer->bufferHeader->nFilledLen; + inputUseBuffer->remainDataLen = inputUseBuffer->dataLen; + inputUseBuffer->usedDataLen = 0; + inputUseBuffer->dataValid = OMX_TRUE; + inputUseBuffer->nFlags = inputUseBuffer->bufferHeader->nFlags; + inputUseBuffer->timeStamp = inputUseBuffer->bufferHeader->nTimeStamp; + + Exynos_OSAL_Free(message); + +#ifndef SLP_PLATFORM + if (inputUseBuffer->allocSize <= inputUseBuffer->dataLen) + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", inputUseBuffer->allocSize, inputUseBuffer->dataLen); +#endif + } + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dataBuffer = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + + FunctionIn(); + + dataBuffer = &(exynosOMXOutputPort->way.port2WayDataBuffer.outputDataBuffer); + bufferHeader = dataBuffer->bufferHeader; + + if (bufferHeader != NULL) { +#ifdef SLP_PLATFORM + bufferHeader->nFilledLen = sizeof(SCMN_IMGB); +#else + bufferHeader->nFilledLen = dataBuffer->remainDataLen; +#endif + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"Exynos_OutputBufferReturn: nFilledLen: %d", bufferHeader->nFilledLen); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"Exynos_OutputBufferReturn: nFlags: %d", bufferHeader->nFlags); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"Exynos_OutputBufferReturn: nTimeStamp: %lld", bufferHeader->nTimeStamp); + + if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData; + pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL; + pExynosComponent->propagateMarkType.pMarkData = NULL; + } + + if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + bufferHeader->nFilledLen = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d bufferHeader is NULL! ", __FUNCTION__, __LINE__); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(dataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + + FunctionIn(); + + bufferHeader = dataBuffer->bufferHeader; + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData; + pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL; + pExynosComponent->propagateMarkType.pMarkData = NULL; + } + + if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + bufferHeader->nFilledLen = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!"); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(dataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorUndefined; + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_MESSAGE *message = NULL; + EXYNOS_OMX_DATABUFFER *outputUseBuffer = NULL; + + FunctionIn(); + + if (pExynosPort->bufferProcessType & BUFFER_COPY) { + outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + } + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){ + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + if (outputUseBuffer->dataValid != OMX_TRUE) { + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(message); + ret = OMX_ErrorCodecFlush; + goto EXIT; + } + + outputUseBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + outputUseBuffer->allocSize = outputUseBuffer->bufferHeader->nAllocLen; + outputUseBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + outputUseBuffer->remainDataLen = outputUseBuffer->dataLen; + outputUseBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + outputUseBuffer->dataValid = OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ +/* + if (pExynosPort->bufferProcessType & BUFFER_SHARE) + outputUseBuffer->pPrivate = outputUseBuffer->bufferHeader->pOutputPortPrivate; + else if (pExynosPort->bufferProcessType & BUFFER_COPY) { + pExynosPort->processData.dataBuffer = outputUseBuffer->bufferHeader->pBuffer; + pExynosPort->processData.allocSize = outputUseBuffer->bufferHeader->nAllocLen; + } +*/ + + Exynos_OSAL_Free(message); + } + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_BUFFERHEADERTYPE *retBuffer = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (pExynosComponent->currentState != OMX_StateExecuting) { + retBuffer = NULL; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){ + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + + message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (message == NULL) { + retBuffer = NULL; + goto EXIT; + } + if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(message); + retBuffer = NULL; + goto EXIT; + } + + retBuffer = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + Exynos_OSAL_Free(message); + } + +EXIT: + FunctionOut(); + + return retBuffer; +} + +OMX_ERRORTYPE Exynos_CodecBufferEnQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR data) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + pExynosPort= &pExynosComponent->pExynosPort[PortIndex]; + + if (data == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + +#ifdef SLP_PLATFORM + if (pExynosPort == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d: pExynosPort is NULL", __FUNCTION__, __LINE__); + } +#endif + + ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)data); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_CodecBufferDeQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR *data) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_U32 tempData; + + FunctionIn(); + + pExynosPort = &pExynosComponent->pExynosPort[PortIndex]; + Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID); + tempData = (OMX_U32)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ); + if (tempData == NULL) { + *data = NULL; + ret = OMX_ErrorUndefined; + goto EXIT; + } + *data = (OMX_PTR)tempData; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + pExynosPort= &pExynosComponent->pExynosPort[PortIndex]; + + ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + while (1) { + int cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt); + if (cnt > 0) + Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID); + else + break; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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 = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pExynosComponent->portParam.nPorts; + portParam->nStartPortNumber = pExynosComponent->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; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pExynosComponent->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; + } + + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + portDefinition = &pExynosPort->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) { + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + portDefinition = &pExynosPort->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_FormatNV12Tiled; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; +#ifdef SLP_PLATFORM + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; +#endif + default: + if (index > supportFormat_0) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + break; + } + } + ret = OMX_ErrorNone; + } + break; +#ifdef USE_PB + case OMX_IndexParamGetAndroidNativeBuffer: + { + ret = Exynos_OSAL_GetPBParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; +#endif + default: + { + ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->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; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + portDefinition = &pExynosPort->portDefinition; + + portDefinition->format.video.eColorFormat = portFormat->eColorFormat; + portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; + portDefinition->format.video.xFramerate = portFormat->xFramerate; + } + } + break; +#ifdef USE_PB +#ifdef SLP_PLATFORM + case OMX_IndexParamEnablePlatformSpecificBuffers: +#else + case OMX_IndexParamEnableAndroidBuffers: +#endif + case OMX_IndexParamUseAndroidNativeBuffer: + { + ret = Exynos_OSAL_SetPBParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; +#endif + +#ifdef SLP_PLATFORM + case OMX_IndexParamEnableTimestampReorder: + { + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->bNeedTimestampReorder = OMX_TRUE; + } + break; +#endif + default: + { + ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexVendorThumbnailMode: + { + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure); + + ret = OMX_ErrorNone; + } + break; + default: + ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + +#ifdef USE_PB +#ifdef SLP_PLATFORM + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnablePlatformSpecificBuffers; + else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_TS_REORDER) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableTimestampReorder; +#else + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableAndroidBuffers; +#endif + else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer; + else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_USE_ANB) == 0) + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer; + else + ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); +#else + ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +#ifdef USE_PB /* this is from FillThisBuffer */ +OMX_ERRORTYPE Exynos_Shared_PlatformBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_PLANE nPlane) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_U32 width, height; +// void *pPhys[MAX_BUFFER_PLANE]; + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + + FunctionIn(); + + memset(planes, 0, sizeof(planes)); + + if (pExynosPort->bIsPBEnabled == OMX_TRUE) { + OMX_U32 stride; + + width = pExynosPort->portDefinition.format.video.nFrameWidth; + height = pExynosPort->portDefinition.format.video.nFrameHeight; + if ((pUseBuffer->bufferHeader != NULL) && (pUseBuffer->bufferHeader->pBuffer != NULL)) { + Exynos_OSAL_LockPB(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes); + pUseBuffer->dataLen = sizeof(void *); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (nPlane == TWO_PLANE) { + /* Case of Shared Buffer, Only support two PlaneBuffer */ + pData->buffer.multiPlaneBuffer.dataBuffer[0] = planes[0].addr; + pData->buffer.multiPlaneBuffer.dataBuffer[1] = planes[1].addr; +#ifdef USE_DMA_BUF + pData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd; + pData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd; +#endif + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane"); + ret = OMX_ErrorNotImplemented; + goto EXIT; + } + + pData->allocSize = pUseBuffer->allocSize; + pData->dataLen = pUseBuffer->dataLen; + pData->usedDataLen = pUseBuffer->usedDataLen; + pData->remainDataLen = pUseBuffer->remainDataLen; + pData->timeStamp = pUseBuffer->timeStamp; + pData->nFlags = pUseBuffer->nFlags; + pData->pPrivate = pUseBuffer->pPrivate; + pData->bufferHeader = pUseBuffer->bufferHeader; + +EXIT: + FunctionOut(); + return ret; +} + +/* this is for Fill This Buffer Done */ +#ifdef SLP_PLATFORM +OMX_ERRORTYPE Exynos_Shared_DataToPlatformBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_BASEPORT *pExynosInPort) +#else +OMX_ERRORTYPE Exynos_Shared_DataToPlatformBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort) +#endif +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + pUseBuffer->bufferHeader = pData->bufferHeader; + pUseBuffer->allocSize = pData->allocSize; +#ifdef SLP_PLATFORM + pUseBuffer->dataLen = sizeof(SCMN_IMGB); +#else + pUseBuffer->dataLen = pData->dataLen; +#endif + pUseBuffer->usedDataLen = pData->usedDataLen; + pUseBuffer->remainDataLen = pData->remainDataLen; + pUseBuffer->timeStamp = pData->timeStamp; + pUseBuffer->nFlags = pData->nFlags; + pUseBuffer->pPrivate = pData->pPrivate; + + if ((pUseBuffer->bufferHeader == NULL) || + (pUseBuffer->bufferHeader->pBuffer == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "pUseBuffer->bufferHeader or pUseBuffer->bufferHeader->pBuffer is NULL"); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + if (pExynosPort->bIsPBEnabled == OMX_TRUE) { +#ifdef SLP_PLATFORM + Exynos_OSAL_UnlockPB(pUseBuffer->bufferHeader->pBuffer, pData, pExynosPort,pExynosInPort); +#else + Exynos_OSAL_UnlockPB(pUseBuffer->bufferHeader->pBuffer, pData); +#endif + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} +#endif diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.h b/openmax/component/video/dec/Exynos_OMX_VdecControl.h new file mode 100644 index 0000000..d7428a5 --- /dev/null +++ b/openmax/component/video/dec/Exynos_OMX_VdecControl.h @@ -0,0 +1,110 @@ +/* + * + * 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 Exynos_OMX_VdecControl.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_VIDEO_DECODECONTROL +#define EXYNOS_OMX_VIDEO_DECODECONTROL + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Basecomponent.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_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 Exynos_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 Exynos_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_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 Exynos_OMX_VideoDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent); +OMX_ERRORTYPE Exynos_FlushInputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer); +OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer); + +#ifdef USE_PB +OMX_ERRORTYPE Exynos_Shared_PlatformBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_PLANE nPlane); +#ifdef SLP_PLATFORM +OMX_ERRORTYPE Exynos_Shared_DataToPlatformBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort,EXYNOS_OMX_BASEPORT *pExynosInPort); +#else +OMX_ERRORTYPE Exynos_Shared_DataToPlatformBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openmax/component/video/dec/Makefile.am b/openmax/component/video/dec/Makefile.am new file mode 100644 index 0000000..5b04d89 --- /dev/null +++ b/openmax/component/video/dec/Makefile.am @@ -0,0 +1,28 @@ +SUBDIRS = . h264 mpeg4 mpeg2 vc1 + +lib_LTLIBRARIES = libExynosOMX_Vdec.la + +libExynosOMX_Vdec_la_SOURCES = Exynos_OMX_Vdec.c \ + Exynos_OMX_Vdec.h \ + Exynos_OMX_VdecControl.c \ + Exynos_OMX_VdecControl.h + +libExynosOMX_Vdec_la_LIBADD = $(X11_LIBS) $(DRI2_LIBS) $(DRM_SLP_LIBS) $(XFIXES_LIBS)\ + $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos/libcsc/libcsc.la + +libExynosOMX_Vdec_la_CFLAGS = $(X11_CFLAGS) $(DRI2_CFLAGS) $(DRM_SLP_CFLAGS) $(XFIXES_CFLAGS) \ + -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/exynos/libcsc + +if BOARD_USE_DMA_BUF +libExynosOMX_Vdec_la_CFLAGS += -DUSE_ANB +endif diff --git a/openmax/component/video/dec/h264/Android.mk b/openmax/component/video/dec/h264/Android.mk new file mode 100644 index 0000000..f916974 --- /dev/null +++ b/openmax/component/video/dec/h264/Android.mk @@ -0,0 +1,52 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_H264dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.AVC.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +ifeq ($(BOARD_USE_S3D_SUPPORT), true) +LOCAL_CFLAGS += -DUSE_S3D_SUPPORT +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c new file mode 100755 index 0000000..54bf2f0 --- /dev/null +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -0,0 +1,2847 @@ +/* + * + * 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 Exynos_OMX_H264dec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_H264dec.h" +#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +#include + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_H264_DEC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +#define H264_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define ADD_SPS_PPS_I_FRAME +//#define FULL_FRAME_SEARCH + +/* H.264 Decoder Supported Levels & profiles */ +EXYNOS_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_AVCProfileBaseline, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42}, + + {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_AVCProfileMain, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42}, + + {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_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}}; + +static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (addr != NULL) { + addr[0] = pCodecBuffer->planes[0].addr; + addr[1] = pCodecBuffer->planes[1].addr; + addr[2] = pCodecBuffer->planes[2].addr; + } + + if (size != NULL) { + size[0] = pCodecBuffer->planes[0].allocSize; + size[1] = pCodecBuffer->planes[1].allocSize; + size[2] = pCodecBuffer->planes[2].allocSize; + } + +EXIT: + return ret; +} + +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; + + Exynos_OSAL_Log(EXYNOS_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; +} + +static OMX_BOOL Check_H264_StartCode( + OMX_U8 *pInputStream, + OMX_U32 streamSize) +{ + if (streamSize < 4) { + return OMX_FALSE; + } + + if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x00) && + (pInputStream[3] != 0x00) && + ((pInputStream[3] >> 3) == 0x00)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[4] & 0x1F), pInputStream[3], pInputStream[4], pInputStream[5]); + return OMX_TRUE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] != 0x00) && + ((pInputStream[2] >> 3) == 0x00)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[3] & 0x1F), pInputStream[2], pInputStream[3], pInputStream[4]); + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264DEC_HANDLE *pH264Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pH264Dec == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps)); + pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + + if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pH264Dec->hMFCH264Handle.pDecOps = pDecOps; + pH264Dec->hMFCH264Handle.pInbufOps = pInbufOps; + pH264Dec->hMFCH264Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pDecOps->nSize = sizeof(ExynosVideoDecOps); + pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + + Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for decoder ops */ + if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || + (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || +#ifdef USE_S3D_SUPPORT + (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) || +#endif + (pDecOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* alloc context, open, querycap */ + if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) { +#ifdef USE_DMA_BUF + pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); +#else + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s :%d V4L2_MEMORY_USERPTR", __FUNCTION__, __LINE__); + pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_USERPTR); +#endif + } else { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s :%d V4L2_MEMORY_DMABUF", __FUNCTION__, __LINE__); + pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); + } + if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + +#ifdef USE_S3D_SUPPORT + /*S3D: Enable SEI parsing to check Frame Packing */ + if (pDecOps->Enable_SEIParsing(pH264Dec->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Enable SEI Parsing"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pH264Dec->hMFCH264Handle.pDecOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pH264Dec->hMFCH264Handle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pH264Dec->hMFCH264Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecClose(EXYNOS_H264DEC_HANDLE *pH264Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pH264Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pDecOps->Finalize(hMFCHandle); + pH264Dec->hMFCH264Handle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pH264Dec->hMFCH264Handle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pH264Dec->hMFCH264Handle.pInbufOps = NULL; + } + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pH264Dec->hMFCH264Handle.pDecOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pH264Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pH264Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, plane; + + + if (pVideoDec->bThumbnailMode == OMX_TRUE) + pDecOps->Set_DisplayDelay(hMFCHandle, 0); + + /* input buffer info */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + bufferConf.eCompressionFormat = VIDEO_CODING_AVC; + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE + ||pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) + pInbufOps->Set_Shareable(hMFCHandle); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth + * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; + } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]; + plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0]; + plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE) { + ExynosVideoBuffer *pBuffer = NULL; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + /* get input buffer info */ + if (pInbufOps->Get_Buffer) { + if (pInbufOps->Get_Buffer(pH264Dec->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + +#ifdef SLP_PLATFORM + if (pExynosInputPort == NULL || pExynosOutputPort == NULL || pOMXComponent == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "invalid param: pExynosInputPort= %p pExynosOutputPort= %p pOMXComponent= %p", pExynosInputPort, pExynosOutputPort, pOMXComponent); + } +#endif + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /* Register input buffer */ + for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { + ExynosVideoPlane plane; + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { +#ifdef SLP_PLATFORM + /* IL Client assigns FD value in pBuffer */ + plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; +#else + plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); +#endif + } else { + plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + } + plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pH264Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pH264Dec->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pH264Dec->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pH264Dec->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]); + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pH264Dec->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); + nOutbufs += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "EXTRA_DPB_NUM = %d, nOutbufs =%d", EXTRA_DPB_NUM, nOutbufs); + for (i = 0; i < nOutbufs; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + +#ifdef USE_S3D_SUPPORT +OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent) +{ + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoFramePacking framePacking; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + OMX_BOOL ret = OMX_FALSE; + + /* Get Frame packing information*/ + if (pDecOps->Get_FramePackingInfo(pH264Dec->hMFCH264Handle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Get Frame Packing Information"); + ret = OMX_FALSE; + goto EXIT; + } + + if (framePacking.available) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement ID: 0x%08x", framePacking.arrangement_id); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement_type: %d", framePacking.arrangement_type); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "content_interpretation_type: %d", framePacking.content_interpretation_type); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "current_frame_is_frame0_flag: %d", framePacking.current_frame_is_frame0_flag); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "spatial_flipping_flag: %d", framePacking.spatial_flipping_flag); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", framePacking.frame0_grid_pos_x, + framePacking.frame0_grid_pos_y, framePacking.frame1_grid_pos_x, framePacking.frame1_grid_pos_y); + + pH264Dec->hMFCH264Handle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type; + /** Send Port Settings changed call back - output color format change */ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + + Exynos_OSAL_SleepMillisec(0); + ret = OMX_TRUE; + } + +EXIT: + return ret; +} +#endif + +OMX_ERRORTYPE H264CodecDstFreeCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + + int i, j; + + FunctionIn(); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + } + + Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]); + } + } + + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer)); + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE H264CodecDstAllocCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + + MEMORY_TYPE eMemoryType = NORMAL_MEMORY; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth, + pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth, + pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1); + + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) + eMemoryType = SECURE_MEMORY; + + for (i = 0; i < nOutbufs; i++) { + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType); + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pVideoDec->pMFCDecOutputBuffer[i]->fd[j] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j]; + } + } + + return OMX_ErrorNone; + +EXIT: + H264CodecDstFreeCodecBuffers(pOMXComponent); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecDstRegistCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + planes[j].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]; + planes[j].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[j]; + planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecResetupAllElement( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + int i, j, nOutbufs; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pH264Dec->bSourceStart == OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pH264Dec->bDestinationStart == OMX_TRUE)) { + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + + /**********************************/ + /* Codec Buffer Free & Unregister */ + /**********************************/ + H264CodecDstFreeCodecBuffers(pOMXComponent); + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + + pOutbufOps->Cleanup(hMFCHandle); + /******************************************************/ + /* V4L2 Destnation Setup for DPB Buffer Number Change */ + /******************************************************/ + H264CodecDstSetup(pOMXComponent); + + pVideoDec->bDRCProcessing = OMX_FALSE; + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + + /**********************************/ + /* Codec Buffer Unregister */ + /**********************************/ + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + pOutbufOps->Cleanup(hMFCHandle); + } + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE)) { + ret = H264CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + + /* set output geometry */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* input buffer enqueue for header parsing */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); + if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); +// ret = OMX_ErrorInsufficientResources; + ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; + goto EXIT; + } + + /* start header parsing */ + if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + ret = H264CodecCheckResolutionChange(pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + Exynos_OSAL_SleepMillisec(0); + ret = OMX_ErrorInputDataDecodeYet; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); +#endif + +EXIT: + H264CodecStop(pOMXComponent, INPUT_PORT_INDEX); + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + int i, nOutbufs; + + FunctionIn(); + + /* get dpb count */ + nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE + ||pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Set_Shareable(hMFCHandle); + + if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int plane; + + nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth, + pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth, + pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1); + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + H264CodecDstAllocCodecBuffers(pOMXComponent, nOutbufs); + H264CodecDstRegistCodecBuffers(pOMXComponent, nOutbufs); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE) { + + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + int plane; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + if (pOutbufOps->Get_Buffer) { + if (pOutbufOps->Get_Buffer(pH264Dec->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { +#ifdef USE_PB + if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) { + for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; + planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].allocSize = nAllocLen[plane]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } +#else + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + /* Waiting for DPB buffer setup to be completed, + * valid only for share mode + */ + if (pDecOps->Enable_DecodeWait != NULL) + pDecOps->Enable_DecodeWait(hMFCHandle); + + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX); + } + pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + int i; + + FunctionIn(); + + /* get geometry for output */ + Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* get dpb count */ + pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "H264CodecCheckResolutionChange H264CodecSetup nOutbufs: %d", pH264Dec->hMFCH264Handle.maxDPBNum); + + pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE; + + pExynosOutputPort->cropRectangle.nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop; + pExynosOutputPort->cropRectangle.nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft; + pExynosOutputPort->cropRectangle.nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth; + pExynosOutputPort->cropRectangle.nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVideoDec->bDRCProcessing) || + (pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) || + (pExynosOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } +#ifdef SLP_PLATFORM + pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum; + pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum; +#else + pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum - 4; + pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum - 4; +#endif + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } + + if (((pVideoDec->bDRCProcessing) && (pExynosOutputPort->bufferProcessType & BUFFER_COPY)) || + (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) || + (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) { + /* Check Crop */ + pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + Exynos_UpdateFrameSize(pOMXComponent); + + /** Send crop info call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + OMX_IndexConfigCommonOutputCrop, + NULL); + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = Exynos_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(EXYNOS_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; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE)) { + pExynosComponent->pExynosPort[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; + EXYNOS_OMX_BASEPORT *pExynosPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition_backup; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize); + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup); + + realWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + realHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pExynosPort->portDefinition.format.video.nStride = width; + pExynosPort->portDefinition.format.video.nSliceHeight = height; + pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + pExynosOutputPort->portDefinition.format.video.nStride = width; + pExynosOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; +#ifdef SLP_PLATFORM /* NV12T fd */ + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + break; +#endif + case OMX_SEC_COLOR_FormatNV12Tiled: + pExynosOutputPort->portDefinition.nBufferSize = + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + pExynosOutputPort->portDefinition.nBufferSize = + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + ret = Exynos_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 = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigCommonOutputCrop: + { + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + OMX_CONFIG_RECTTYPE *pSrcRectType = NULL; + OMX_CONFIG_RECTTYPE *pDstRectType = NULL; + pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + + if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == 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; + } + + EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex]; + + pSrcRectType = &(pExynosPort->cropRectangle); + + pDstRectType->nTop = pSrcRectType->nTop; + pDstRectType->nLeft = pSrcRectType->nLeft; + pDstRectType->nHeight = pSrcRectType->nHeight; + pDstRectType->nWidth = pSrcRectType->nWidth; + } + break; +#ifdef USE_S3D_SUPPORT + case OMX_IndexVendorS3DMode: + { + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + OMX_U32 *pS3DMode = NULL; + pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + + pS3DMode = (OMX_U32 *)pComponentConfigStructure; + *pS3DMode = (OMX_U32) pH264Dec->hMFCH264Handle.S3DFPArgmtType; + } + break; +#endif + default: + ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + *pIndexType = OMX_IndexVendorThumbnailMode; + ret = OMX_ErrorNone; + } +#ifdef USE_S3D_SUPPORT + else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) { + *pIndexType = OMX_IndexVendorS3DMode; + ret = OMX_ErrorNone; + } +#endif + else { + ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_ComponentRoleEnum( + OMX_HANDLETYPE hComponent, + OMX_U8 *cRole, + OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i, plane; + + FunctionIn(); + + pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE; + pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + /* H.264 Codec Open */ + ret = H264CodecOpen(pH264Dec); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY); + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else { +#ifdef SLP_PLATFORM + if (pOMXComponent == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d: invalid parm: pOMXComponent = %p", __FUNCTION__, __LINE__, pOMXComponent); + } +#endif + ret = H264CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pH264Dec->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent); + pH264Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Dec->hMFCH264Handle.indexTimestamp = 0; + pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { + pVideoDec->csc_handle = csc_init(CSC_METHOD_HW); + csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2); + csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode); + } else { + pVideoDec->csc_handle = csc_init(csc_method); + } + + if (pVideoDec->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + + int i, plane; + + FunctionIn(); + + if (pVideoDec->csc_handle != NULL) { + csc_deinit(pVideoDec->csc_handle); + pVideoDec->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent); + pH264Dec->hDestinationStartEvent = NULL; + pH264Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent); + pH264Dec->hSourceStartEvent = NULL; + pH264Dec->bSourceStart = OMX_FALSE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + H264CodecDstFreeCodecBuffers(pOMXComponent); + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); + pVideoDec->pMFCDecInputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + H264CodecClose(pH264Dec); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + OMX_BOOL bInStartCode = OMX_FALSE; + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData); + goto EXIT; + } + if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) { + ret = H264CodecDstSetup(pOMXComponent); + } + + if (((pVideoDec->bDRMPlayerMode == OMX_TRUE) || + ((bInStartCode = Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE)) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Dec->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags); + pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp); + pH264Dec->hMFCH264Handle.indexTimestamp++; + pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + + if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) { + /* Enable Immediately display After seek*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); + pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE; + } + } +#endif + + /*Add First Frame check : */ + if((pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG) + { + MMTA_ACUM_ITEM_END("Video First Frame Coming", 0); + } + + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + if (codecReturn != VIDEO_ERROR_NONE) { + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + goto EXIT; + } + H264CodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pH264Dec->bSourceStart == OMX_FALSE) { + pH264Dec->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pH264Dec->bDestinationStart == OMX_FALSE) { + pH264Dec->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } else if (bInStartCode == OMX_FALSE) { + ret = OMX_ErrorCorruptedFrame; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + i++; + } + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + + if ((pVideoDec->bDRCProcessing == OMX_TRUE) && + (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) && + (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) { + ret = H264CodecDstSetup(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig H264CodecDstSetup Failed"); + goto EXIT; + } + pVideoDec->bDRCProcessing = OMX_FALSE; + } + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry *bufferGeometry; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + OMX_S32 indexTimestamp = 0; + int plane; + + FunctionIn(); + + if (pH264Dec->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + while (1) { + pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle); + if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available"); + ret = OMX_ErrorHardware; + goto EXIT; + } + + if (pVideoBuffer == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + displayStatus = pVideoBuffer->displayStatus; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus); + + if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || + (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + if (pVideoBuffer != NULL) { + ret = OMX_ErrorNone; + break; + } else { + ret = OMX_ErrorUndefined; + break; + } + } + } + + if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) { + if (pVideoDec->bDRCProcessing != OMX_TRUE) { + pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; + pVideoDec->bDRCProcessing = OMX_TRUE; + H264CodecCheckResolutionChange(pOMXComponent); + pVideoDec->csc_set_format = OMX_FALSE; + } + ret = OMX_ErrorNone; + goto EXIT; + } + + pH264Dec->hMFCH264Handle.outputIndexTimestamp++; + pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->allocSize = pDstOutputData->dataLen = 0; + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; + pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; + } + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; + bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf; + pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; + pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + switch (bufferGeometry->eColorFormat) { + case VIDEO_COLORFORMAT_NV12: +#ifdef SLP_PLATFORM /* NV12T fd */ + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#else + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#endif + break; + case VIDEO_COLORFORMAT_NV12_TILED: + default: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + break; + } + +#ifdef USE_S3D_SUPPORT + /* Check Whether frame packing information is available */ + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pVideoDec->bThumbnailMode == OMX_FALSE && + pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_NONE) { + H264CodecCheckFramePacking(pOMXComponent); + } +#endif + + indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) && + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp); + } else { + pDstOutputData->timeStamp = 0x00; + pDstOutputData->nFlags = 0x00; + } + } else { + /* For timestamp correction. if mfc support frametype detect */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType); +//#ifdef NEED_TIMESTAMP_REORDER + /* SLP_PLATFORM */ + if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NEED_TIMESTAMP_REORDER ON"); + if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp]; + } +//#else + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } +//endif + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags); + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } else { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData); + if ((ret != OMX_ErrorNone) && + (ret != OMX_ErrorInputDataDecodeYet) && + (ret != OMX_ErrorCorruptedFrame)) { +pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pH264Dec->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent); + } + + ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pH264Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent); + } + } + if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pH264Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent); + } + } + ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + OMX_BOOL bDRMPlayerMode = OMX_FALSE; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) { + bDRMPlayerMode = OMX_FALSE; + } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) { + bDRMPlayerMode = OMX_TRUE; + } else { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE)); + if (pH264Dec == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE)); + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec; + + if (bDRMPlayerMode == OMX_TRUE) + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC); + else + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DEC); + + pVideoDec->bDRMPlayerMode = bDRMPlayerMode; + /* In case of BUFFER_COPY mode + bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR + bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP + In case of BUFFER_SHARE + bShareableBuf should be TRUE, FALSE is ignored + */ + pH264Dec->hMFCH264Handle.bShareableBuf = OMX_FALSE; +#ifdef USE_S3D_SUPPORT + pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE; +#endif + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + if (bDRMPlayerMode == OMX_TRUE) + pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; +#ifdef SLP_PLATFORM + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#else + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; +#endif + pExynosPort->portDefinition.bEnabled = OMX_TRUE; +#ifdef SLP_PLATFORM + pExynosPort->bufferProcessType = BUFFER_SHARE; +#else + pExynosPort->bufferProcessType = BUFFER_COPY; +#endif + pExynosPort->portWayType = WAY2_PORT; + + 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 = &Exynos_H264Dec_GetParameter; + pOMXComponent->SetParameter = &Exynos_H264Dec_SetParameter; + pOMXComponent->GetConfig = &Exynos_H264Dec_GetConfig; + pOMXComponent->SetConfig = &Exynos_H264Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_H264Dec_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate; + + pVideoDec->exynos_codec_srcInputProcess = &Exynos_H264Dec_srcInputBufferProcess; + pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess; + pVideoDec->exynos_codec_dstInputProcess = &Exynos_H264Dec_dstInputBufferProcess; + pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess; + + pVideoDec->exynos_codec_start = &H264CodecStart; + pVideoDec->exynos_codec_stop = &H264CodecStop; + pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun; + pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer; + pVideoDec->exynos_codec_resetupAllElement = &H264CodecResetupAllElement; + + pVideoDec->exynos_checkInputFrame = &Check_H264_Frame; + pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoDec->hSharedMemory == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + Exynos_OSAL_Free(pH264Dec); + pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pH264Dec != NULL) { + Exynos_OSAL_Free(pH264Dec); + pH264Dec = pVideoDec->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h new file mode 100644 index 0000000..9b039f2 --- /dev/null +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h @@ -0,0 +1,81 @@ +/* + * + * 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 Exynos_OMX_H264dec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_H264_DEC_COMPONENT +#define EXYNOS_OMX_H264_DEC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "ExynosVideoApi.h" + +typedef struct _EXYNOS_MFC_H264DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + OMX_U32 maxDPBNum; +#ifdef USE_S3D_SUPPORT + EXYNOS_OMX_FPARGMT_TYPE S3DFPArgmtType; +#endif + + ExynosVideoColorFormatType MFCOutputColorType; + ExynosVideoDecOps *pDecOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoGeometry codecOutbufConf; +} EXYNOS_MFC_H264DEC_HANDLE; + +typedef struct _EXYNOS_H264DEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* EXYNOS MFC Codec specific */ + EXYNOS_MFC_H264DEC_HANDLE hMFCH264Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +} EXYNOS_H264DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/h264/Makefile.am b/openmax/component/video/dec/h264/Makefile.am new file mode 100644 index 0000000..8cdbb5d --- /dev/null +++ b/openmax/component/video/dec/h264/Makefile.am @@ -0,0 +1,48 @@ +lib_LTLIBRARIES = libOMX.Exynos.AVC.Decoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_AVC_Decoder_la_SOURCES = Exynos_OMX_H264dec.c \ + Exynos_OMX_H264dec.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_AVC_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + + +libOMX_Exynos_AVC_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc\ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + +if BOARD_USE_ANB +libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DUSE_ANB +endif + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_DMA_BUF +libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DUSE_DMA_BUF +endif + +if BOARD_USE_DRM +libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DUSE_DRM +endif + +if BOARD_USE_MFC_FPS +libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DCONFIG_MFC_FPS +endif + +libOMX_Exynos_AVC_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/dec/h264/library_register.c b/openmax/component/video/dec/h264/library_register.c new file mode 100644 index 0000000..7fe26e8 --- /dev/null +++ b/openmax/component/video/dec/h264/library_register.c @@ -0,0 +1,59 @@ +/* + * + * 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 library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" +#include "Exynos_OSAL_Log.h" + + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents) +{ + FunctionIn(); + + if (exynosComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_DEC); + Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE); + exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video decoder H.264 for DRM */ + Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC); + Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE); + exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} diff --git a/openmax/component/video/dec/h264/library_register.h b/openmax/component/video/dec/h264/library_register.h new file mode 100644 index 0000000..e727322 --- /dev/null +++ b/openmax/component/video/dec/h264/library_register.h @@ -0,0 +1,56 @@ +/* + * + * 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 library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_H264_REG +#define EXYNOS_OMX_H264_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_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 EXYNOS_OMX_COMPONENT_H264_DEC "OMX.Exynos.AVC.Decoder" +#define EXYNOS_OMX_COMPONENT_H264_DRM_DEC "OMX.Exynos.AVC.Decoder.secure" +#define EXYNOS_OMX_COMPONENT_H264_DEC_ROLE "video_decoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/openmax/component/video/dec/mpeg2/Android.mk b/openmax/component/video/dec/mpeg2/Android.mk new file mode 100644 index 0000000..2862afd --- /dev/null +++ b/openmax/component/video/dec/mpeg2/Android.mk @@ -0,0 +1,51 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Mpeg2dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.MPEG2.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 + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler + +ifeq ($(BOARD_USES_MFC_FPS),true) +LOCAL_CFLAGS += -DCONFIG_MFC_FPS +endif + +LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + hardware/samsung_slsi/exynos4/include \ + hardware/samsung_slsi/exynos4/libcsc \ + hardware/samsung_slsi/exynos4/libcodec/video/v4l2/include + + + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c new file mode 100644 index 0000000..1fce8b5 --- /dev/null +++ b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c @@ -0,0 +1,2129 @@ +/* + * + * 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 Exynos_OMX_Mpeg2dec.c + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_Mpeg2dec.h" +#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG2_DEC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +#define MPEG2_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH /* Full frame search not support*/ + +static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (addr != NULL) { + addr[0] = pCodecBuffer->planes[0].addr; + addr[1] = pCodecBuffer->planes[1].addr; + addr[2] = pCodecBuffer->planes[2].addr; + } + + if (size != NULL) { + size[0] = pCodecBuffer->planes[0].allocSize; + size[1] = pCodecBuffer->planes[1].allocSize; + size[2] = pCodecBuffer->planes[2].allocSize; + } + +EXIT: + return ret; +} + +int Check_Mpeg2_Frame( + OMX_U8 *pInputStream, + int buffSize, + OMX_U32 flag, + OMX_BOOL bPreviousFrameEOF, + OMX_BOOL *pbEndOfFrame) +{ + FunctionIn(); + + *pbEndOfFrame = OMX_TRUE; + + /* Frame Start code*/ + if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found"); + *pbEndOfFrame = OMX_FALSE; + } + + FunctionOut(); + return buffSize; +} + +static OMX_BOOL Check_Mpeg2_StartCode( + OMX_U8 *pInputStream, + OMX_U32 streamSize) +{ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize); + + if (streamSize < 3) { + return OMX_FALSE; + } + + /* Frame Start code*/ + if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found"); + return OMX_FALSE; + } + + return OMX_TRUE; +} + +OMX_ERRORTYPE Mpeg2CodecOpen(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pMpeg2Dec == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps)); + pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + + if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pMpeg2Dec->hMFCMpeg2Handle.pDecOps = pDecOps; + pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = pInbufOps; + pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pDecOps->nSize = sizeof(ExynosVideoDecOps); + pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + + Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for decoder ops */ + if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || + (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || + (pDecOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* alloc context, open, querycap */ +#ifdef USE_DMA_BUF + pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); +#else + pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(V4L2_MEMORY_USERPTR); +#endif + if (pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecClose(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pMpeg2Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pDecOps->Finalize(hMFCHandle); + pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL; + } + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg2Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg2Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg2Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pMpeg2Dec->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pMpeg2Dec->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pMpeg2Dec->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]); + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pMpeg2Dec->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); + nOutbufs += EXTRA_DPB_NUM; + for (i = 0; i < nOutbufs; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pVideoDec->bThumbnailMode == OMX_TRUE) + pDecOps->Set_DisplayDelay(hMFCHandle, 0); + + /* input buffer info */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + bufferConf.eCompressionFormat = VIDEO_CODING_MPEG2; + pInbufOps->Set_Shareable(hMFCHandle); + if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { + bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth + * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]; + plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0]; + plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "BUFFER_COPY Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { + /* Register input buffer */ + for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { + ExynosVideoPlane plane; + plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "BUFFER_SHARE Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + + /* set output geometry */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* input buffer enqueue for header parsing */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); + if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); +// ret = OMX_ErrorInsufficientResources; + ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; + goto EXIT; + } + + /* start header parsing */ + if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + /* get geometry for output */ + Exynos_OSAL_Memset(&pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* get dpb count */ + pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg2CodecSetup nOutbufs: %d", pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum); + + pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_TRUE; + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + Exynos_UpdateFrameSize(pOMXComponent); +/* FIXME: OMX_EventPortSettingsChanged. do not set NEED_PORT_DISABLE in SLP platform now */ +/* pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;*/ + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight) || + (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum - 4; + pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum - 4; + + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } + Exynos_OSAL_SleepMillisec(0); + ret = OMX_ErrorInputDataDecodeYet; + Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + int i, nOutbufs; + + FunctionIn(); + + /* get dpb count */ + nOutbufs = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum; + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + pOutbufOps->Set_Shareable(hMFCHandle); + if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int plane; + + nAllocLen[0] = calc_plane(pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth, + pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_plane(pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth, + pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight >> 1); + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY); + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane]; + + planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]; + planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane]; + planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + /* Register output buffer */ + /*************/ + /* TBD */ + /*************/ +#ifdef USE_PB + if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) { + for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; + planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].allocSize = nAllocLen[plane]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } +#else + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + Mpeg2CodecStop (pOMXComponent, OUTPUT_PORT_INDEX); + } + pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg2: + { + OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + ret = Exynos_OMX_Check_SizeVersion(pDstMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "1"); + goto EXIT; + } + + if (pDstMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "2"); + ret = OMX_ErrorBadPortIndex; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg2Param = &pMpeg2Dec->Mpeg2Component[pDstMpeg2Param->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstMpeg2Param, pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Component = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + ret = Exynos_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; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg2Component = &pMpeg2Dec->Mpeg2Component[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcMpeg2Component->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg2Component->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + ret = Exynos_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; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcErrorCorrectionType = &pMpeg2Dec->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 = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg2: + { + OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = NULL; + OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstMpeg2Param = &pMpeg2Dec->Mpeg2Component[pSrcMpeg2Param->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstMpeg2Param, pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE)) { + pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + realWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + realHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pExynosPort->portDefinition.format.video.nStride = width; + pExynosPort->portDefinition.format.video.nSliceHeight = height; + pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + pExynosOutputPort->portDefinition.format.video.nStride = width; + pExynosOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: +// case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + //case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + pExynosOutputPort->portDefinition.nBufferSize = + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + + if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + pExynosOutputPort->portDefinition.nBufferSize = + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Component = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + ret = Exynos_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; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + + pDstMpeg2Component = &pMpeg2Dec->Mpeg2Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg2Component->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg2Component->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + ret = Exynos_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; + } + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstErrorCorrectionType = &pMpeg2Dec->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 = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + *pIndexType = OMX_IndexVendorThumbnailMode; + ret = OMX_ErrorNone; + } else { + ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_ComponentRoleEnum( + OMX_HANDLETYPE hComponent, + OMX_U8 *cRole, + OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + OMX_PTR hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i, plane; + + FunctionIn(); + + pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE; + pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + /* Mpeg2 Codec Open */ + ret = Mpeg2CodecOpen(pMpeg2Dec); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY); + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pMpeg2Dec->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg2Dec->hSourceStartEvent); + pMpeg2Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg2Dec->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp = 0; + pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + pVideoDec->csc_handle = csc_init(csc_method); + if (pVideoDec->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_Mpeg2Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + + int i, plane; + + FunctionIn(); + + if (pVideoDec->csc_handle != NULL) { + csc_deinit(pVideoDec->csc_handle); + pVideoDec->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationStartEvent); + pMpeg2Dec->hDestinationStartEvent = NULL; + pMpeg2Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pMpeg2Dec->hSourceStartEvent); + pMpeg2Dec->hSourceStartEvent = NULL; + pMpeg2Dec->bSourceStart = OMX_FALSE; + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]); + pVideoDec->pMFCDecOutputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); + pVideoDec->pMFCDecInputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + Mpeg2CodecClose(pMpeg2Dec); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = Mpeg2CodecSrcSetup(pOMXComponent, pSrcInputData); + goto EXIT; + } + if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE) { + ret = Mpeg2CodecDstSetup(pOMXComponent); + } + + if ((Check_Mpeg2_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize) == OMX_TRUE) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){ + pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp, pSrcInputData->nFlags); + pDecOps->Set_FrameTag(hMFCHandle, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp); + pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp++; + pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp %= MAX_TIMESTAMP; + + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + if (codecReturn != VIDEO_ERROR_NONE) { + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + goto EXIT; + } + Mpeg2CodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pMpeg2Dec->bSourceStart == OMX_FALSE) { + pMpeg2Dec->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pMpeg2Dec->bDestinationStart == OMX_FALSE) { + pMpeg2Dec->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + i++; + } + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + Mpeg2CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry *bufferGeometry; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + OMX_S32 indexTimestamp = 0; + int plane; + + FunctionIn(); + + if (pMpeg2Dec->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + while (1) { + if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + displayStatus = pVideoBuffer->displayStatus; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus); + + if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || + (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + if (pVideoBuffer != NULL) { + ret = OMX_ErrorNone; + break; + } else { + ret = OMX_ErrorUndefined; + break; + } + } + } + + if (ret != OMX_ErrorNone) + goto EXIT; + + pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp++; + pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->allocSize = pDstOutputData->dataLen = 0; + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; + pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; + } + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; + bufferGeometry = &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf; + pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; + pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + switch (bufferGeometry->eColorFormat) { + case VIDEO_COLORFORMAT_NV12: + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case VIDEO_COLORFORMAT_NV12_TILED: + default: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + break; + } + + indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) && + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp); + } else { + pDstOutputData->timeStamp = 0x00; + pDstOutputData->nFlags = 0x00; + } + } else { + /* For timestamp correction. if mfc support frametype detect */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType); +//#ifdef NEED_TIMESTAMP_REORDER + /* SLP_PLATFORM */ + if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) { + if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = indexTimestamp; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp]; + } +//#else + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } +//#endif + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags); + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } else { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_Mpeg2Dec_SrcIn(pOMXComponent, pSrcInputData); + if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pMpeg2Dec->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pMpeg2Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg2Dec->hSourceStartEvent); + } + + ret = Exynos_Mpeg2Dec_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { + if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent); + } + } + if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_Mpeg2Dec_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg2Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { + if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent); + } + } + ret = Exynos_Mpeg2Dec_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG2_DEC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg2Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG2DEC_HANDLE)); + if (pMpeg2Dec == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pMpeg2Dec, 0, sizeof(EXYNOS_MPEG2DEC_HANDLE)); + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg2Dec; + + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG2_DEC); + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg2"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + //pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; +#ifdef SLP_PLATFORM + pExynosPort->bufferProcessType = BUFFER_SHARE; +#else + pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_PBSHARE; +#endif + pExynosPort->portWayType = WAY2_PORT; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg2Dec->Mpeg2Component[i], OMX_VIDEO_PARAM_MPEG2TYPE); + pMpeg2Dec->Mpeg2Component[i].nPortIndex = i; + pMpeg2Dec->Mpeg2Component[i].eProfile = OMX_VIDEO_MPEG2ProfileMain; + pMpeg2Dec->Mpeg2Component[i].eLevel = OMX_VIDEO_MPEG2LevelML; /* Check again**** */ + } + + pOMXComponent->GetParameter = &Exynos_Mpeg2Dec_GetParameter; + pOMXComponent->SetParameter = &Exynos_Mpeg2Dec_SetParameter; + pOMXComponent->GetConfig = &Exynos_Mpeg2Dec_GetConfig; + pOMXComponent->SetConfig = &Exynos_Mpeg2Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_Mpeg2Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg2Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_Mpeg2Dec_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg2Dec_Terminate; + + pVideoDec->exynos_codec_srcInputProcess = &Exynos_Mpeg2Dec_srcInputBufferProcess; + pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg2Dec_srcOutputBufferProcess; + pVideoDec->exynos_codec_dstInputProcess = &Exynos_Mpeg2Dec_dstInputBufferProcess; + pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg2Dec_dstOutputBufferProcess; + + pVideoDec->exynos_codec_start = &Mpeg2CodecStart; + pVideoDec->exynos_codec_stop = &Mpeg2CodecStop; + pVideoDec->exynos_codec_bufferProcessRun = &Mpeg2CodecOutputBufferProcessRun; + pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg2CodecEnQueueAllBuffer; + + pVideoDec->exynos_checkInputFrame = &Check_Mpeg2_Frame; + pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoDec->hSharedMemory == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + Exynos_OSAL_Free(pMpeg2Dec); + pMpeg2Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( + OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg2Dec != NULL) { + Exynos_OSAL_Free(pMpeg2Dec); + pMpeg2Dec = pVideoDec->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h new file mode 100644 index 0000000..914ed64 --- /dev/null +++ b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h @@ -0,0 +1,81 @@ +/* + * + * 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 Exynos_OMX_Mpeg2dec.h + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#ifndef EXYNOS_OMX_MPEG2_DEC_COMPONENT +#define EXYNOS_OMX_MPEG2_DEC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "ExynosVideoApi.h" + + +typedef struct _EXYNOS_MFC_MPEG2DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + OMX_U32 maxDPBNum; + + ExynosVideoColorFormatType MFCOutputColorType; + ExynosVideoDecOps *pDecOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoGeometry codecOutbufConf; +} EXYNOS_MFC_MPEG2DEC_HANDLE; + +typedef struct _EXYNOS_MPEG2DEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_MPEG2TYPE Mpeg2Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* EXYNOS MFC Codec specific */ + EXYNOS_MFC_MPEG2DEC_HANDLE hMFCMpeg2Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +} EXYNOS_MPEG2DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName); +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( + OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/mpeg2/Makefile.am b/openmax/component/video/dec/mpeg2/Makefile.am new file mode 100644 index 0000000..8a5d601 --- /dev/null +++ b/openmax/component/video/dec/mpeg2/Makefile.am @@ -0,0 +1,40 @@ +lib_LTLIBRARIES = libOMX.Exynos.M2V.Decoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_M2V_Decoder_la_SOURCES = Exynos_OMX_Mpeg2dec.c \ + Exynos_OMX_Mpeg2dec.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_M2V_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + +libOMX_Exynos_M2V_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc\ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + +if BOARD_USE_ANB +libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DUSE_ANB +endif + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_DMA_BUF +libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DUSE_DMA_BUF +endif + + +libOMX_Exynos_M2V_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/dec/mpeg2/library_register.c b/openmax/component/video/dec/mpeg2/library_register.c new file mode 100644 index 0000000..cc66aec --- /dev/null +++ b/openmax/component/video/dec/mpeg2/library_register.c @@ -0,0 +1,58 @@ +/* + * + * 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 library_register.c + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG2_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - video decoder MPEG2 */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG2_DEC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} diff --git a/openmax/component/video/dec/mpeg2/library_register.h b/openmax/component/video/dec/mpeg2/library_register.h new file mode 100644 index 0000000..993c55d --- /dev/null +++ b/openmax/component/video/dec/mpeg2/library_register.h @@ -0,0 +1,55 @@ +/* + * + * 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 library_register.h + * @brief + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#ifndef EXYNOS_OMX_MPEG2_DEC_REG +#define EXYNOS_OMX_MPEG2_DEC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG2 */ +#define EXYNOS_OMX_COMPONENT_MPEG2_DEC "OMX.Exynos.MPEG2.Decoder" +#define EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE "video_decoder.mpeg2" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/mpeg4/Android.mk b/openmax/component/video/dec/mpeg4/Android.mk new file mode 100644 index 0000000..98d0f7f --- /dev/null +++ b/openmax/component/video/dec/mpeg4/Android.mk @@ -0,0 +1,48 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Mpeg4dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.MPEG4.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c new file mode 100644 index 0000000..c518a06 --- /dev/null +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -0,0 +1,2947 @@ +/* + * + * 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 Exynos_OMX_Mpeg4dec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_Mpeg4dec.h" +#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG4_DEC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +#define MPEG4_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH + +/* MPEG4 Decoder Supported Levels & profiles */ +EXYNOS_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 */ +EXYNOS_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_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (addr != NULL) { + addr[0] = pCodecBuffer->planes[0].addr; + addr[1] = pCodecBuffer->planes[1].addr; + addr[2] = pCodecBuffer->planes[2].addr; + } + + if (size != NULL) { + size[0] = pCodecBuffer->planes[0].allocSize; + size[1] = pCodecBuffer->planes[1].allocSize; + size[2] = pCodecBuffer->planes[2].allocSize; + } + +EXIT: + return ret; +} + +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 */ + BitmapInfoHhr *pInfoHeader; + + pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1); + /* FIXME */ + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "############## NOT SUPPORTED #################"); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "width(%d), height(%d)", pInfoHeader->BiWidth, pInfoHeader->BiHeight); + 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; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); + + return len - 4; + +EXIT : + *pbEndOfFrame = OMX_FALSE; + + Exynos_OSAL_Log(EXYNOS_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; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize); + + return len - 3; + +EXIT : + + *pbEndOfFrame = OMX_FALSE; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +static OMX_BOOL Check_Stream_StartCode( + 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) { + unsigned startCode = 0xFFFFFFFF; + unsigned pTypeMask = 0x03; + unsigned pType = 0; + OMX_U32 len = 0; + int readStream; + /* Check 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 > 0x3) + break; + } + + if (len > 0x3) { + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Picture Start Code Missing", __FUNCTION__); + return OMX_FALSE; + } else { + return OMX_TRUE; + } + } else { + return OMX_FALSE; + } + default: + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType); + return OMX_FALSE; + } +} + +static void getAByte(char *buff, int *code) +{ + int byte; + + *code = (*code << 8); + byte = (int)*buff; + byte &= 0xFF; + *code |= byte; +} + +static int Check_IsPBPacked( + OMX_U8 *pInputStream, + OMX_U32 streamSize) +{ + OMX_U8 *pStrmBuf = NULL; + int startCode = 0xFFFFFFFF; + int leng_idx = 1; + + pStrmBuf = pInputStream; + + while (1) { + while (startCode != USR_DATA_START_CODE) { + if ((startCode == VOP_START_CODE) || (leng_idx == streamSize)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"isPBPacked] VOP START Found !! Non Packed PB.....return"); + return 0; + } + getAByte(pStrmBuf, &startCode); + pStrmBuf++; + leng_idx++; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"isPBPacked] User Data Found !!"); + + do { + if (*pStrmBuf == 'p') { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"isPBPacked] Packed PB\n"); + return 1; + } + getAByte(pStrmBuf, &startCode); + pStrmBuf++; leng_idx++; + } while ((leng_idx <= streamSize) && ((startCode >> 8) != MP4_START_CODE)); + + if (leng_idx > streamSize) + break; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"isPBPacked] Non Packed PB"); + + return 0; +} + +OMX_ERRORTYPE Mpeg4CodecOpen(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pMpeg4Dec == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps)); + pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + + if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pMpeg4Dec->hMFCMpeg4Handle.pDecOps = pDecOps; + pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = pInbufOps; + pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pDecOps->nSize = sizeof(ExynosVideoDecOps); + pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + + Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for decoder ops */ + if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || + (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || + (pDecOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* alloc context, open, querycap */ + if (pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { +#ifdef USE_DMA_BUF + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); +#else + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(V4L2_MEMORY_USERPTR); +#endif + } else { + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); + } + if (pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecClose(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pMpeg4Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pDecOps->Finalize(hMFCHandle); + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL; + } + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg4Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg4Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, plane; + + if (pVideoDec->bThumbnailMode == OMX_TRUE) + pDecOps->Set_DisplayDelay(hMFCHandle, 0); + + /* input buffer info */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4; + else + bufferConf.eCompressionFormat = VIDEO_CODING_H263; + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE + ||pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + pInbufOps->Set_Shareable(hMFCHandle); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth + * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; + } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]; + plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0]; + plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) { + ExynosVideoBuffer *pBuffer = NULL; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + /* get input buffer info */ + if (pInbufOps->Get_Buffer) { + if (pInbufOps->Get_Buffer(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + +#ifdef SLP_PLATFORM + if (pExynosInputPort == NULL || pExynosOutputPort == NULL || pOMXComponent == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "invalid param: pExynosInputPort= %p pExynosOutputPort= %p pOMXComponent= %p", pExynosInputPort, pExynosOutputPort, pOMXComponent); + } +#endif + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /* Register input buffer */ + for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { + ExynosVideoPlane plane; + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { + plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); + } else { + plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + } + plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + + + +OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg4Dec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pMpeg4Dec->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pMpeg4Dec->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pMpeg4Dec->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]); + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pMpeg4Dec->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); + nOutbufs += EXTRA_DPB_NUM; + for (i = 0; i < nOutbufs; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE Mpeg4CodecDstFreeCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + + int i, j; + + FunctionIn(); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + } + + Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]); + } + } + + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer)); + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Mpeg4CodecDstAllocCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + + MEMORY_TYPE eMemoryType = NORMAL_MEMORY; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + nAllocLen[0] = calc_yplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth, + pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_uvplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth, + pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight >> 1); + + for (i = 0; i < nOutbufs; i++) { + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType); + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pVideoDec->pMFCDecOutputBuffer[i]->fd[j] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j]; + } + } + + return OMX_ErrorNone; + +EXIT: + Mpeg4CodecDstFreeCodecBuffers(pOMXComponent); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecDstRegistCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + planes[j].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]; + planes[j].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[j]; + planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecResetupAllElement( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + int i, j, nOutbufs; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pMpeg4Dec->bSourceStart == OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pMpeg4Dec->bDestinationStart == OMX_TRUE)) { + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + + /**********************************/ + /* Codec Buffer Free & Unregister */ + /**********************************/ + Mpeg4CodecDstFreeCodecBuffers(pOMXComponent); + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + if (pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + + pOutbufOps->Cleanup(hMFCHandle); + /******************************************************/ + /* V4L2 Destnation Setup for DPB Buffer Number Change */ + /******************************************************/ + Mpeg4CodecDstSetup(pOMXComponent); + + pVideoDec->bDRCProcessing = OMX_FALSE; + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + + /**********************************/ + /* Codec Buffer Unregister */ + /**********************************/ + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + pOutbufOps->Cleanup(hMFCHandle); + } + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE)) { + ret = Mpeg4CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + + /*Check for PB Packed*/ + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4 && + Check_IsPBPacked(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) { + if (pDecOps->Enable_PackedPB(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pMpeg4Dec->hMFCMpeg4Handle.bPackedPB = OMX_TRUE; + } + + /* set output geometry */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* input buffer enqueue for header parsing */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); + if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); +// ret = OMX_ErrorInsufficientResources; + ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; + goto EXIT; + } + + /* start header parsing */ + if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + ret = Mpeg4CodecCheckResolutionChange(pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + Exynos_OSAL_SleepMillisec(0); + ret = OMX_ErrorInputDataDecodeYet; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); +#endif +EXIT: + Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX); + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + int i, nOutbufs; + + FunctionIn(); + + /* get dpb count */ + nOutbufs = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE + ||pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Set_Shareable(hMFCHandle); + + if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int plane; + + nAllocLen[0] = calc_yplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth, + pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_uvplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth, + pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight >> 1); + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + Mpeg4CodecDstAllocCodecBuffers(pOMXComponent, nOutbufs); + Mpeg4CodecDstRegistCodecBuffers(pOMXComponent, nOutbufs); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) { + + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + int plane; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + if (pOutbufOps->Get_Buffer) { + if (pOutbufOps->Get_Buffer(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { +#ifdef USE_PB + if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) { + for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; + planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].allocSize = nAllocLen[plane]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } +#else + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + Mpeg4CodecStop (pOMXComponent, OUTPUT_PORT_INDEX); + } + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + int i; + + FunctionIn(); + + /* get geometry for output */ + Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* get dpb count */ + pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg4CodecCheckResolutionChange Mpeg4CodecSetup nOutbufs: %d", pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVideoDec->bDRCProcessing) || + (pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) || + (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } +#ifdef SLP_PLATFORM + pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; + pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; +#else + pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 4; + pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 4; +#endif + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex]; + + Exynos_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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex]; + + Exynos_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 = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE); + else + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = Exynos_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 = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(EXYNOS_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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex]; + + Exynos_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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE)) { + pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE)) { + pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition_backup; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize); + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup); + + realWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + realHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pExynosPort->portDefinition.format.video.nStride = width; + pExynosPort->portDefinition.format.video.nSliceHeight = height; + pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + pExynosOutputPort->portDefinition.format.video.nStride = width; + pExynosOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; +#ifdef SLP_PLATFORM /* NV12T fd */ + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + break; +#endif + case OMX_SEC_COLOR_FormatNV12Tiled: + pExynosOutputPort->portDefinition.nBufferSize = + calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + pExynosOutputPort->portDefinition.nBufferSize = + calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + } + } + } + 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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + *pIndexType = OMX_IndexVendorThumbnailMode; + ret = OMX_ErrorNone; + } else { + ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = 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 = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE); + else + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i, plane; + + FunctionIn(); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE; + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + /* Mpeg4 Codec Open */ + ret = Mpeg4CodecOpen(pMpeg4Dec); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + if (pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY); + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else { +#ifdef SLP_PLATFORM + if (pOMXComponent == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d: invalid parm: pOMXComponent = %p", __FUNCTION__, __LINE__, pOMXComponent); + } +#endif + ret = Mpeg4CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pMpeg4Dec->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg4Dec->hSourceStartEvent); + pMpeg4Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg4Dec->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + pVideoDec->csc_handle = csc_init(csc_method); + if (pVideoDec->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + int i, plane; + + FunctionIn(); + + if (pVideoDec->csc_handle != NULL) { + csc_deinit(pVideoDec->csc_handle); + pVideoDec->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationStartEvent); + pMpeg4Dec->hDestinationStartEvent = NULL; + pMpeg4Dec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pMpeg4Dec->hSourceStartEvent); + pMpeg4Dec->hSourceStartEvent = NULL; + pMpeg4Dec->bSourceStart = OMX_FALSE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Mpeg4CodecDstFreeCodecBuffers(pOMXComponent); + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); + pVideoDec->pMFCDecInputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + Mpeg4CodecClose(pMpeg4Dec); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + OMX_BOOL bInStartCode = OMX_FALSE; + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData); + goto EXIT; + } + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) { + ret = Mpeg4CodecDstSetup(pOMXComponent); + } + + if (((bInStartCode = Check_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType)) == OMX_TRUE) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){ + pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags); + pDecOps->Set_FrameTag(hMFCHandle, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) { + /* Enable Immediately display After seek*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); + pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE; + } + } +#endif + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + if (codecReturn != VIDEO_ERROR_NONE) { + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + goto EXIT; + } + Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pMpeg4Dec->bSourceStart == OMX_FALSE) { + pMpeg4Dec->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pMpeg4Dec->bDestinationStart == OMX_FALSE) { + pMpeg4Dec->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } else if (bInStartCode == OMX_FALSE) { + ret = OMX_ErrorCorruptedFrame; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + i++; + } + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + + if ((pVideoDec->bDRCProcessing == OMX_TRUE) && + (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) && + (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) { + ret = Mpeg4CodecDstSetup(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig CodecDstSetup Failed"); + goto EXIT; + } + pVideoDec->bDRCProcessing = OMX_FALSE; + } + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry *bufferGeometry; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + OMX_S32 indexTimestamp = 0; + int plane; + + FunctionIn(); + + if (pMpeg4Dec->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + while (1) { + pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle); + if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available"); + ret = OMX_ErrorHardware; + goto EXIT; + } + + if (pVideoBuffer == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + displayStatus = pVideoBuffer->displayStatus; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus); + + if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || + (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + if (pVideoBuffer != NULL) { + ret = OMX_ErrorNone; + break; + } else { + ret = OMX_ErrorUndefined; + break; + } + } + } + + if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) { + if (pVideoDec->bDRCProcessing != OMX_TRUE) { + pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; + pVideoDec->bDRCProcessing = OMX_TRUE; + Mpeg4CodecCheckResolutionChange(pOMXComponent); + pVideoDec->csc_set_format = OMX_FALSE; + } + ret = OMX_ErrorNone; + goto EXIT; + } + + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->allocSize = pDstOutputData->dataLen = 0; + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; + pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; + } + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; + bufferGeometry = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf; + pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; + pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + switch (bufferGeometry->eColorFormat) { + case VIDEO_COLORFORMAT_NV12: +#ifdef SLP_PLATFORM /* NV12T fd */ + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#else + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#endif + break; + case VIDEO_COLORFORMAT_NV12_TILED: + default: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + break; + } + + indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) && + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp); + } else { + pDstOutputData->timeStamp = 0x00; + pDstOutputData->nFlags = 0x00; + } + } else { + /* For timestamp correction. if mfc support frametype detect */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType); +//#ifdef NEED_TIMESTAMP_REORDER + if (pMpeg4Dec->hMFCMpeg4Handle.bPackedPB == OMX_TRUE || + pVideoDec->bNeedTimestampReorder == OMX_TRUE) { /* SLP_PLATFORM */ + if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp]; + } + } else { +//#else + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } +//#endif + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags); + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } else { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_Mpeg4Dec_SrcIn(pOMXComponent, pSrcInputData); +if ((ret != OMX_ErrorNone) && + (ret != OMX_ErrorInputDataDecodeYet) && + (ret != OMX_ErrorCorruptedFrame)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pMpeg4Dec->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Dec->hSourceStartEvent); + } + + ret = Exynos_Mpeg4Dec_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent); + } + } + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent); + } + } + ret = Exynos_Mpeg4Dec_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + int i = 0; + OMX_S32 codecType = -1; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_DEC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4DEC_HANDLE)); + if (pMpeg4Dec == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pMpeg4Dec, 0, sizeof(EXYNOS_MPEG4DEC_HANDLE)); + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec; + pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DEC); + else + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H263_DEC); + + /* In case of BUFFER_COPY mode + bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR + bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP + In case of BUFFER_SHARE + bShareableBuf should be TRUE, FALSE is ignored + */ + pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf = OMX_FALSE; + pMpeg4Dec->hMFCMpeg4Handle.bPackedPB = OMX_FALSE; + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + if (codecType == CODEC_TYPE_MPEG4) { + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; +#ifdef SLP_PLATFORM + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; + pExynosPort->bufferProcessType = BUFFER_SHARE; +#else + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pExynosPort->bufferProcessType = BUFFER_COPY; +#endif + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->portWayType = WAY2_PORT; + + 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 = &Exynos_Mpeg4Dec_GetParameter; + pOMXComponent->SetParameter = &Exynos_Mpeg4Dec_SetParameter; + pOMXComponent->GetConfig = &Exynos_Mpeg4Dec_GetConfig; + pOMXComponent->SetConfig = &Exynos_Mpeg4Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_Mpeg4Dec_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Dec_Terminate; + + pVideoDec->exynos_codec_srcInputProcess = &Exynos_Mpeg4Dec_srcInputBufferProcess; + pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Dec_srcOutputBufferProcess; + pVideoDec->exynos_codec_dstInputProcess = &Exynos_Mpeg4Dec_dstInputBufferProcess; + pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Dec_dstOutputBufferProcess; + + pVideoDec->exynos_codec_start = &Mpeg4CodecStart; + pVideoDec->exynos_codec_stop = &Mpeg4CodecStop; + pVideoDec->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun; + pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnQueueAllBuffer; + pVideoDec->exynos_codec_resetupAllElement = &Mpeg4CodecResetupAllElement; + + if (codecType == CODEC_TYPE_MPEG4) + pVideoDec->exynos_checkInputFrame = &Check_Mpeg4_Frame; + else + pVideoDec->exynos_checkInputFrame = &Check_H263_Frame; + + pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoDec->hSharedMemory == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + Exynos_OSAL_Free(pMpeg4Dec); + pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + if (pMpeg4Dec != NULL) { + Exynos_OSAL_Free(pMpeg4Dec); + pMpeg4Dec = pVideoDec->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h new file mode 100644 index 0000000..a1b0706 --- /dev/null +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h @@ -0,0 +1,114 @@ +/* + * + * 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 Exynos_OMX_Mpeg4dec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_MPEG4_DEC_COMPONENT +#define EXYNOS_OMX_MPEG4_DEC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "ExynosVideoApi.h" + +/* Macros need for checking PackedPB */ +#define USR_DATA_START_CODE (0x000001B2) +#define VOP_START_CODE (0x000001B6) +#define MP4_START_CODE (0x000001) + +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 _EXYNOS_MFC_MPEG4DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + OMX_U32 maxDPBNum; + CODEC_TYPE codecType; + OMX_BOOL bPackedPB; + + ExynosVideoColorFormatType MFCOutputColorType; + ExynosVideoDecOps *pDecOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoGeometry codecOutbufConf; +} EXYNOS_MFC_MPEG4DEC_HANDLE; + +typedef struct _EXYNOS_MPEG4DEC_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]; + + /* EXYNOS MFC Codec specific */ + EXYNOS_MFC_MPEG4DEC_HANDLE hMFCMpeg4Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +} EXYNOS_MPEG4DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName); +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( + OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/mpeg4/Makefile.am b/openmax/component/video/dec/mpeg4/Makefile.am new file mode 100644 index 0000000..0de12e3 --- /dev/null +++ b/openmax/component/video/dec/mpeg4/Makefile.am @@ -0,0 +1,40 @@ +lib_LTLIBRARIES = libOMX.Exynos.M4V.Decoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_M4V_Decoder_la_SOURCES = Exynos_OMX_Mpeg4dec.c \ + Exynos_OMX_Mpeg4dec.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_M4V_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + +libOMX_Exynos_M4V_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + +if BOARD_USE_ANB +libOMX_Exynos_M4V_Decoder_la_CFLAGS += -DUSE_ANB +endif + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_M4V_Decoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_DMA_BUF +libOMX_Exynos_M4V_Decoder_la_CFLAGS += -DUSE_DMA_BUF +endif + + +libOMX_Exynos_M4V_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/dec/mpeg4/library_register.c b/openmax/component/video/dec/mpeg4/library_register.c new file mode 100644 index 0000000..d4f670d --- /dev/null +++ b/openmax/component/video/dec/mpeg4/library_register.c @@ -0,0 +1,64 @@ +/* + * + * 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 library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG4_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - video decoder MPEG4 */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DEC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video decoder H.263 */ + Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_H263_DEC); + Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_H263_DEC_ROLE); + ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} diff --git a/openmax/component/video/dec/mpeg4/library_register.h b/openmax/component/video/dec/mpeg4/library_register.h new file mode 100644 index 0000000..5af7840 --- /dev/null +++ b/openmax/component/video/dec/mpeg4/library_register.h @@ -0,0 +1,59 @@ +/* + * + * 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 library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_MPEG4_DEC_REG +#define EXYNOS_OMX_MPEG4_DEC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define EXYNOS_OMX_COMPONENT_MPEG4_DEC "OMX.Exynos.MPEG4.Decoder" +#define EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE "video_decoder.mpeg4" + +/* H.263 */ +#define EXYNOS_OMX_COMPONENT_H263_DEC "OMX.Exynos.H263.Decoder" +#define EXYNOS_OMX_COMPONENT_H263_DEC_ROLE "video_decoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/vc1/Android.mk b/openmax/component/video/dec/vc1/Android.mk new file mode 100644 index 0000000..f06eaab --- /dev/null +++ b/openmax/component/video/dec/vc1/Android.mk @@ -0,0 +1,48 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Wmvdec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.WMV.Decoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c new file mode 100644 index 0000000..b14d8e0 --- /dev/null +++ b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c @@ -0,0 +1,2815 @@ +/* + * + * 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 Exynos_OMX_Wmvdec.c + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + * : Support WMV3 (Vc-1 Simple/Main Profile) + * : Support WMvC1 (Vc-1 Advanced Profile) + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_Wmvdec.h" +#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_WMV_DEC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +#define WMV_DEC_NUM_OF_EXTRA_BUFFERS 7 + +//#define FULL_FRAME_SEARCH + +/* ASF parser does not send start code on Stagefright */ +#define WO_START_CODE +/* Enable or disable "WMV3_ADDITIONAL_START_CODE" based on MFC F/W's need */ +//#define WMV3_ADDITIONAL_START_CODE + +const OMX_U32 wmv3 = 0x33564d57; +const OMX_U32 wvc1 = 0x31435657; +const OMX_U32 wmva = 0x41564d57; + + +static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (addr != NULL) { + addr[0] = pCodecBuffer->planes[0].addr; + addr[1] = pCodecBuffer->planes[1].addr; + addr[2] = pCodecBuffer->planes[2].addr; + } + + if (size != NULL) { + size[0] = pCodecBuffer->planes[0].allocSize; + size[1] = pCodecBuffer->planes[1].allocSize; + size[2] = pCodecBuffer->planes[2].allocSize; + } + +EXIT: + return ret; +} + +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; + WMV_FORMAT gWvmFormat = WMV_FORMAT_UNKNOWN; + + Exynos_OSAL_Log(EXYNOS_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) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3"); + gWvmFormat = WMV_FORMAT_WMV3; + + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + else if ((compressionID == wvc1) || (compressionID == wmva)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1"); + gWvmFormat = WMV_FORMAT_VC1; + +#ifdef WO_START_CODE +/* ASF parser does not send start code on Stagefright */ + *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 Stagefright */ + 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; + + Exynos_OSAL_Log(EXYNOS_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; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +static OMX_BOOL Check_Stream_PrefixCode( + OMX_U8 *pInputStream, + OMX_U32 streamSize, + WMV_FORMAT wmvFormat) +{ + switch (wmvFormat) { + case WMV_FORMAT_WMV3: +#ifdef WMV3_ADDITIONAL_START_CODE + return OMX_FALSE; +#endif + if (streamSize > 0) + return OMX_TRUE; + else + return OMX_FALSE; + break; + case WMV_FORMAT_VC1: + /* TODO : for comformanc test based on common buffer scheme w/o parser */ + if (streamSize < 3) { + Exynos_OSAL_Log(EXYNOS_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 { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Cannot find prefix", __FUNCTION__); + return OMX_FALSE; + } + break; + + default: + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} + +static OMX_BOOL Make_Stream_MetaData( + OMX_U8 *pInputStream, + OMX_U32 *pStreamSize, + WMV_FORMAT wmvFormat +#ifdef SLP_PLATFORM + , OMX_U32 width, OMX_U32 height +#endif + ) +{ + OMX_U8 *pCurrBuf = pInputStream; + OMX_U32 currPos = 0; +#ifndef SLP_PLATFORM + OMX_U32 width, height; +#endif + 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) { +#ifndef SLP_PLATFORM + BitmapInfoHhr *pBitmapInfoHeader; + pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream; + + width = pBitmapInfoHeader->BiWidth; + height = pBitmapInfoHeader->BiHeight; +#endif + if (*pStreamSize > BITMAPINFOHEADER_SIZE) + Exynos_OSAL_Memcpy(struct_C, pInputStream+BITMAPINFOHEADER_SIZE, 4); + + Exynos_OSAL_Memcpy(pCurrBuf + currPos, const_C5, 4); + currPos +=4; + + Exynos_OSAL_Memcpy(pCurrBuf + currPos, const_04, 4); + currPos +=4; + + Exynos_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; + + Exynos_OSAL_Memcpy(pCurrBuf + currPos,const_0C, 4); + currPos +=4; + + Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_1, 4); + currPos +=4; + + Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_2, 4); + currPos +=4; + + Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_3, 4); + currPos +=4; + + *pStreamSize = currPos; + return OMX_TRUE; + } else { + Exynos_OSAL_Log(EXYNOS_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) { + Exynos_OSAL_Memcpy(pCurrBuf, pInputStream + BITMAPINFOHEADER_ASFBINDING_SIZE, *pStreamSize - BITMAPINFOHEADER_ASFBINDING_SIZE); + *pStreamSize -= BITMAPINFOHEADER_ASFBINDING_SIZE; + return OMX_TRUE; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize); + return OMX_FALSE; + } + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: It is not necessary to make bitstream metadata for wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} + +static OMX_BOOL Make_Stream_StartCode( + OMX_U8 *pInputStream, + OMX_U32 *pStreamSize, + WMV_FORMAT wmvFormat) +{ + OMX_U8 frameStartCode[4] = {0x00, 0x00, 0x01, 0x0d}; +#ifdef WMV3_ADDITIONAL_START_CODE + /* first 4 bytes : size of Frame, second 4 bytes : present Time stamp */ + OMX_U8 frameStartCode2[8] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; +#endif + OMX_U32 i; + + switch (wmvFormat) { + case WMV_FORMAT_WMV3: +#ifdef WMV3_ADDITIONAL_START_CODE + Exynos_OSAL_Memmove(pInputStream+8, pInputStream, *pStreamSize); + Exynos_OSAL_Memcpy(pInputStream, frameStartCode2, 8); + *pStreamSize += 8; +#endif + return OMX_TRUE; + break; + + case WMV_FORMAT_VC1: + /* Should find better way to shift data */ + Exynos_OSAL_Memmove(pInputStream+4, pInputStream, *pStreamSize); + Exynos_OSAL_Memcpy(pInputStream, frameStartCode, 4); + *pStreamSize += 4; + return OMX_TRUE; + break; + + default: + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat); + return OMX_FALSE; + break; + } +} + +OMX_ERRORTYPE Process_Wmv_CodecConfigData(OMX_COMPONENTTYPE *pOMXComponent, void *pConfig) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; +#ifdef SLP_PLATFORM + EXYNOS_OMX_DATABUFFER *pSrcInputData = (EXYNOS_OMX_DATA *)pConfig; + OMX_U8 *pInputStream = pSrcInputData->bufferHeader->pBuffer; +#endif + + FunctionIn(); + +#ifdef SLP_PLATFORM + if (pWmvDec->wmvFormat == WMV_FORMAT_UNKNOWN) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Process_Wmv_CodecConfigData. dataLen = %d", pSrcInputData->dataLen); + if (pSrcInputData->dataLen < 4) { + pWmvDec->wmvFormat = WMV_FORMAT_UNKNOWN; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_UNKNOWN"); + } else if ((pInputStream[1] == 0x00) && + (pInputStream[2] == 0x00) && + (pInputStream[3] == 0x01)) { + pWmvDec->wmvFormat = WMV_FORMAT_VC1; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1"); + } else { + pWmvDec->wmvFormat = WMV_FORMAT_WMV3; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3"); + } + } + + pWmvDec->hMFCWmvHandle.wmvFormat = pWmvDec->wmvFormat; +#else + BitmapInfoHhr *pBitmapInfoHeader; + pBitmapInfoHeader = (BitmapInfoHhr *)pConfig; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_BUFFERFLAG_CODECCONFIG"); + if (pBitmapInfoHeader->BiCompression == wmv3) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3"); + pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_WMV3; + } else if ((pBitmapInfoHeader->BiCompression == wvc1) || (pBitmapInfoHeader->BiCompression == wmva)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1"); + pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_VC1; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_UNKNOWN (0x%x), default value will be used", pBitmapInfoHeader->BiCompression); + } +#endif + ret = WmvCodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to WmvCodecSrcInit"); + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecOpen(EXYNOS_WMVDEC_HANDLE *pWmvDec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + enum v4l2_memory v4l2MemoryType = V4L2_MEMORY_USERPTR; + + FunctionIn(); + + if (pWmvDec == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps)); + pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); + + if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pWmvDec->hMFCWmvHandle.pDecOps = pDecOps; + pWmvDec->hMFCWmvHandle.pInbufOps = pInbufOps; + pWmvDec->hMFCWmvHandle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pDecOps->nSize = sizeof(ExynosVideoDecOps); + pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps); + + Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for decoder ops */ + if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || + (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || + (pDecOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + // For slp platform + if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) { +#ifdef USE_DMA_BUF + v4l2MemoryType = V4L2_MEMORY_DMABUF; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_DMABUF"); +#else + v4l2MemoryType = V4L2_MEMORY_USERPTR; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_USEPTR"); +#endif + } else { + v4l2MemoryType = V4L2_MEMORY_DMABUF; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_DMABUF"); + } + + /* alloc context, open, querycap */ + pWmvDec->hMFCWmvHandle.hMFCHandle = pWmvDec->hMFCWmvHandle.pDecOps->Init(v4l2MemoryType); + if (pWmvDec->hMFCWmvHandle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pWmvDec->hMFCWmvHandle.pDecOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pWmvDec->hMFCWmvHandle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pWmvDec->hMFCWmvHandle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecClose(EXYNOS_WMVDEC_HANDLE *pWmvDec) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pWmvDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + if (hMFCHandle != NULL) { + pDecOps->Finalize(hMFCHandle); + pWmvDec->hMFCWmvHandle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pWmvDec->hMFCWmvHandle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pWmvDec->hMFCWmvHandle.pInbufOps = NULL; + } + if (pDecOps != NULL) { + Exynos_OSAL_Free(pDecOps); + pWmvDec->hMFCWmvHandle.pDecOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + if (pWmvDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + if (pWmvDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE WmvCodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, plane; + + FunctionIn(); + + if (pVideoDec->bThumbnailMode == OMX_TRUE) + pDecOps->Set_DisplayDelay(hMFCHandle, 0); + + /* input buffer info */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_CODING_VC1_RCV"); + bufferConf.eCompressionFormat = VIDEO_CODING_VC1_RCV; + } else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_CODING_VC1"); + bufferConf.eCompressionFormat = VIDEO_CODING_VC1; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Unsupported WMV Codec Format Type"); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE + ||pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) + pInbufOps->Set_Shareable(hMFCHandle); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth + * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; + } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]; + plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0]; + plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE) { + ExynosVideoBuffer *pBuffer = NULL; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + /* get input buffer info */ + if (pInbufOps->Get_Buffer) { + if (pInbufOps->Get_Buffer(pWmvDec->hMFCWmvHandle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /* Register input buffer */ + for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { + ExynosVideoPlane plane; + plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; + if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + if (pWmvDec == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pWmvDec->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pWmvDec->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pWmvDec->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]); + + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pWmvDec->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); + nOutbufs += EXTRA_DPB_NUM; + for (i = 0; i < nOutbufs; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecDstFreeCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + + int i, j; + + FunctionIn(); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + } + + Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]); + } + } + + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer)); + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE WmvCodecDstAllocCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + + MEMORY_TYPE eMemoryType = NORMAL_MEMORY; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + nAllocLen[0] = calc_yplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth, + pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_uvplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth, + pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight >> 1); + + for (i = 0; i < nOutbufs; i++) { + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType); + if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pVideoDec->pMFCDecOutputBuffer[i]->fd[j] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]); + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j]; + } + } + + return OMX_ErrorNone; + +EXIT: + WmvCodecDstFreeCodecBuffers(pOMXComponent); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecDstRegistCodecBuffers( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nOutbufs) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int i, j; + + FunctionIn(); + + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) { + planes[j].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]; + planes[j].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[j]; + planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecResetupAllElement( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + int i, j, nOutbufs; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pWmvDec->bSourceStart == OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pWmvDec->bDestinationStart == OMX_TRUE)) { + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + + /**********************************/ + /* Codec Buffer Free & Unregister */ + /**********************************/ + WmvCodecDstFreeCodecBuffers(pOMXComponent); + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + + pOutbufOps->Cleanup(hMFCHandle); + /******************************************************/ + /* V4L2 Destnation Setup for DPB Buffer Number Change */ + /******************************************************/ + WmvCodecDstSetup(pOMXComponent); + + pVideoDec->bDRCProcessing = OMX_FALSE; + } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) { + + /**********************************/ + /* Codec Buffer Unregister */ + /**********************************/ + pOutbufOps->Clear_RegisteredBuffer(hMFCHandle); + pOutbufOps->Cleanup(hMFCHandle); + } + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + OMX_BOOL bMetaData = OMX_FALSE; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE)) { + if (pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + BitmapInfoHhr *pBitmapInfoHeader; + pBitmapInfoHeader = (BitmapInfoHhr *)pSrcInputData->buffer.singlePlaneBuffer.dataBuffer; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_BUFFERFLAG_CODECCONFIG"); + if (pBitmapInfoHeader->BiCompression == wmv3) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "WMV_FORMAT_WMV3"); + pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_WMV3; + } else if ((pBitmapInfoHeader->BiCompression == wvc1) || (pBitmapInfoHeader->BiCompression == wmva)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "WMV_FORMAT_VC1"); + pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_VC1; + } + } + + ret = WmvCodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + + /* set output geometry */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + bMetaData = Make_Stream_MetaData(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat +#ifdef SLP_PLATFORM + , pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.nFrameWidth + , pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.nFrameHeight +#endif + ); + if (bMetaData == OMX_FALSE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream MetaData"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* input buffer enqueue for header parsing */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); + if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); +// ret = OMX_ErrorInsufficientResources; + ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; + goto EXIT; + } + + /* start header parsing */ + if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + ret = WmvCodecCheckResolutionChange(pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorCodecInit; + goto EXIT; + } + + Exynos_OSAL_SleepMillisec(0); + ret = OMX_ErrorInputDataDecodeYet; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); +#endif +EXIT: + WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX); + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + int i, nOutbufs; + + FunctionIn(); + + /* get dpb count */ + nOutbufs = pWmvDec->hMFCWmvHandle.maxDPBNum; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE + ||pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) + pOutbufOps->Set_Shareable(hMFCHandle); + + if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; + OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + int plane; + + nAllocLen[0] = calc_yplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth, + pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight); + nAllocLen[1] = calc_uvplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth, + pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight >> 1); + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) { + WmvCodecDstAllocCodecBuffers(pOMXComponent, nOutbufs); + WmvCodecDstRegistCodecBuffers(pOMXComponent, nOutbufs); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY && + pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE) { + /* Register output buffer */ + for (i = 0; i < nOutbufs; i++) { + int plane; + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + + if (pOutbufOps->Get_Buffer) { + if (pOutbufOps->Get_Buffer(pWmvDec->hMFCWmvHandle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { +#ifdef USE_PB + if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) { + for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; + planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].allocSize = nAllocLen[plane]; + } + + if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } else { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } +#else + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + } + + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + WmvCodecStop (pOMXComponent, OUTPUT_PORT_INDEX); + } + pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE WmvCodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoGeometry bufferConf; + int i; + + FunctionIn(); + + /* get geometry for output */ + Exynos_OSAL_Memset(&pWmvDec->hMFCWmvHandle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pWmvDec->hMFCWmvHandle.codecOutbufConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* get dpb count */ + pWmvDec->hMFCWmvHandle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pWmvDec->hMFCWmvHandle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WmvCodecCheckResolutionChange WmvCodecSetup nOutbufs: %d", pWmvDec->hMFCWmvHandle.maxDPBNum); + + pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_TRUE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVideoDec->bDRCProcessing) || + (pExynosInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) || + (pExynosInputPort->portDefinition.format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight) || + (pExynosOutputPort->portDefinition.nBufferCountActual != pWmvDec->hMFCWmvHandle.maxDPBNum)) { + pExynosInputPort->portDefinition.format.video.nFrameWidth = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth; + pExynosInputPort->portDefinition.format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight; + pExynosInputPort->portDefinition.format.video.nStride = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight + 15) & (~15)); + + if (pVideoDec->bDRCProcessing == OMX_TRUE) { + pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual; + } +#ifdef SLP_PLATFORM + pExynosOutputPort->portDefinition.nBufferCountActual = pWmvDec->hMFCWmvHandle.maxDPBNum; + pExynosOutputPort->portDefinition.nBufferCountMin = pWmvDec->hMFCWmvHandle.maxDPBNum; +#else + pExynosOutputPort->portDefinition.nBufferCountActual = pWmvDec->hMFCWmvHandle.maxDPBNum - 4; + pExynosOutputPort->portDefinition.nBufferCountMin = pWmvDec->hMFCWmvHandle.maxDPBNum - 4; +#endif + Exynos_UpdateFrameSize(pOMXComponent); + pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; + + /** Send Port Settings changed call back **/ + (*(pExynosComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pExynosComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + ret = Exynos_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 = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcWmvParam = &pWmvDec->WmvComponent[pDstWmvParam->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_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; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + ret = Exynos_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 = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + ret = Exynos_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 = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstWmvParam = &pWmvDec->WmvComponent[pSrcWmvParam->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE)) { + pExynosComponent->pExynosPort[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; + EXYNOS_OMX_BASEPORT *pExynosPort; + OMX_U32 width, height, size; + OMX_U32 realWidth, realHeight; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition_backup; + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize); + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup); + + realWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + realHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + width = ((realWidth + 15) & (~15)); + height = ((realHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pExynosPort->portDefinition.format.video.nStride = width; + pExynosPort->portDefinition.format.video.nSliceHeight = height; + pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth; + pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight; + pExynosOutputPort->portDefinition.format.video.nStride = width; + pExynosOutputPort->portDefinition.format.video.nSliceHeight = height; + + switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; +#ifdef SLP_PLATFORM /* NV12T fd */ + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + break; +#endif + case OMX_SEC_COLOR_FormatNV12Tiled: + pExynosOutputPort->portDefinition.nBufferSize = + calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + break; + default: + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + pExynosOutputPort->portDefinition.nBufferSize = + calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) + + calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1); + } + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + ret = Exynos_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 = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + *pIndexType = OMX_IndexVendorThumbnailMode; + ret = OMX_ErrorNone; + } else { + ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_ComponentRoleEnum( + OMX_HANDLETYPE hComponent, + OMX_U8 *cRole, + OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = NULL; + ExynosVideoDecBufferOps *pInbufOps = NULL; + ExynosVideoDecBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i, plane; + + FunctionIn(); + + pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE; + pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + /* WMV Codec Open */ + ret = WmvCodecOpen(pWmvDec); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + /* Use ION Allocator */ + pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY); + pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); + } + } else { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pWmvDec->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pWmvDec->hSourceStartEvent); + pWmvDec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pWmvDec->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pWmvDec->hMFCWmvHandle.indexTimestamp = 0; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0; + /* Default WMV codec format is set as VC1*/ + pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_WMV3;//WMV_FORMAT_VC1; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + pVideoDec->csc_handle = csc_init(csc_method); + if (pVideoDec->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoDec->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + + int i, plane; + + FunctionIn(); + + if (pVideoDec->csc_handle != NULL) { + csc_deinit(pVideoDec->csc_handle); + pVideoDec->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationStartEvent); + pWmvDec->hDestinationStartEvent = NULL; + pWmvDec->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pWmvDec->hSourceStartEvent); + pWmvDec->hSourceStartEvent = NULL; + pWmvDec->bSourceStart = OMX_FALSE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + WmvCodecDstFreeCodecBuffers(pOMXComponent); + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoDec->pMFCDecInputBuffer[i] != NULL) { + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); + pVideoDec->pMFCDecInputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + WmvCodecClose(pWmvDec); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + OMX_BOOL bStartCode = OMX_FALSE; + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) { + ret = WmvCodecSrcSetup(pOMXComponent, pSrcInputData); + goto EXIT; + } + if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE) { + ret = WmvCodecDstSetup(pOMXComponent); + } + + bStartCode = Check_Stream_PrefixCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bStartCode == OMX_FALSE && ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + if (pSrcInputData->allocSize < oneFrameSize+4) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can't attach startcode due to lack of buffer space"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + + bStartCode = Make_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat); + if (bStartCode == OMX_FALSE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream Start Code"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + } + + if ((bStartCode == OMX_TRUE) || ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){ + pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pWmvDec->hMFCWmvHandle.indexTimestamp, pSrcInputData->nFlags); + pDecOps->Set_FrameTag(hMFCHandle, pWmvDec->hMFCWmvHandle.indexTimestamp); + pWmvDec->hMFCWmvHandle.indexTimestamp++; + pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP; + +#ifdef USE_IMMEDIATE_DISPLAY + /* Set Immediately display for I Frame*/ + if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) { + /* Enable Immediately display After seek*/ + pDecOps->Set_ImmediateDisplay(hMFCHandle); + pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE; + } + } +#endif + + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + if (codecReturn != VIDEO_ERROR_NONE) { + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + goto EXIT; + } + WmvCodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pWmvDec->bSourceStart == OMX_FALSE) { + pWmvDec->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pWmvDec->bDestinationStart == OMX_FALSE) { + pWmvDec->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + i++; + } + pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + OMX_U32 dataLen[2] = {0,}; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); + + if ((pVideoDec->bDRCProcessing == OMX_TRUE) && + (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) && + (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) { + ret = WmvCodecDstSetup(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig CodecDstSetup Failed"); + goto EXIT; + } + pVideoDec->bDRCProcessing = OMX_FALSE; + } + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + WmvCodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry *bufferGeometry; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + OMX_S32 indexTimestamp = 0; + int plane; + + FunctionIn(); + + if (pWmvDec->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + while (1) { + pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle); + if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available"); + ret = OMX_ErrorHardware; + goto EXIT; + } + + if (pVideoBuffer == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + displayStatus = pVideoBuffer->displayStatus; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus); + + if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || + (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + if (pVideoBuffer != NULL) { + ret = OMX_ErrorNone; + break; + } else { + ret = OMX_ErrorUndefined; + break; + } + } + } + + if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) { + if (pVideoDec->bDRCProcessing != OMX_TRUE) { + pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; + pVideoDec->bDRCProcessing = OMX_TRUE; + WmvCodecCheckResolutionChange(pOMXComponent); + pVideoDec->csc_set_format = OMX_FALSE; + } + ret = OMX_ErrorNone; + goto EXIT; + } + + pWmvDec->hMFCWmvHandle.outputIndexTimestamp++; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->allocSize = pDstOutputData->dataLen = 0; + for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { + pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; + pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; + } + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; + bufferGeometry = &pWmvDec->hMFCWmvHandle.codecOutbufConf; + pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; + pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + switch (bufferGeometry->eColorFormat) { + case VIDEO_COLORFORMAT_NV12: +#ifdef SLP_PLATFORM /* NV12T fd */ + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#else + pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#endif + break; + case VIDEO_COLORFORMAT_NV12_TILED: + default: + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + break; + } + + indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) && + (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp); + } else { + pDstOutputData->timeStamp = 0x00; + pDstOutputData->nFlags = 0x00; + } + } else { + /* For timestamp correction. if mfc support frametype detect */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType); + +//#ifdef NEED_TIMESTAMP_REORDER + if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) { /* SLP_PLATFORM */ + if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp]; + } +//#else + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; +//#endif + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags); + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } else { + pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_WmvDec_SrcIn(pOMXComponent, pSrcInputData); + if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pWmvDec->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pWmvDec->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pWmvDec->hSourceStartEvent); + } + + ret = Exynos_WmvDec_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pWmvDec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent); + } + } + if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_WmvDec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pWmvDec->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent); + } + } + ret = Exynos_WmvDec_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && + (pExynosComponent->currentState == OMX_StateExecuting)) { + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + OMX_S32 wmvFormat = WMV_FORMAT_UNKNOWN; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_DEC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pWmvDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_WMVDEC_HANDLE)); + if (pWmvDec == NULL) { + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pWmvDec, 0, sizeof(EXYNOS_WMVDEC_HANDLE)); + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec; + pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat; + + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_WMV_DEC); + + /* In case of BUFFER_COPY mode + bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR + bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP + In case of BUFFER_SHARE + bShareableBuf should be TRUE, FALSE is ignored + */ + pWmvDec->hMFCWmvHandle.bShareableBuf = OMX_FALSE; + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/wmv"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; +#ifdef SLP_PLATFORM + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#else + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; +#endif + pExynosPort->portDefinition.bEnabled = OMX_TRUE; +#ifdef SLP_PLATFORM + pExynosPort->bufferProcessType = BUFFER_SHARE; +#else + pExynosPort->bufferProcessType = BUFFER_COPY; +#endif + pExynosPort->portWayType = WAY2_PORT; + + 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; + } + +#ifdef SLP_PLATFORM + pWmvDec->wmvFormat = WMV_FORMAT_UNKNOWN; +#endif + + pOMXComponent->GetParameter = &Exynos_WmvDec_GetParameter; + pOMXComponent->SetParameter = &Exynos_WmvDec_SetParameter; + pOMXComponent->GetConfig = &Exynos_WmvDec_GetConfig; + pOMXComponent->SetConfig = &Exynos_WmvDec_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_WmvDec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_WmvDec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_WmvDec_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_WmvDec_Terminate; + + pVideoDec->exynos_codec_srcInputProcess = &Exynos_WmvDec_srcInputBufferProcess; + pVideoDec->exynos_codec_srcOutputProcess = &Exynos_WmvDec_srcOutputBufferProcess; + pVideoDec->exynos_codec_dstInputProcess = &Exynos_WmvDec_dstInputBufferProcess; + pVideoDec->exynos_codec_dstOutputProcess = &Exynos_WmvDec_dstOutputBufferProcess; + + pVideoDec->exynos_codec_start = &WmvCodecStart; + pVideoDec->exynos_codec_stop = &WmvCodecStop; + pVideoDec->exynos_codec_bufferProcessRun = &WmvCodecOutputBufferProcessRun; + pVideoDec->exynos_codec_enqueueAllBuffer = &WmvCodecEnQueueAllBuffer; + pVideoDec->exynos_codec_resetupAllElement = &WmvCodecResetupAllElement; + + pVideoDec->exynos_checkInputFrame = &Check_Wmv_Frame; + pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + + pVideoDec->exynos_process_codecConfigData = &Process_Wmv_CodecConfigData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoDec->hSharedMemory == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + Exynos_OSAL_Free(pWmvDec); + pWmvDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( + OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle; + if (pWmvDec != NULL) { + Exynos_OSAL_Free(pWmvDec); + pWmvDec = pVideoDec->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h new file mode 100644 index 0000000..d944208 --- /dev/null +++ b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h @@ -0,0 +1,119 @@ +/* + * + * 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 Exynos_OMX_Wmvdec.h + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#ifndef EXYNOS_OMX_WMV_DEC_COMPONENT +#define EXYNOS_OMX_WMV_DEC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "ExynosVideoApi.h" + +#ifdef SLP_PLATFORM +#define BITMAPINFOHEADER_SIZE 0 +#define BITMAPINFOHEADER_ASFBINDING_SIZE 1 +#else +#define BITMAPINFOHEADER_SIZE 40 +#define BITMAPINFOHEADER_ASFBINDING_SIZE 41 +#endif +#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 _EXYNOS_MFC_WMVDEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + OMX_U32 maxDPBNum; + WMV_FORMAT wmvFormat; + + ExynosVideoColorFormatType MFCOutputColorType; + ExynosVideoDecOps *pDecOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoGeometry codecOutbufConf; +} EXYNOS_MFC_WMVDEC_HANDLE; + +typedef struct _EXYNOS_WMVDEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_WMVTYPE WmvComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* EXYNOS MFC Codec specific */ + EXYNOS_MFC_WMVDEC_HANDLE hMFCWmvHandle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +#ifdef SLP_PLATFORM + WMV_FORMAT wmvFormat; +#endif +} EXYNOS_WMVDEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName); +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( + OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/dec/vc1/Makefile.am b/openmax/component/video/dec/vc1/Makefile.am new file mode 100644 index 0000000..d3636bc --- /dev/null +++ b/openmax/component/video/dec/vc1/Makefile.am @@ -0,0 +1,40 @@ +lib_LTLIBRARIES = libOMX.Exynos.WMV.Decoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_WMV_Decoder_la_SOURCES = Exynos_OMX_Wmvdec.c \ + Exynos_OMX_Wmvdec.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_WMV_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + +libOMX_Exynos_WMV_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + +if BOARD_USE_ANB +libOMX_Exynos_WMV_Decoder_la_CFLAGS += -DUSE_ANB +endif + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_WMV_Decoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_DMA_BUF +libOMX_Exynos_WMV_Decoder_la_CFLAGS += -DUSE_DMA_BUF +endif + + +libOMX_Exynos_WMV_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/dec/vc1/library_register.c b/openmax/component/video/dec/vc1/library_register.c new file mode 100644 index 0000000..dd8942e --- /dev/null +++ b/openmax/component/video/dec/vc1/library_register.c @@ -0,0 +1,58 @@ +/* + * + * 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 library_register.c + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_WMV_DEC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - video decoder WMV */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_WMV_DEC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} \ No newline at end of file diff --git a/openmax/component/video/dec/vc1/library_register.h b/openmax/component/video/dec/vc1/library_register.h new file mode 100644 index 0000000..0cd5ab2 --- /dev/null +++ b/openmax/component/video/dec/vc1/library_register.h @@ -0,0 +1,54 @@ +/* + * + * 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 library_register.h + * @brief + * @author HyeYeon Chung (hyeon.chung@samsung.com) + * @author Satish Kumar Reddy (palli.satish@samsung.com) + * @version 2.0.0 + * @history + * 2012.07.10 : Create + */ + +#ifndef EXYNOS_OMX_WMV_DEC_REG +#define EXYNOS_OMX_WMV_DEC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* WMV */ +#define EXYNOS_OMX_COMPONENT_WMV_DEC "OMX.Exynos.WMV.Decoder" +#define EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE "video_decoder.wmv" + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register( + ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/openmax/component/video/enc/Android.mk b/openmax/component/video/enc/Android.mk new file mode 100644 index 0000000..dd168c9 --- /dev/null +++ b/openmax/component/video/enc/Android.mk @@ -0,0 +1,47 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + Exynos_OMX_VencControl.c \ + Exynos_OMX_Venc.c + +LOCAL_MODULE := libExynosOMX_Venc +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/enc \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_CFLAGS += -DUSE_ANB +endif + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +ifeq ($(BOARD_USE_STOREMETADATA), true) +LOCAL_CFLAGS += -DUSE_STOREMETADATA +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_SHARED_LIBRARIES := libcsc + +include $(BUILD_STATIC_LIBRARY) diff --git a/openmax/component/video/enc/Exynos_OMX_Venc.c b/openmax/component/video/enc/Exynos_OMX_Venc.c new file mode 100644 index 0000000..afd3c4e --- /dev/null +++ b/openmax/component/video/enc/Exynos_OMX_Venc.c @@ -0,0 +1,1167 @@ +/* + * + * 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 Exynos_OMX_Venc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OMX_Venc.h" +#include "Exynos_OMX_VencControl.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" +#include "ExynosVideoApi.h" +#include "csc.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + + +inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + if ((exynosOutputPort->portDefinition.format.video.nFrameWidth != + exynosInputPort->portDefinition.format.video.nFrameWidth) || + (exynosOutputPort->portDefinition.format.video.nFrameHeight != + exynosInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + exynosOutputPort->portDefinition.format.video.nFrameWidth = + exynosInputPort->portDefinition.format.video.nFrameWidth; + exynosOutputPort->portDefinition.format.video.nFrameHeight = + exynosInputPort->portDefinition.format.video.nFrameHeight; + width = exynosOutputPort->portDefinition.format.video.nStride = + exynosInputPort->portDefinition.format.video.nStride; + height = exynosOutputPort->portDefinition.format.video.nSliceHeight = + exynosInputPort->portDefinition.format.video.nSliceHeight; + + if (width && height) + exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + } + + return; +} + +OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) +{ + OMX_BOOL ret = OMX_FALSE; + + if ((pExynosComponent->currentState == OMX_StateExecuting) && + (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) { + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + + return ret; +} + +OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + CODEC_ENC_BUFFER *pInputCodecBuffer = (CODEC_ENC_BUFFER*)codecBuffer; + + pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0]; + pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1]; + pData->allocSize = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1]; + pData->dataLen = pInputCodecBuffer->dataSize; + pData->usedDataLen = 0; + pData->remainDataLen = pInputCodecBuffer->dataSize; + + pData->nFlags = 0; + pData->timeStamp = 0; + pData->pPrivate = codecBuffer; + pData->bufferHeader = NULL; + + return ret; +} + +OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + OMX_PTR pSrcBuf; + OMX_U32 allocSize; + + pVideoEnc->exynos_codec_getCodecOutputPrivateData(codecBuffer, &pSrcBuf, &allocSize); + pData->buffer.singlePlaneBuffer.dataBuffer = pSrcBuf; + pData->allocSize = allocSize; + pData->dataLen = 0; + pData->usedDataLen = 0; + pData->remainDataLen = 0; + + pData->nFlags = 0; + pData->timeStamp = 0; + pData->pPrivate = codecBuffer; + pData->bufferHeader = NULL; + + return ret; +} + +void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) +{ + EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL; + + FunctionIn(); + + exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (((pExynosComponent->currentState == OMX_StatePause) || + (pExynosComponent->currentState == OMX_StateIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) || + (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) && + (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) && + (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) { + Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent); + } + + FunctionOut(); + + return; +} + +OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; + OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; + OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + OMX_BYTE checkInputStream = NULL; + OMX_BOOL flagEOS = OMX_FALSE; + + FunctionIn(); + + checkInputStream = inputUseBuffer->bufferHeader->pBuffer; + + CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate; + codecInputBuffer->dataSize = ((nFrameWidth * nFrameHeight) * 3) / 2; + + unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); + CSC_METHOD csc_method = CSC_METHOD_SW; + unsigned int cacheable = 1; + + unsigned char *pSrcBuf[3] = {NULL, }; + unsigned char *pDstBuf[3] = {NULL, }; + + CSC_ERRORCODE cscRet = CSC_ErrorNone; + + pSrcBuf[0] = checkInputStream; + pSrcBuf[1] = checkInputStream + (nFrameWidth * nFrameHeight); + pSrcBuf[2] = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4); + + pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]; + pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]; + pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2]; + + csc_get_method(pVideoEnc->csc_handle, &csc_method); + if (csc_method == CSC_METHOD_HW) { + pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.fd[0]; + pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.fd[1]; + pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.fd[2]; + } + +#ifdef USE_METADATABUFFERTYPE + OMX_PTR ppBuf[MAX_BUFFER_PLANE]; + + /* kMetadataBufferTypeGrallocSource */ + if (exynosInputPort->bStoreMetaData == OMX_TRUE) { + /* ARGB8888 converted to YUV420SemiPlanar */ + 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); + + Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + OMX_U32 stride; + int imageSize; + + Exynos_OSAL_LockPB((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, &stride, planes); + imageSize = nFrameWidth * nFrameHeight * 3; /* RGB888 */ +#ifdef USE_DMA_BUF + if (csc_method == CSC_METHOD_HW) + pSrcBuf[0] = (unsigned char *)planes[0].fd; + else +#endif + pSrcBuf[0] = planes[0].addr; + pSrcBuf[1] = NULL; + pSrcBuf[2] = NULL; + } + } else +#endif + { +#ifdef USE_DMA_BUF + if (csc_method == CSC_METHOD_HW) { + pSrcBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream); + pSrcBuf[1] = NULL; + pSrcBuf[2] = NULL; + } +#endif + + switch (eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per 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: + /* Just copied to MFC input buffer */ + 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; + } + } + + csc_set_src_format( + pVideoEnc->csc_handle, /* handle */ + nFrameWidth, /* width */ + nFrameHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nFrameWidth, /* crop_width */ + nFrameHeight, /* crop_height */ + csc_src_color_format, /* color_format */ + cacheable); /* cacheable */ + csc_set_dst_format( + pVideoEnc->csc_handle, /* handle */ + nFrameWidth, /* width */ + nFrameHeight, /* height */ + 0, /* crop_left */ + 0, /* crop_right */ + nFrameWidth, /* crop_width */ + nFrameHeight, /* 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 */ + cscRet = csc_convert(pVideoEnc->csc_handle); + if (cscRet != CSC_ErrorNone) + ret = OMX_FALSE; + else + ret = OMX_TRUE; + +#ifdef USE_METADATABUFFERTYPE + if (exynosInputPort->bStoreMetaData == OMX_TRUE) { + Exynos_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]); + } +#endif + + ret = OMX_TRUE; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; + OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; + OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_BOOL flagEOS = OMX_FALSE; + + FunctionIn(); + + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + if ((srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || + (srcInputData->pPrivate == NULL)) { + ret = OMX_FALSE; + goto EXIT; + } + } + + if (inputUseBuffer->dataValid == OMX_TRUE) { + if (exynosInputPort->bufferProcessType & BUFFER_SHARE) { + Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE); +#ifdef USE_METADATABUFFERTYPE + if (exynosInputPort->bStoreMetaData == OMX_TRUE) { + OMX_PTR ppBuf[MAX_BUFFER_PLANE]; + OMX_PTR allocSize[MAX_BUFFER_PLANE]; + int plane = 0; + + /* kMetadataBufferTypeCameraSource */ + Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); +#ifdef USE_DMA_BUF + srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0]; + srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1]; + allocSize[0] = nFrameWidth * nFrameHeight; + allocSize[1] = nFrameWidth * nFrameHeight >> 1; + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = + Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); + if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = + Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); + } + } + /* input buffers are 2 plane. */ + srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; + srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; +#else + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = ppBuf[plane]; + } + srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; +#endif + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[1]); + } +#else // for Tizen Camera scenario + SCMN_IMGB *pscmn_Imgb = (SCMN_IMGB*)inputUseBuffer->bufferHeader->pBuffer; + int plane = 0; + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pscmn_Imgb->a[plane]; + srcInputData->buffer.multiPlaneBuffer.fd[plane] = pscmn_Imgb->fd[plane]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[ENC] get fd[%d] %d , a[%d] %x " + , plane, srcInputData->buffer.multiPlaneBuffer.fd[plane], plane, srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] ); + } + + + + /* input buffers are 2 plane. */ + srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; + srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; +#endif + /* reset dataBuffer */ + Exynos_ResetDataBuffer(inputUseBuffer); + } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + pExynosComponent->bUseFlagEOF = OMX_TRUE; + + if (checkInputStreamLen == 0) { + inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOS = OMX_TRUE; + } + + copySize = checkInputStreamLen; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE"); + + if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) { + Exynos_CSC_InputData(pOMXComponent, srcInputData); + + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + srcInputData->dataLen += copySize; + srcInputData->remainDataLen += copySize; + + srcInputData->timeStamp = inputUseBuffer->timeStamp; + srcInputData->nFlags = inputUseBuffer->nFlags; + srcInputData->bufferHeader = inputUseBuffer->bufferHeader; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ret = OMX_FALSE; + } + +#ifndef SLP_PLATFORM + if (((exynosInputPort->bStoreMetaData == OMX_TRUE) && (eColorFormat == OMX_COLOR_FormatAndroidOpaque)) || + (exynosInputPort->bStoreMetaData == OMX_FALSE)) +#else + if (exynosInputPort->bStoreMetaData == OMX_FALSE) +#endif + { + Exynos_InputBufferReturn(pOMXComponent); + } else { + inputUseBuffer->dataValid = OMX_TRUE; + } + } + + if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE"); + srcInputData->dataLen = 0; + srcInputData->remainDataLen = 0; + pExynosComponent->bSaveFlagEOS = OMX_TRUE; + } + + if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp; + pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", + srcInputData->timeStamp, srcInputData->timeStamp / 1E6); + } + + ret = OMX_TRUE; + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData) +{ + OMX_BOOL ret = OMX_FALSE; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + OMX_U32 copySize = 0; + + FunctionIn(); + + if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone) + outputUseBuffer->dataValid = OMX_TRUE; + } + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if (pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp){ + pExynosComponent->checkTimeStamp.startTimeStamp = -19761123; + pExynosComponent->checkTimeStamp.nStartFlags = 0x0; + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "drop frame after seeking"); + ret = OMX_TRUE; + goto EXIT; + } + } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + ret = OMX_TRUE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestamp after seeking"); + goto EXIT; + } + + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + if (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = dstOutputData->remainDataLen; + if (copySize > 0) + Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (dstOutputData->buffer.singlePlaneBuffer.dataBuffer + dstOutputData->usedDataLen), + copySize); + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = dstOutputData->nFlags; + outputUseBuffer->timeStamp = dstOutputData->timeStamp; + + ret = OMX_TRUE; + + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + Exynos_OutputBufferReturn(pOMXComponent); + } + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than encoded data size Out Length"); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ret = OMX_FALSE; + } + } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((outputUseBuffer->remainDataLen > 0) || + ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || + (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) + Exynos_OutputBufferReturn(pOMXComponent); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; + EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; + OMX_BOOL bCheckInputData = OMX_FALSE; + OMX_BOOL bValidCodecData = OMX_FALSE; + + FunctionIn(); + + while (!pVideoEnc->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) && + (!pVideoEnc->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) + break; + if (exynosInputPort->portState != OMX_StateIdle) + break; + + Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex); + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + if ((pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) { + Exynos_CodecBufferDequeue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer); + if (codecBuffer != NULL) { + Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData); + } + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + } + + if (srcInputUseBuffer->dataValid == OMX_TRUE) { + bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData); + } else { + bCheckInputData = OMX_FALSE; + } + + if ((bCheckInputData == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { + ret = Exynos_InputBufferGetQueue(pExynosComponent); + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + + if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) { + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + break; + } + + ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData); + Exynos_ResetCodecData(pSrcInputData); + Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); + if (ret == OMX_ErrorCodecInit) + pVideoEnc->bExitBufferProcessThread = OMX_TRUE; + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer; + EXYNOS_OMX_DATA srcOutputData; + + FunctionIn(); + + while (!pVideoEnc->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + + while (!pVideoEnc->bExitBufferProcessThread) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE) + break; + } + Exynos_OSAL_SleepMillisec(0); + + if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) + break; + + Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex); + ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData); + + if (ret == OMX_ErrorNone) { + if (exynosInputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + codecBuffer = srcOutputData.pPrivate; + if (codecBuffer != NULL) + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer); + } + if (exynosInputPort->bufferProcessType & BUFFER_SHARE) { + Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer); + Exynos_InputBufferReturn(pOMXComponent); + } + Exynos_ResetCodecData(&srcOutputData); + } + Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer; + EXYNOS_OMX_DATA dstInputData; + + FunctionIn(); + + while (!pVideoEnc->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && + (!pVideoEnc->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) || + (!CHECK_PORT_POPULATED(exynosOutputPort))) + break; + if (exynosOutputPort->portState != OMX_StateIdle) + break; + + Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex); + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + ret = Exynos_CodecBufferDequeue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData); + } + + if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((dstInputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + ret = Exynos_OutputBufferGetQueue(pExynosComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE); + Exynos_ResetDataBuffer(dstInputUseBuffer); + } + } + + if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) { + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + break; + } + ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData); + + Exynos_ResetCodecData(&dstInputData); + Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; + EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData; + + FunctionIn(); + + while (!pVideoEnc->bExitBufferProcessThread) { + Exynos_OSAL_SleepMillisec(0); + Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX); + + while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && + (!pVideoEnc->bExitBufferProcessThread)) { + Exynos_OSAL_SleepMillisec(0); + + if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) + break; + + Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex); + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((dstOutputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { + ret = Exynos_OutputBufferGetQueue(pExynosComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); + break; + } + } + } + + if ((dstOutputUseBuffer->dataValid == OMX_TRUE) || + (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) + ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData); + + if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) || + (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) { + Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData); + } + + if (exynosOutputPort->bufferProcessType & BUFFER_COPY) { + OMX_PTR codecBuffer; + codecBuffer = pDstOutputData->pPrivate; + if (codecBuffer != NULL) { + Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer); + pDstOutputData->pPrivate = NULL; + } + } + + /* reset outputData */ + Exynos_ResetCodecData(pDstOutputData); + Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); + } + } + +EXIT: + + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_SrcInputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_SrcOutputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_DstInputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + Exynos_OMX_DstOutputBufferProcess(pOMXComponent); + + Exynos_OSAL_ThreadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + FunctionIn(); + + pVideoEnc->bExitBufferProcessThread = OMX_FALSE; + + ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread, + Exynos_OMX_DstOutputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread, + Exynos_OMX_SrcOutputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread, + Exynos_OMX_DstInputProcessThread, + pOMXComponent); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread, + Exynos_OMX_SrcInputProcessThread, + pOMXComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + OMX_S32 countValue = 0; + unsigned int i = 0; + + FunctionIn(); + + pVideoEnc->bExitBufferProcessThread = OMX_TRUE; + + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID); + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread); + pVideoEnc->hSrcInputThread = NULL; + + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID); + Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue); + if (countValue == 0) + Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread); + pVideoEnc->hDstInputThread = NULL; + + pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX); + pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread); + pVideoEnc->hSrcOutputThread = NULL; + + pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX); + pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); + Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); + Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread); + pVideoEnc->hDstOutputThread = NULL; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = Exynos_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); + if (pVideoEnc == NULL) { + Exynos_OMX_BaseComponent_Destructor(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); + pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; + + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + pVideoEnc->configChange = OMX_FALSE; + pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter + pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter + pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter + + pExynosComponent->bMultiThreadProcess = OMX_TRUE; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = 0; + pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pExynosPort->portDefinition.format.video.nFrameWidth = 0; + pExynosPort->portDefinition.format.video.nFrameHeight= 0; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.format.video.pNativeWindow = NULL; + pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; + + pExynosPort->bStoreMetaData = OMX_FALSE; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pExynosPort->portDefinition.format.video.nFrameWidth = 0; + pExynosPort->portDefinition.format.video.nFrameHeight= 0; + pExynosPort->portDefinition.format.video.nStride = 0; + pExynosPort->portDefinition.format.video.nSliceHeight = 0; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.format.video.pNativeWindow = NULL; + pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; + + pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest; + + pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer; + pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer; + pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create; + pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; + pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_Free(pVideoEnc); + pExynosComponent->hComponentHandle = pVideoEnc = NULL; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pExynosPort = &pExynosComponent->pExynosPort[i]; + Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType); + pExynosPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = Exynos_OMX_Port_Destructor(pOMXComponent); + + ret = Exynos_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/enc/Exynos_OMX_Venc.h b/openmax/component/video/enc/Exynos_OMX_Venc.h new file mode 100644 index 0000000..4cdba14 --- /dev/null +++ b/openmax/component/video/enc/Exynos_OMX_Venc.h @@ -0,0 +1,153 @@ +/* + * + * 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 Exynos_OMX_Venc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_VIDEO_ENCODE +#define EXYNOS_OMX_VIDEO_ENCODE + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_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_16B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_16B(DEFAULT_FRAME_HEIGHT) + \ + ALIGN((ALIGN_TO_16B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_16B(DEFAULT_FRAME_HEIGHT))/2,256)) +#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2 + +#define MFC_INPUT_BUFFER_NUM_MAX 3 +#define MFC_OUTPUT_BUFFER_NUM_MAX 4 + +#define DEFAULT_MFC_INPUT_YBUFFER_SIZE ALIGN_TO_16B(1920) * ALIGN_TO_16B(1080) +#define DEFAULT_MFC_INPUT_CBUFFER_SIZE ALIGN((DEFAULT_MFC_INPUT_YBUFFER_SIZE / 2), 256) +#define DEFAULT_MFC_OUTPUT_BUFFER_SIZE 1920 * 1080 * 3 / 2 + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 7 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 + +#define MFC_INPUT_BUFFER_PLANE 2 +#define MFC_OUTPUT_BUFFER_PLANE 1 + +#ifdef SLP_PLATFORM +/* FIXME: for camera slow motion 12 buffer and eos issue, we increase this value */ +/* FIXME: for trim small resolution video. dec + enc case */ +#define MAX_CAMERA_INPUTBUFFER_NUM 25 /* number of metadata buffer */ +#else +#define MAX_CAMERA_INPUTBUFFER_NUM 12 /* number of metadata buffer */ +#endif + + +// The largest metadata buffer size advertised +// when metadata buffer mode is used for video encoding +#define MAX_INPUT_METADATA_BUFFER_SIZE (64) + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} CODEC_ENC_ADDR_INFO; + +typedef struct _CODEC_ENC_BUFFER +{ + void *pVirAddr[MAX_BUFFER_PLANE]; /* virtual address */ + int bufferSize[MAX_BUFFER_PLANE]; /* buffer alloc size */ + int fd[MAX_BUFFER_PLANE]; /* buffer FD */ + int dataSize; /* total data length */ +} CODEC_ENC_BUFFER; + +typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT +{ + OMX_HANDLETYPE hCodecHandle; + OMX_BOOL bFirstFrame; + CODEC_ENC_BUFFER *pMFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + CODEC_ENC_BUFFER *pMFCEncOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX]; + + /* Buffer Process */ + OMX_BOOL bExitBufferProcessThread; + OMX_HANDLETYPE hSrcInputThread; + OMX_HANDLETYPE hSrcOutputThread; + OMX_HANDLETYPE hDstInputThread; + OMX_HANDLETYPE hDstOutputThread; + + /* Shared Memory Handle */ + OMX_HANDLETYPE hSharedMemory; + + OMX_BOOL configChange; + OMX_BOOL IntraRefreshVOP; + OMX_VIDEO_CONTROLRATETYPE eControlRate[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_QUANTIZATIONTYPE quantization; + + OMX_BOOL bFirstOutput; + OMX_BOOL bSharedOutputFD; + + /* CSC handle */ + OMX_PTR csc_handle; + OMX_U32 csc_set_format; + + OMX_ERRORTYPE (*exynos_codec_srcInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); + OMX_ERRORTYPE (*exynos_codec_srcOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); + OMX_ERRORTYPE (*exynos_codec_dstInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData); + OMX_ERRORTYPE (*exynos_codec_dstOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData); + + OMX_ERRORTYPE (*exynos_codec_start)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_stop)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_bufferProcessRun)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*exynos_codec_enqueueAllBuffer)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + + int (*exynos_checkInputFrame) (OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, + OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); + OMX_ERRORTYPE (*exynos_codec_getCodecInputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]); + OMX_ERRORTYPE (*exynos_codec_getCodecOutputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr, OMX_U32 *size); +} EXYNOS_OMX_VIDEOENC_COMPONENT; + +#ifdef __cplusplus +extern "C" { +#endif + +inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent); +OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData); +OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData); + + +OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/component/video/enc/Exynos_OMX_VencControl.c b/openmax/component/video/enc/Exynos_OMX_VencControl.c new file mode 100644 index 0000000..49203f5 --- /dev/null +++ b/openmax/component/video/enc/Exynos_OMX_VencControl.c @@ -0,0 +1,1849 @@ +/* + * + * 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 Exynos_OMX_VencControl.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include "Exynos_OMX_Macros.h" +#include "Exynos_OSAL_Event.h" +#include "Exynos_OMX_Venc.h" +#include "Exynos_OMX_VencControl.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OSAL_Thread.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_SharedMemory.h" + +#ifdef USE_PB +#include "Exynos_OSAL_Platform_Specific.h" +#endif + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENCCONTROL" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pTempBufferHdr = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (pExynosPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (pTempBufferHdr == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr; + pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE); + pTempBufferHdr->pBuffer = pBuffer; + pTempBufferHdr->nAllocLen = nSizeBytes; + pTempBufferHdr->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX; + else + pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX; +#ifdef SLP_PLATFORM + if (nPortIndex == OUTPUT_PORT_INDEX && pVideoEnc->bSharedOutputFD == OMX_TRUE) + pExynosPort->extendBufferHeader[i].buf_fd[0] = (int)(pBuffer); /*IL Client provides only FD value*/ +#endif + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBufferHdr = pTempBufferHdr; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(pTempBufferHdr); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AllocateBuffer( + 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_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pTempBufferHdr = NULL; + OMX_U8 *pTempBuffer = NULL; + int fdTempBuffer = -1; + MEMORY_TYPE eMemType; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; +/* + if (pExynosPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (pExynosPort->bufferProcessType & BUFFER_SHARE) + eMemType = NORMAL_MEMORY; + else + eMemType = SYSTEM_MEMORY; + + pTempBuffer = Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nSizeBytes, eMemType); + if (pTempBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + fdTempBuffer = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pTempBuffer); + + pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (pTempBufferHdr == NULL) { + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr; + pExynosPort->extendBufferHeader[i].buf_fd[0] = fdTempBuffer; + pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE); + pTempBufferHdr->pBuffer = pTempBuffer; + pTempBufferHdr->nAllocLen = nSizeBytes; + pTempBufferHdr->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX; + else + pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX; + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBufferHdr = pTempBufferHdr; + ret = OMX_ErrorNone; + goto EXIT; + } + } + + Exynos_OSAL_Free(pTempBufferHdr); + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pOMXBufferHdr = NULL; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pExynosPort->portState != OMX_StateLoaded) && + (pExynosPort->portState != OMX_StateInvalid)) { + (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent, + pExynosComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) { + if ((pExynosPort->bufferStateAllocate[i] != BUFFER_STATE_FREE) && + (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) { + pOMXBufferHdr = pExynosPort->extendBufferHeader[i].OMXBufferHeader; + + if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) { + if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pOMXBufferHdr->pBuffer); + pOMXBufferHdr->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pExynosPort->assignedBufferNum--; + + if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + Exynos_OSAL_Free(pOMXBufferHdr); + pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL; + pBufferHdr = NULL; + } + + pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if ((ret == OMX_ErrorNone) && + (pExynosPort->assignedBufferNum == 0)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set"); + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + pExynosPort->portDefinition.bPopulated = OMX_FALSE; + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pTempBufferHdr = NULL; + OMX_U8 *pTempBuffer = NULL; + OMX_U32 nBufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pTempBufferHdr = NULL; + OMX_U8 *pTempBuffer = NULL; + OMX_U32 nBufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_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_ERRORTYPE Exynos_OMX_GetFlushBuffer( + EXYNOS_OMX_BASEPORT *pExynosPort, + EXYNOS_OMX_DATABUFFER *pDataBuffer[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + *pDataBuffer = NULL; + + if (pExynosPort->portWayType == WAY1_PORT) { + *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer; + } else if (pExynosPort->portWayType == WAY2_PORT) { + pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_FlushPort( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer[2] = {NULL, NULL}; + EXYNOS_OMX_MESSAGE *pMessage = NULL; + OMX_S32 nSemaCnt = 0; + int i = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "flushPort idx:%d", nPortIndex); +#endif + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) { + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &nSemaCnt); + if (nSemaCnt == 0) + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if ((pMessage != NULL) && + (pMessage->messageType != EXYNOS_OMX_CommandFakeBuffer)) { + pBufferHdr = (OMX_BUFFERHEADERTYPE *)pMessage->pCmdData; + pBufferHdr->nFilledLen = 0; + + if (nPortIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr); + } else if (nPortIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr); + } + } + Exynos_OSAL_Free(pMessage); + pMessage = NULL; + } + + Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer); + if ((pDataBuffer[0] != NULL) && + (pDataBuffer[0]->dataValid == OMX_TRUE)) { + if (nPortIndex == INPUT_PORT_INDEX) + Exynos_FlushInputBufferReturn(pOMXComponent, pDataBuffer[0]); + else if (nPortIndex == OUTPUT_PORT_INDEX) + Exynos_FlushOutputBufferReturn(pOMXComponent, pDataBuffer[0]); + } + if ((pDataBuffer[1] != NULL) && + (pDataBuffer[1]->dataValid == OMX_TRUE)) { + if (nPortIndex == INPUT_PORT_INDEX) + Exynos_FlushInputBufferReturn(pOMXComponent, pDataBuffer[1]); + else if (nPortIndex == OUTPUT_PORT_INDEX) + Exynos_FlushOutputBufferReturn(pOMXComponent, pDataBuffer[1]); + } + + if (pExynosComponent->bMultiThreadProcess == OMX_TRUE) { + if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + if (pExynosPort->processData.bufferHeader != NULL) { + if (nPortIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader); + } else if (nPortIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader); + } + } + Exynos_ResetCodecData(&pExynosPort->processData); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) { + if (nPortIndex == OUTPUT_PORT_INDEX) { + Exynos_OMX_OutputBufferReturn(pOMXComponent, + pExynosPort->extendBufferHeader[i].OMXBufferHeader); + } else if (nPortIndex == INPUT_PORT_INDEX) { + Exynos_OMX_InputBufferReturn(pOMXComponent, + pExynosPort->extendBufferHeader[i].OMXBufferHeader); + } + } + } + } + } else { + Exynos_ResetCodecData(&pExynosPort->processData); + } + + while (1) { + OMX_S32 cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt); + if (cnt <= 0) + break; + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + } + Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_BufferFlush( + OMX_COMPONENTTYPE *pOMXComponent, + OMX_S32 nPortIndex, + OMX_BOOL bEvent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer[2] = {NULL, NULL}; + OMX_U32 i = 0; + + FunctionIn(); +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlush idx:%d", nPortIndex); +#endif + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex); + + pExynosPort->bIsPortFlushed = OMX_TRUE; + + if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) { + Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent); + } else { + Exynos_OSAL_SignalSet(pExynosPort->pauseEvent); + } + + Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer); + if (pDataBuffer[0] == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pExynosPort->bufferProcessType & BUFFER_COPY) + Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); + Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID); + + pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex); + + Exynos_OSAL_MutexLock(pDataBuffer[0]->bufferMutex); + pVideoEnc->exynos_codec_stop(pOMXComponent, nPortIndex); + + if (pDataBuffer[1] != NULL) + Exynos_OSAL_MutexLock(pDataBuffer[1]->bufferMutex); + + ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pExynosPort->bufferProcessType & BUFFER_COPY) + pVideoEnc->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex); + Exynos_ResetCodecData(&pExynosPort->processData); + + if (ret == OMX_ErrorNone) { + if (nPortIndex == INPUT_PORT_INDEX) { + pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + pExynosComponent->reInputData = OMX_FALSE; + } + + pExynosPort->bIsPortFlushed = OMX_FALSE; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex); + if (bEvent == OMX_TRUE) + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandFlush, nPortIndex, NULL); + } + + if (pDataBuffer[1] != NULL) + Exynos_OSAL_MutexUnlock(pDataBuffer[1]->bufferMutex); + + Exynos_OSAL_MutexUnlock(pDataBuffer[0]->bufferMutex); + +EXIT: + if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_InputBufferReturn( + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer = NULL; + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]); + + if (pExynosPort->bufferProcessType & BUFFER_COPY) { + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + } + + pBufferHdr = pDataBuffer->bufferHeader; + + if (pBufferHdr != NULL) { + if (pExynosPort->markType.hMarkTargetComponent != NULL) { + pBufferHdr->hMarkTargetComponent = pExynosPort->markType.hMarkTargetComponent; + pBufferHdr->pMarkData = pExynosPort->markType.pMarkData; + pExynosPort->markType.hMarkTargetComponent = NULL; + pExynosPort->markType.pMarkData = NULL; + } + + if (pBufferHdr->hMarkTargetComponent != NULL) { + if (pBufferHdr->hMarkTargetComponent == pOMXComponent) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventMark, + 0, 0, pBufferHdr->pMarkData); + } else { + pExynosComponent->propagateMarkType.hMarkTargetComponent = pBufferHdr->hMarkTargetComponent; + pExynosComponent->propagateMarkType.pMarkData = pBufferHdr->pMarkData; + } + } + + pBufferHdr->nFilledLen = 0; + pBufferHdr->nOffset = 0; + Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(pDataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_FlushInputBufferReturn( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATABUFFER *pDataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]); + + pBufferHdr = pDataBuffer->bufferHeader; + + if (pBufferHdr != NULL) { + if (pExynosPort->markType.hMarkTargetComponent != NULL) { + pBufferHdr->hMarkTargetComponent = pExynosPort->markType.hMarkTargetComponent; + pBufferHdr->pMarkData = pExynosPort->markType.pMarkData; + pExynosPort->markType.hMarkTargetComponent = NULL; + pExynosPort->markType.pMarkData = NULL; + } + + if (pBufferHdr->hMarkTargetComponent != NULL) { + if (pBufferHdr->hMarkTargetComponent == pOMXComponent) { + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventMark, + 0, 0, pBufferHdr->pMarkData); + } else { + pExynosComponent->propagateMarkType.hMarkTargetComponent = pBufferHdr->hMarkTargetComponent; + pExynosComponent->propagateMarkType.pMarkData = pBufferHdr->pMarkData; + } + } + + pBufferHdr->nFilledLen = 0; + pBufferHdr->nOffset = 0; + Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(pDataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_InputBufferGetQueue( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorUndefined; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_MESSAGE *pMessage = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]); + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + if (pDataBuffer->dataValid != OMX_TRUE) { + pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (pMessage == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(pMessage); + ret = OMX_ErrorCodecFlush; + goto EXIT; + } + + pDataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData); + pDataBuffer->allocSize = pDataBuffer->bufferHeader->nAllocLen; + pDataBuffer->dataLen = pDataBuffer->bufferHeader->nFilledLen; + pDataBuffer->remainDataLen = pDataBuffer->dataLen; + pDataBuffer->usedDataLen = 0; + pDataBuffer->dataValid = OMX_TRUE; + pDataBuffer->nFlags = pDataBuffer->bufferHeader->nFlags; + pDataBuffer->timeStamp = pDataBuffer->bufferHeader->nTimeStamp; + + Exynos_OSAL_Free(pMessage); + +#ifndef SLP_PLATFORM + if (pDataBuffer->allocSize <= pDataBuffer->dataLen) + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", pDataBuffer->allocSize, pDataBuffer->dataLen); +#endif + } + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OutputBufferReturn( + OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer = NULL; + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]); + + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + pBufferHdr = pDataBuffer->bufferHeader; + + if (pBufferHdr != NULL) { + pBufferHdr->nFilledLen = pDataBuffer->remainDataLen; + pBufferHdr->nOffset = 0; + pBufferHdr->nFlags = pDataBuffer->nFlags; + pBufferHdr->nTimeStamp = pDataBuffer->timeStamp; + + if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { + pBufferHdr->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; + pBufferHdr->pMarkData = pExynosComponent->propagateMarkType.pMarkData; + pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL; + pExynosComponent->propagateMarkType.pMarkData = NULL; + } + + if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pBufferHdr->nFilledLen = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "event OMX_BUFFERFLAG_EOS!!!"); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + pBufferHdr->nFlags, NULL); + } + + Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(pDataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_FlushOutputBufferReturn( + OMX_COMPONENTTYPE *pOMXComponent, + EXYNOS_OMX_DATABUFFER *pDataBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pBufferHdr = pDataBuffer->bufferHeader; + + if (pBufferHdr != NULL) { + pBufferHdr->nFilledLen = pDataBuffer->remainDataLen; + pBufferHdr->nOffset = 0; + pBufferHdr->nFlags = pDataBuffer->nFlags; + pBufferHdr->nTimeStamp = pDataBuffer->timeStamp; + + if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { + pBufferHdr->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; + pBufferHdr->pMarkData = pExynosComponent->propagateMarkType.pMarkData; + pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL; + pExynosComponent->propagateMarkType.pMarkData = NULL; + } + + if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pBufferHdr->nFilledLen = 0; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "event OMX_BUFFERFLAG_EOS!!!"); + pExynosComponent->pCallbacks->EventHandler(pOMXComponent, + pExynosComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + pBufferHdr->nFlags, NULL); + } + Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr); + } + + /* reset dataBuffer */ + Exynos_ResetDataBuffer(pDataBuffer); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OutputBufferGetQueue( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorUndefined; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_MESSAGE *pMessage = NULL; + EXYNOS_OMX_DATABUFFER *pDataBuffer = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]); + + if (pExynosPort->bufferProcessType & BUFFER_COPY) { + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer); + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer); + } + + if (pExynosComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + if (pDataBuffer->dataValid != OMX_TRUE) { + pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (pMessage == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(pMessage); + ret = OMX_ErrorCodecFlush; + goto EXIT; + } + + pDataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData); + pDataBuffer->allocSize = pDataBuffer->bufferHeader->nAllocLen; + pDataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + pDataBuffer->remainDataLen = pDataBuffer->dataLen; + pDataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + pDataBuffer->dataValid = OMX_TRUE; + /* pDataBuffer->nFlags = pDataBuffer->bufferHeader->nFlags; */ + /* pDtaBuffer->nTimeStamp = pDataBuffer->bufferHeader->nTimeStamp; */ +/* + if (pExynosPort->bufferProcessType & BUFFER_SHARE) + pDataBuffer->pPrivate = pDataBuffer->bufferHeader->pOutputPortPrivate; + else if (pExynosPort->bufferProcessType & BUFFER_COPY) { + pExynosPort->processData.dataBuffer = pDataBuffer->bufferHeader->pBuffer; + pExynosPort->processData.allocSize = pDataBuffer->bufferHeader->nAllocLen; + } +*/ + Exynos_OSAL_Free(pMessage); + } + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_MESSAGE *pMessage = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + pBufferHdr = NULL; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]); + + if (pExynosComponent->currentState != OMX_StateExecuting) { + pBufferHdr = NULL; + goto EXIT; + } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && + (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) { + Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID); + + pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ); + if (pMessage == NULL) { + pBufferHdr = NULL; + goto EXIT; + } + if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) { + Exynos_OSAL_Free(pMessage); + pBufferHdr = NULL; + goto EXIT; + } + + pBufferHdr = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData); + Exynos_OSAL_Free(pMessage); + } + +EXIT: + FunctionOut(); + + return pBufferHdr; +} + +OMX_ERRORTYPE Exynos_CodecBufferEnqueue( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + OMX_U32 nPortIndex, + OMX_PTR pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]); + + if (pData == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)pData); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_CodecBufferDequeue( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + OMX_U32 nPortIndex, + OMX_PTR *pData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PTR pTempData = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]); + + Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID); + pTempData = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ); + if (pTempData != NULL) { + *pData = (OMX_PTR)pTempData; + ret = OMX_ErrorNone; + } else { + *pData = NULL; + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_CodecBufferReset( + EXYNOS_OMX_BASECOMPONENT *pExynosComponent, + OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (pExynosComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]); + + ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + while (1) { + int cnt = 0; + Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt); + if (cnt > 0) + Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID); + else + break; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pPortParam->nPorts = pExynosComponent->portParam.nPorts; + pPortParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pPortFormat->nPortIndex; + OMX_U32 nIndex = pPortFormat->nIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + OMX_U32 nSupportFormat = 0; + + ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (nPortIndex == INPUT_PORT_INDEX) { + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pPortDef = &pExynosPort->portDefinition; + + switch (nIndex) { + case supportFormat_0: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_1: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_2: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_3: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV21Linear; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_4: +#ifdef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "can not support this format"); +#else + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_COLOR_FormatAndroidOpaque; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; +#endif + break; + case supportFormat_5: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + case supportFormat_6: + pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + pPortFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + break; + default: + if (nIndex > supportFormat_0) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + break; + } + } else if (nPortIndex == OUTPUT_PORT_INDEX) { + nSupportFormat = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (nIndex > nSupportFormat) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pPortDef = &pExynosPort->portDefinition; + + pPortFormat->eCompressionFormat = pPortDef->format.video.eCompressionFormat; + pPortFormat->eColorFormat = pPortDef->format.video.eColorFormat; + pPortFormat->xFramerate = pPortDef->format.video.xFramerate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *pVideoBitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pVideoBitrate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pPortDef = &pExynosPort->portDefinition; + + pVideoBitrate->eControlRate = pVideoEnc->eControlRate[nPortIndex]; + pVideoBitrate->nTargetBitrate = pPortDef->format.video.nBitrate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoQuantization: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pVideoQuantization->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pPortDef = &pExynosPort->portDefinition; + + pVideoQuantization->nQpI = pVideoEnc->quantization.nQpI; + pVideoQuantization->nQpP = pVideoEnc->quantization.nQpP; + pVideoQuantization->nQpB = pVideoEnc->quantization.nQpB; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pPortDef->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + Exynos_OSAL_Memcpy(pPortDef, &pExynosPort->portDefinition, pPortDef->nSize); + +#ifdef USE_STOREMETADATA + if ((nPortIndex == 0) && + (pExynosPort->bStoreMetaData == OMX_TRUE)) { + pPortDef->nBufferSize = MAX_INPUT_METADATA_BUFFER_SIZE; + } +#endif + } + break; + default: + { + ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, pComponentParameterStructure); + } + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pPortFormat->nPortIndex; + OMX_U32 nIndex = pPortFormat->nIndex; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + OMX_U32 nSupportFormat = 0; + + ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition); + + pPortDef->format.video.eColorFormat = pPortFormat->eColorFormat; + pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat; + pPortDef->format.video.xFramerate = pPortFormat->xFramerate; + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *pVideoBitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pVideoBitrate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition); + + pVideoEnc->eControlRate[nPortIndex] = pVideoBitrate->eControlRate; + pPortDef->format.video.nBitrate = pVideoBitrate->nTargetBitrate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoQuantization: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pVideoQuantization->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pPortDef = &pExynosPort->portDefinition; + + pVideoEnc->quantization.nQpI = pVideoQuantization->nQpI; + pVideoEnc->quantization.nQpP = pVideoQuantization->nQpP; + pVideoEnc->quantization.nQpB = pVideoQuantization->nQpB; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 nPortIndex = pPortDef->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + OMX_U32 width, height, size; + + if ((nPortIndex < 0) || + (nPortIndex >= pExynosComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + + if ((pExynosComponent->currentState != OMX_StateLoaded) && + (pExynosComponent->currentState != OMX_StateWaitForResources)) { + if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + + if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDef, pPortDef->nSize); + if (nPortIndex == INPUT_PORT_INDEX) { + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + Exynos_UpdateFrameSize(pOMXComponent); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosOutputPort->portDefinition.nBufferSize: %d", + pExynosPort->portDefinition.nBufferSize); + } + ret = OMX_ErrorNone; + } + break; +#ifdef USE_STOREMETADATA + case OMX_IndexParamStoreMetaDataBuffer: + { + ret = Exynos_OSAL_SetANBParameter(hComponent, nParamIndex, pComponentParameterStructure); + } + break; +#endif + default: + { + ret = Exynos_OMX_SetParameter(hComponent, nParamIndex, pComponentParameterStructure); + } + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentConfigStructure == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; + OMX_U32 nPortIndex = pConfigBitrate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pConfigBitrate->nEncodeBitrate = pExynosPort->portDefinition.format.video.nBitrate; + } + } + break; + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; + OMX_U32 nPortIndex = pConfigFramerate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pConfigFramerate->xEncodeFramerate = pExynosPort->portDefinition.format.video.xFramerate; + } + } + break; + default: + { + ret = Exynos_OMX_GetConfig(hComponent, nParamIndex, pComponentConfigStructure); + } + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pComponentConfigStructure) + { + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || + (pComponentConfigStructure == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure; + OMX_U32 nPortIndex = pConfigBitrate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pExynosPort->portDefinition.format.video.nBitrate = pConfigBitrate->nEncodeBitrate; + } + } + break; + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure; + OMX_U32 nPortIndex = pConfigFramerate->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pExynosPort = &pExynosComponent->pExynosPort[nPortIndex]; + pExynosPort->portDefinition.format.video.xFramerate = pConfigFramerate->xEncodeFramerate; + } + } + break; + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + OMX_U32 nPortIndex = pIntraRefreshVOP->nPortIndex; + + if (pExynosComponent->hComponentHandle == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + if (nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pVideoEnc->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP; + } + } + break; + default: + { + ret = Exynos_OMX_SetConfig(hComponent, nParamIndex, pComponentConfigStructure); + } + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING szParamName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((szParamName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + +#ifdef USE_STOREMETADATA + if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) { + *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamStoreMetaDataBuffer; + } else { + ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType); + } +#else + ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType); +#endif +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/enc/Exynos_OMX_VencControl.h b/openmax/component/video/enc/Exynos_OMX_VencControl.h new file mode 100644 index 0000000..f2bd4ed --- /dev/null +++ b/openmax/component/video/enc/Exynos_OMX_VencControl.h @@ -0,0 +1,100 @@ +/* + * + * 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 Exynos_OMX_VencControl.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_VIDEO_ENCODECONTROL +#define EXYNOS_OMX_VIDEO_ENCODECONTROL + +#include "OMX_Component.h" +#include "Exynos_OMX_Def.h" +#include "Exynos_OSAL_Queue.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Basecomponent.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_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 Exynos_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 Exynos_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer( + EXYNOS_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE Exynos_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 Exynos_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); +OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING szParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType); +OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent); +OMX_ERRORTYPE Exynos_FlushInputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer); +OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer); +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openmax/component/video/enc/Makefile.am b/openmax/component/video/enc/Makefile.am new file mode 100644 index 0000000..72d5c89 --- /dev/null +++ b/openmax/component/video/enc/Makefile.am @@ -0,0 +1,30 @@ +SUBDIRS = . h264 mpeg4 + +lib_LTLIBRARIES = libExynosOMX_Venc.la + +libExynosOMX_Venc_la_SOURCES = Exynos_OMX_Venc.c \ + Exynos_OMX_Venc.h \ + Exynos_OMX_VencControl.c \ + Exynos_OMX_VencControl.h + +libExynosOMX_Venc_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos/libcsc/libcsc.la + +libExynosOMX_Venc_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/enc \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/exynos/libcsc + +if BOARD_USE_METADATABUFFERTYPE +libExynosOMX_Venc_la_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +if BOARD_USE_STOREMETADATA +libExynosOMX_Venc_la_CFLAGS += -DUSE_STOREMETADATA +endif diff --git a/openmax/component/video/enc/h264/Android.mk b/openmax/component/video/enc/h264/Android.mk new file mode 100644 index 0000000..11c6b7f --- /dev/null +++ b/openmax/component/video/enc/h264/Android.mk @@ -0,0 +1,49 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_H264enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.AVC.Encoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi + +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/enc \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/enc/h264/Exynos_OMX_H264enc.c b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.c new file mode 100644 index 0000000..b9f10da --- /dev/null +++ b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.c @@ -0,0 +1,2580 @@ +/* + * + * 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 Exynos_OMX_H264enc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Venc.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_H264enc.h" +//#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_H264_ENC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +/* H.264 Encoder Supported Levels & profiles */ +EXYNOS_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_AVCProfileBaseline, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42}, + + {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_AVCProfileMain, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42}, + + {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_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}}; + +static OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile) +{ + OMX_U32 ret = 0; + + if (profile == OMX_VIDEO_AVCProfileBaseline) + ret = 0; + else if (profile == OMX_VIDEO_AVCProfileMain) + ret = 2; + else if (profile == OMX_VIDEO_AVCProfileHigh) + ret = 4; + + return ret; +} + +static OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level) +{ + OMX_U32 ret = 11; //default OMX_VIDEO_AVCLevel4 + + if (level == OMX_VIDEO_AVCLevel1) + ret = 0; + else if (level == OMX_VIDEO_AVCLevel1b) + ret = 1; + else if (level == OMX_VIDEO_AVCLevel11) + ret = 2; + else if (level == OMX_VIDEO_AVCLevel12) + ret = 3; + else if (level == OMX_VIDEO_AVCLevel13) + ret = 4; + else if (level == OMX_VIDEO_AVCLevel2) + ret = 5; + else if (level == OMX_VIDEO_AVCLevel21) + ret = 6; + else if (level == OMX_VIDEO_AVCLevel22) + ret = 7; + else if (level == OMX_VIDEO_AVCLevel3) + ret = 8; + else if (level == OMX_VIDEO_AVCLevel31) + ret = 9; + else if (level == OMX_VIDEO_AVCLevel32) + ret = 10; + else if (level == OMX_VIDEO_AVCLevel4) + ret = 11; + else if (level == OMX_VIDEO_AVCLevel41) + ret = 12; + else if (level == OMX_VIDEO_AVCLevel42) + ret = 13; + + return ret; +} + +static 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; +} + +static void Print_H264Enc_Param(ExynosVideoEncParam *pEncParam) +{ + ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam; + ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264; + + /* common parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth : %d", pCommonParam->SourceWidth); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight : %d", pCommonParam->SourceHeight); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod : %d", pCommonParam->IDRPeriod); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode : %d", pCommonParam->SliceMode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh : %d", pCommonParam->RandomIntraMBRefresh); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate : %d", pCommonParam->Bitrate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp : %d", pCommonParam->FrameQp); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P : %d", pCommonParam->FrameQp_P); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax : %d", pCommonParam->QSCodeMax); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin : %d", pCommonParam->QSCodeMin); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn : %d", pCommonParam->PadControlOn); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal : %d", pCommonParam->LumaPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal : %d", pCommonParam->CbPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal : %d", pCommonParam->CrPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap : %d", pCommonParam->FrameMap); + + /* H.264 specific parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProfileIDC : %d", pH264Param->ProfileIDC); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LevelIDC : %d", pH264Param->LevelIDC); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_B : %d", pH264Param->FrameQp_B); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameRate : %d", pH264Param->FrameRate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceArgument : %d", pH264Param->SliceArgument); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberBFrames : %d", pH264Param->NumberBFrames); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberReferenceFrames : %d", pH264Param->NumberReferenceFrames); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberRefForPframes : %d", pH264Param->NumberRefForPframes); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterDisable : %d", pH264Param->LoopFilterDisable); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterBetaOffset : %d", pH264Param->LoopFilterBetaOffset); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SymbolMode : %d", pH264Param->SymbolMode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PictureInterlace : %d", pH264Param->PictureInterlace); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Transform8x8Mode : %d", pH264Param->Transform8x8Mode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DarkDisable : %d", pH264Param->DarkDisable); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SmoothDisable : %d", pH264Param->SmoothDisable); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "StaticDisable : %d", pH264Param->StaticDisable); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ActivityDisable : %d", pH264Param->ActivityDisable); + + /* rate control related parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl : %d", pCommonParam->EnableFRMRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl : %d", pCommonParam->EnableMBRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf : %d", pCommonParam->CBRPeriodRf); +} + +static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL; + + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncH264Param *pH264Param = NULL; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pMFCH264Handle = &pH264Enc->hMFCH264Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + pEncParam = &pMFCH264Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pH264Param = &pEncParam->codecParam.h264; + pEncParam->eCompressionFormat = VIDEO_CODING_AVC; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat); + + /* common parameters */ + pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth; + pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight; + pCommonParam->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + pCommonParam->SliceMode = pH264Enc->AVCSliceFmo.eSliceMode; + pCommonParam->RandomIntraMBRefresh = 0; + pCommonParam->Bitrate = pExynosOutputPort->portDefinition.format.video.nBitrate; + pCommonParam->FrameQp = pVideoEnc->quantization.nQpI; + pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP; + pCommonParam->QSCodeMax = 51; + pCommonParam->QSCodeMin = 10; + pCommonParam->PadControlOn = 0; /* 0: disable, 1: enable */ + pCommonParam->LumaPadVal = 0; + pCommonParam->CbPadVal = 0; + pCommonParam->CrPadVal = 0; + + switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_Preprocessor_InputData */ + case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd: +#ifdef USE_METADATABUFFERTYPE + case OMX_COLOR_FormatAndroidOpaque: +#endif + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; + break; + default: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + /* H.264 specific parameters */ + pH264Param->ProfileIDC = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile); /*0: OMX_VIDEO_AVCProfileMain */ + pH264Param->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); /*40: OMX_VIDEO_AVCLevel4 */ + pH264Param->FrameQp_B = pVideoEnc->quantization.nQpB; + pH264Param->FrameRate = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; + if (pH264Enc->AVCSliceFmo.eSliceMode == OMX_VIDEO_SLICEMODE_AVCDefault) + pH264Param->SliceArgument = 0; /* Slice mb/byte size number */ + else + pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing; + + pH264Param->NumberBFrames = 0; /* 0 ~ 2 */ + pH264Param->NumberReferenceFrames = 1; + pH264Param->NumberRefForPframes = 1; +#ifdef SLP_PLATFORM /* for B2 camera */ + pH264Param->LoopFilterDisable = 0; /* 1: Loop Filter Disable, 0: Filter Enable */ +#else + pH264Param->LoopFilterDisable = 1; /* 1: Loop Filter Disable, 0: Filter Enable */ +#endif + pH264Param->LoopFilterAlphaC0Offset = 0; + pH264Param->LoopFilterBetaOffset = 0; + pH264Param->SymbolMode = 0; /* 0: CAVLC, 1: CABAC */ + pH264Param->PictureInterlace = 0; + pH264Param->Transform8x8Mode = 0; /* 0: 4x4, 1: allow 8x8 */ + pH264Param->DarkDisable = 1; + pH264Param->SmoothDisable = 1; + pH264Param->StaticDisable = 1; + pH264Param->ActivityDisable = 1; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + /* rate control related parameters */ + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateDisable: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR"); + pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 0; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 9; + break; + case OMX_Video_ControlRateVariable: + default: /*Android default */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 100; + break; + } + + Print_H264Enc_Param(pEncParam); +} + +static void Change_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncH264Param *pH264Param = NULL; + + int setParam = 0; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pMFCH264Handle = &pH264Enc->hMFCH264Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pEncOps = pMFCH264Handle->pEncOps; + + pEncParam = &pMFCH264Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pH264Param = &pEncParam->codecParam.h264; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + setParam = VIDEO_FRAME_I; + pEncOps->Set_FrameType(pH264Enc->hMFCH264Handle.hMFCHandle, setParam); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + if (pCommonParam->IDRPeriod != (int)pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1) { + setParam = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, setParam); + } + if (pCommonParam->Bitrate != (int)pExynosOutputPort->portDefinition.format.video.nBitrate) { + setParam = pExynosOutputPort->portDefinition.format.video.nBitrate; + pEncOps->Set_BitRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam); + } + if (pH264Param->FrameRate != (int)((pExynosInputPort->portDefinition.format.video.xFramerate) >> 16)) { + setParam = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; + pEncOps->Set_FrameRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam); + } + + Set_H264Enc_Param(pExynosComponent); +} + +OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (pVirtAddr != NULL) + *pVirtAddr = pCodecBuffer->planes[0].addr; + + if (dataSize != NULL) + *dataSize = pCodecBuffer->planes[0].allocSize; + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + +EXIT: + return ret; +} + +OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264ENC_HANDLE *pH264Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + enum v4l2_memory v4l2MemoryType = V4L2_MEMORY_USERPTR; + + FunctionIn(); + + if (pH264Enc == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pEncOps = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps)); + pInbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + + if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate encoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pH264Enc->hMFCH264Handle.pEncOps = pEncOps; + pH264Enc->hMFCH264Handle.pInbufOps = pInbufOps; + pH264Enc->hMFCH264Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pEncOps->nSize = sizeof(ExynosVideoEncOps); + pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + + Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for encoder ops */ + if ((pEncOps->Init == NULL) || (pEncOps->Finalize == NULL) || + (pEncOps->Set_FrameTag == NULL) || (pEncOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) { +#ifdef USE_DMA_BUF + v4l2MemoryType = V4L2_MEMORY_DMABUF; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_DMABUF"); +#else + v4l2MemoryType = V4L2_MEMORY_USERPTR; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_USEPTR"); +#endif + } else { + //v4l2MemoryType = V4L2_MEMORY_MMAP; + v4l2MemoryType = V4L2_MEMORY_DMABUF; //if input port is using Buffer-share mode + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY - DMABUF & MMAP"); + } + + /* alloc context, open, querycap */ + pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(v4l2MemoryType); + if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pH264Enc->hMFCH264Handle.pEncOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pH264Enc->hMFCH264Handle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pH264Enc->hMFCH264Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecClose(EXYNOS_H264ENC_HANDLE *pH264Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pH264Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pEncOps->Finalize(hMFCHandle); + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps = NULL; + } + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pEncOps = pH264Enc->hMFCH264Handle.pEncOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pH264Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pH264Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; + void *hMFCHandle = pMFCH264Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoEncParam *pEncParam = NULL; + + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, nOutbufs; + + FunctionIn(); + + Set_H264Enc_Param(pExynosComponent); + pEncParam = &pMFCH264Handle->encParam; + if (pEncOps->Set_EncParam) { + if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + if (pMFCH264Handle->bPrependSpsPpsToIdr == OMX_TRUE) { + if (pEncOps->Enable_PrependSpsPpsToIdr) + pEncOps->Enable_PrependSpsPpsToIdr(pH264Enc->hMFCH264Handle.hMFCHandle); + } + + /* input buffer info: only 3 config values needed */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;; + bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth; + bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight; + + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "bufferConf, eColorFormat=%d, w=%d, h=%d", bufferConf.eColorFormat, bufferConf.nFrameWidth, bufferConf.nFrameHeight); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE + ||pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) + pInbufOps->Set_Shareable(hMFCHandle); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + inputBufferNumber = MAX_CAMERA_INPUTBUFFER_NUM; /* Need change to number of camera buffer */ + } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set Enable_Cacheable for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry) { + + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; + int plane; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY && + pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + planes[plane].addr = pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]; + planes[plane].allocSize = pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane]; + planes[plane].fd = pVideoEnc->pMFCEncInputBuffer[i]->fd[plane]; + } + if (pInbufOps->Register(hMFCHandle, planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE) { + ExynosVideoBuffer *pBuffer = NULL; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + /* get input buffer info */ + if (pInbufOps->Get_Buffer) { + if (pInbufOps->Get_Buffer(pH264Enc->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoEnc->pMFCEncInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } else { +#ifndef SLP_PLATFORM /* slp platform can go into here */ + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pH264Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pH264Enc->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pH264Enc->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecEnqueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pH264Enc->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pH264Enc->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[2] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]); +// Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); +// Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; + void *hMFCHandle = pMFCH264Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoEncParam *pEncParam = NULL; + + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, nOutbufs; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE)) { + ret = H264CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + + + pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; + void *hMFCHandle = pMFCH264Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + int i, nOutbufs, nPlanes, OutBufferSize; + + FunctionIn(); + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { +/*For memory Optimization */ + OutBufferSize = 1024*1024*2;//pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + } else { + OutBufferSize = pExynosOutputPort->extendBufferHeader[0].OMXBufferHeader->nAllocLen; + } + + /* set geometry for output (dst) */ + if (pOutbufOps->Set_Geometry) { + /* output buffer info: only 2 config values needed */ + bufferConf.eCompressionFormat = VIDEO_CODING_AVC; + bufferConf.nSizeImage = OutBufferSize; + + if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE + ||pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Set_Shareable(hMFCHandle); + + int SetupBufferNumber = 0; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) + SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX; + else + SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber); + + if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0}; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY); + if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->pMFCEncOutputBuffer[i]->fd[0] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]); + pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0] = OutBufferSize; + + plane.addr = pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]; + plane.fd = pVideoEnc->pMFCEncOutputBuffer[i]->fd[0]; + plane.allocSize = pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0]; + + if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + }else if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE) { + /* Register input buffer */ + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoBuffer *pBuffer = NULL; + + pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + + if (pOutbufOps->Get_Buffer) { + if (pOutbufOps->Get_Buffer(pH264Enc->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (nPlanes = 0; nPlanes < MFC_OUTPUT_BUFFER_PLANE; nPlanes++) { + pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes] = (void *)pBuffer->planes[nPlanes].addr; + pVideoEnc->pMFCEncOutputBuffer[i]->fd[nPlanes] = pBuffer->planes[nPlanes].fd; + pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[nPlanes] = pBuffer->planes[nPlanes].allocSize; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes]); + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } + + /* start header encoding */ + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /* Register input buffer */ + /*************/ + /* TBD */ + /*************/ + ExynosVideoPlane plane; + for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) { + plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; + plane.allocSize = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + + pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + + case OMX_IndexParamVideoSliceFMO: + { + OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcSliceFmo = &pH264Enc->AVCSliceFmo; + + Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = Exynos_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(EXYNOS_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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamVideoSliceFMO: + { + OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL; + OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstSliceFmo = &pH264Enc->AVCSliceFmo; + + Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO)); + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE)) { + pExynosComponent->pExynosPort[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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + ret = Exynos_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 = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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; +#ifdef USE_H264_PREPEND_SPS_PPS + case OMX_IndexParamPrependSPSPPSToIDR: + { + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr = OMX_TRUE; + } + break; +#endif +#ifdef SLP_PLATFORM + case OMX_IndexParamSharedOutputFD: + { + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + + pVideoEnc->bSharedOutputFD = OMX_TRUE; + } + break; +#endif + + default: + ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + + switch (nIndex) { + case OMX_IndexConfigVideoIntraPeriod: + { + EXYNOS_OMX_VIDEOENC_COMPONENT *pVEncBase = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + if (ret == OMX_ErrorNone) + pVideoEnc->configChange = OMX_TRUE; + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { + *pIndexType = OMX_IndexConfigVideoIntraPeriod; + ret = OMX_ErrorNone; +#ifdef SLP_PLATFORM + } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENC_SHARED_OUTPUT_FD) == 0) { + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamSharedOutputFD; + goto EXIT; +#endif +#ifdef USE_H264_PREPEND_SPS_PPS + } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) { + *pIndexType = OMX_IndexParamPrependSPSPPSToIDR; + goto EXIT; +#endif + } else { + ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;; + EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle; + OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + OMX_COLOR_FORMATTYPE eColorFormat; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i = 0; + + FunctionIn(); + + pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE; + pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE; + pVideoEnc->bFirstOutput = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat; + if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { +#ifndef SLP_PLATFORM /* we do not use OMX_COLOR_FormatAndroidOpaque */ + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + pExynosInputPort->bufferProcessType = BUFFER_COPY; + } else { + pExynosInputPort->bufferProcessType = BUFFER_SHARE; + } +#endif + } else { + if (eColorFormat == OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd || + eColorFormat == OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd) { + pExynosInputPort->bufferProcessType = BUFFER_SHARE; + } else { + pExynosInputPort->bufferProcessType = BUFFER_COPY; + } + } + +#ifdef SLP_PLATFORM + if (pVideoEnc->bSharedOutputFD == OMX_TRUE) { + pExynosOutputPort->bufferProcessType = BUFFER_SHARE; + } else { + pExynosOutputPort->bufferProcessType = BUFFER_COPY; + } +#endif + + /* H.264 Codec Open */ + ret = H264CodecOpen(pH264Enc); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + /* Use ION Allocator */ + /*Alloc Y-Buffer */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY); + pVideoEnc->pMFCEncInputBuffer[i]->fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; + /*Alloc C-Buffer */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY); + pVideoEnc->pMFCEncInputBuffer[i]->fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; + + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + + if ((pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] == NULL) || + (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* MFC input buffers are 1 plane. */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[2] = NULL; + pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + } else { + ret = H264CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pH264Enc->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent); + pH264Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Enc->hMFCH264Handle.indexTimestamp = 0; + pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + pVideoEnc->csc_handle = csc_init(csc_method); + if (pVideoEnc->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle); + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + + int i = 0, plane = 0; + + FunctionIn(); + + if (pVideoEnc->csc_handle != NULL) { + csc_deinit(pVideoEnc->csc_handle); + pVideoEnc->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent); + pH264Enc->hDestinationStartEvent = NULL; + pH264Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent); + pH264Enc->hSourceStartEvent = NULL; + pH264Enc->bSourceStart = OMX_FALSE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]); +#endif + Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]); + pVideoEnc->pMFCEncOutputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]); + pVideoEnc->pMFCEncInputBuffer[i] = NULL; + } + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + H264CodecClose(pH264Enc); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData); +// if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) + if (ret != OMX_ErrorNone) + goto EXIT; + } + if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) { + ret = H264CodecDstSetup(pOMXComponent); + } + if (pVideoEnc->configChange == OMX_TRUE) { + Change_H264Enc_Param(pExynosComponent); + pVideoEnc->configChange = OMX_FALSE; + } + + if ((pSrcInputData->dataLen >= 0) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL}; + ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; + int plane; + + pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags); + pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp); + pH264Enc->hMFCH264Handle.indexTimestamp++; + pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader); + pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; + pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2; + +//#define INPUT_FILE_DUMP +#ifdef INPUT_FILE_DUMP + { + FILE *pf; + char filename[100]; + static int tmp_cnt=0; + int w = pExynosInputPort->portDefinition.format.video.nFrameWidth; + int h = pExynosInputPort->portDefinition.format.video.nFrameHeight; + + memset(filename, 0x00, sizeof(filename)); + sprintf(filename, "/tmp/enc_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt); + pf = fopen(filename, "wb"); + if (pf == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] filepoint NULL!"); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] fwrite[%d] ", tmp_cnt); + fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0], sizeof(char), h * w, pf); + fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1], sizeof(char), h * w / 2, pf); + } + fclose(pf); + } +#endif + + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); +//#ifdef USE_METADATABUFFERTYPE + if ((codecReturn == VIDEO_ERROR_NOBUFFERS) && + /*(pExynosInputPort->bStoreMetaData == OMX_TRUE) &&*/ + (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) { + OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0}; + nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * + ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight); + nAllocLen[1] = ALIGN(nAllocLen[0]/2,256); + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane]; + planes[plane].allocSize = nAllocLen[plane]; + planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane]; + } + + /* Register input buffer */ + if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle, + planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + + } +//#endif + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + H264CodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pH264Enc->bSourceStart == OMX_FALSE) { + pH264Enc->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pH264Enc->bDestinationStart == OMX_FALSE) { + pH264Enc->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + int plane = 0; + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + } + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize + + pVideoBuffer->planes[1].allocSize + + pVideoBuffer->planes[2].allocSize; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + i++; + } + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + OMX_U32 dataLen = 0; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry bufferGeometry; + OMX_S32 indexTimestamp = 0; + + FunctionIn(); + + if (pH264Enc->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + + pH264Enc->hMFCH264Handle.outputIndexTimestamp++; + pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pDstOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + pDstOutputData->dataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + if (pVideoEnc->bFirstOutput == OMX_FALSE) { + if (pVideoEnc->bSharedOutputFD == OMX_FALSE) { + OMX_U8 *p = NULL; + int iSpsSize = 0; + int iPpsSize = 0; + + /* Calculate sps/pps size if needed */ + p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4), + pDstOutputData->dataLen - 4); + + iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; + pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = + (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; + pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; + + iPpsSize = pDstOutputData->dataLen - iSpsSize; + pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = + (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize; + pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + } + pDstOutputData->timeStamp = 0; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + pVideoEnc->bFirstOutput = OMX_TRUE; + } else { + indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp]; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } + + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (pVideoBuffer->frameType == VIDEO_FRAME_I) + pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pH264Enc->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent); + } + + ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pH264Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent); + } + } + if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pH264Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent); + } + } + ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_ENC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE)); + if (pH264Enc == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE)); + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc; + pVideoEnc->quantization.nQpI = 20; + pVideoEnc->quantization.nQpP = 20; + pVideoEnc->quantization.nQpB = 20; + pVideoEnc->bSharedOutputFD = OMX_FALSE; + + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC); + + /* In case of BUFFER_COPY mode + bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR + bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP + In case of BUFFER_SHARE + bShareableBuf should be TRUE, FALSE is ignored + */ + pH264Enc->hMFCH264Handle.bShareableBuf = OMX_FALSE; //Check bStoreMetaData in Init function + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); +#ifdef SLP_PLATFORM + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; +#else + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#endif + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc"); + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + 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 = &Exynos_H264Enc_GetParameter; + pOMXComponent->SetParameter = &Exynos_H264Enc_SetParameter; + pOMXComponent->GetConfig = &Exynos_H264Enc_GetConfig; + pOMXComponent->SetConfig = &Exynos_H264Enc_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_H264Enc_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate; + + pVideoEnc->exynos_codec_srcInputProcess = &Exynos_H264Enc_srcInputBufferProcess; + pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess; + pVideoEnc->exynos_codec_dstInputProcess = &Exynos_H264Enc_dstInputBufferProcess; + pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess; + + pVideoEnc->exynos_codec_start = &H264CodecStart; + pVideoEnc->exynos_codec_stop = &H264CodecStop; + pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun; + pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnqueueAllBuffer; + + pVideoEnc->exynos_checkInputFrame = NULL; + pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoEnc->hSharedMemory == NULL) { + Exynos_OSAL_Free(pH264Enc); + pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pH264Enc != NULL) { + Exynos_OSAL_Free(pH264Enc); + pH264Enc = pVideoEnc->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/enc/h264/Exynos_OMX_H264enc.h b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.h new file mode 100644 index 0000000..caa606d --- /dev/null +++ b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.h @@ -0,0 +1,87 @@ +/* + * + * 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 Exynos_OMX_H264enc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_H264_ENC_COMPONENT +#define EXYNOS_OMX_H264_ENC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + +#include "ExynosVideoApi.h" + +typedef struct _EXTRA_DATA +{ + OMX_PTR pHeaderSPS; + OMX_U32 SPSLen; + OMX_PTR pHeaderPPS; + OMX_U32 PPSLen; +} EXTRA_DATA; + +typedef struct _EXYNOS_MFC_H264ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + OMX_BOOL bPrependSpsPpsToIdr; + EXTRA_DATA headerData; + + ExynosVideoDecOps *pEncOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoEncParam encParam; +} EXYNOS_MFC_H264ENC_HANDLE; + +typedef struct _EXYNOS_H264ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_AVCSLICEFMO AVCSliceFmo; + /* SEC MFC Codec specific */ + EXYNOS_MFC_H264ENC_HANDLE hMFCH264Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +} EXYNOS_H264ENC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/enc/h264/Makefile.am b/openmax/component/video/enc/h264/Makefile.am new file mode 100644 index 0000000..a59e5ff --- /dev/null +++ b/openmax/component/video/enc/h264/Makefile.am @@ -0,0 +1,35 @@ +lib_LTLIBRARIES = libOMX.Exynos.AVC.Encoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_AVC_Encoder_la_SOURCES = Exynos_OMX_H264enc.c \ + Exynos_OMX_H264enc.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_AVC_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + +libOMX_Exynos_AVC_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/enc \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_AVC_Encoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_METADATABUFFERTYPE +libOMX_Exynos_AVC_Encoder_la_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +libOMX_Exynos_AVC_Encoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/enc/h264/library_register.c b/openmax/component/video/enc/h264/library_register.c new file mode 100644 index 0000000..c8afbd6 --- /dev/null +++ b/openmax/component/video/enc/h264/library_register.c @@ -0,0 +1,55 @@ +/* + * + * 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 library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" +#include "Exynos_OSAL_Log.h" + + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents) +{ + FunctionIn(); + + if (exynosComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_ENC); + Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_ENC_ROLE); + exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} + diff --git a/openmax/component/video/enc/h264/library_register.h b/openmax/component/video/enc/h264/library_register.h new file mode 100644 index 0000000..1d2022a --- /dev/null +++ b/openmax/component/video/enc/h264/library_register.h @@ -0,0 +1,55 @@ +/* + * + * 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 library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_H264_REG +#define EXYNOS_OMX_H264_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_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 EXYNOS_OMX_COMPONENT_H264_ENC "OMX.Exynos.AVC.Encoder" +#define EXYNOS_OMX_COMPONENT_H264_ENC_ROLE "video_encoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/openmax/component/video/enc/mpeg4/Android.mk b/openmax/component/video/enc/mpeg4/Android.mk new file mode 100644 index 0000000..a5c0fa4 --- /dev/null +++ b/openmax/component/video/enc/mpeg4/Android.mk @@ -0,0 +1,48 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Mpeg4enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.Exynos.MPEG4.Encoder +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_METADATABUFFERTYPE), true) +LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ + libswconverter libExynosVideoApi +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \ + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/core \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/enc \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c new file mode 100644 index 0000000..651eaaa --- /dev/null +++ b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c @@ -0,0 +1,2721 @@ +/* + * + * 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 Exynos_OMX_Mpeg4enc.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Venc.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OSAL_Thread.h" +#include "library_register.h" +#include "Exynos_OMX_Mpeg4enc.h" +//#include "ExynosVideoApi.h" +#include "Exynos_OSAL_SharedMemory.h" +#include "Exynos_OSAL_Event.h" + +/* To use CSC_METHOD_HW in EXYNOS 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 EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG4_ENC" +#define EXYNOS_LOG_OFF +//#define EXYNOS_TRACE_ON +#include "Exynos_OSAL_Log.h" + +/* MPEG4 Encoder Supported Levels & profiles */ +EXYNOS_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 */ +EXYNOS_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}}; + +static 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; +} + +static OMX_U32 OMXMpeg4LevelToMFCLevel(OMX_VIDEO_MPEG4LEVELTYPE level) +{ + OMX_U32 ret; + + switch (level) { + case OMX_VIDEO_MPEG4Level0: + ret = 0; + break; + case OMX_VIDEO_MPEG4Level0b: + ret = 1; + break; + case OMX_VIDEO_MPEG4Level1: + ret = 2; + break; + case OMX_VIDEO_MPEG4Level2: + ret = 3; + break; + case OMX_VIDEO_MPEG4Level3: + ret = 4; + break; + case OMX_VIDEO_MPEG4Level4: + case OMX_VIDEO_MPEG4Level4a: + ret = 6; + break; + case OMX_VIDEO_MPEG4Level5: + ret = 7; + break; + default: + ret = 0; + }; + + return ret; +} + +static void Print_Mpeg4Enc_Param(ExynosVideoEncParam *pEncParam) +{ + ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam; + ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4; + + /* common parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth : %d", pCommonParam->SourceWidth); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight : %d", pCommonParam->SourceHeight); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod : %d", pCommonParam->IDRPeriod); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode : %d", pCommonParam->SliceMode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh : %d", pCommonParam->RandomIntraMBRefresh); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate : %d", pCommonParam->Bitrate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp : %d", pCommonParam->FrameQp); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P : %d", pCommonParam->FrameQp_P); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax : %d", pCommonParam->QSCodeMax); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin : %d", pCommonParam->QSCodeMin); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn : %d", pCommonParam->PadControlOn); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal : %d", pCommonParam->LumaPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal : %d", pCommonParam->CbPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal : %d", pCommonParam->CrPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap : %d", pCommonParam->FrameMap); + + /* Mpeg4 specific parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProfileIDC : %d", pMpeg4Param->ProfileIDC); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LevelIDC : %d", pMpeg4Param->LevelIDC); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_B : %d", pMpeg4Param->FrameQp_B); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "TimeIncreamentRes : %d", pMpeg4Param->TimeIncreamentRes); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VopTimeIncreament : %d", pMpeg4Param->VopTimeIncreament); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceArgument : %d", pMpeg4Param->SliceArgument); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberBFrames : %d", pMpeg4Param->NumberBFrames); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisableQpelME : %d", pMpeg4Param->DisableQpelME); + + /* rate control related parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl : %d", pCommonParam->EnableFRMRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl : %d", pCommonParam->EnableMBRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf : %d", pCommonParam->CBRPeriodRf); +} + +static void Print_H263Enc_Param(ExynosVideoEncParam *pEncParam) +{ + ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam; + ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263; + + /* common parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth : %d", pCommonParam->SourceWidth); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight : %d", pCommonParam->SourceHeight); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod : %d", pCommonParam->IDRPeriod); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode : %d", pCommonParam->SliceMode); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh : %d", pCommonParam->RandomIntraMBRefresh); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate : %d", pCommonParam->Bitrate); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp : %d", pCommonParam->FrameQp); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P : %d", pCommonParam->FrameQp_P); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax : %d", pCommonParam->QSCodeMax); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin : %d", pCommonParam->QSCodeMin); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn : %d", pCommonParam->PadControlOn); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal : %d", pCommonParam->LumaPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal : %d", pCommonParam->CbPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal : %d", pCommonParam->CrPadVal); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap : %d", pCommonParam->FrameMap); + + /* H263 specific parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameRate : %d", pH263Param->FrameRate); + + /* rate control related parameters */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl : %d", pCommonParam->EnableFRMRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl : %d", pCommonParam->EnableMBRateControl); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf : %d", pCommonParam->CBRPeriodRf); +} + +static void Set_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncMpeg4Param *pMpeg4Param = NULL; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = pVideoEnc->hCodecHandle; + pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + pEncParam = &pMFCMpeg4Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pMpeg4Param = &pEncParam->codecParam.mpeg4; + pEncParam->eCompressionFormat = VIDEO_CODING_MPEG4; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat); + + /* common parameters */ + pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth; + pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight; + pCommonParam->IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pCommonParam->SliceMode = 0; + pCommonParam->RandomIntraMBRefresh = 0; + pCommonParam->Bitrate = pExynosOutputPort->portDefinition.format.video.nBitrate; + pCommonParam->FrameQp = pVideoEnc->quantization.nQpI; + pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP; + pCommonParam->QSCodeMax = 30; + pCommonParam->QSCodeMin = 10; + pCommonParam->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pCommonParam->LumaPadVal = 0; + pCommonParam->CbPadVal = 0; + pCommonParam->CrPadVal = 0; + + switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_Preprocessor_InputData */ +#ifdef SLP_PLATFORM + case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd: +#endif +#ifdef USE_METADATABUFFERTYPE + case OMX_COLOR_FormatAndroidOpaque: +#endif + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; + break; + default: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + /* Mpeg4 specific parameters */ + pMpeg4Param->ProfileIDC = OMXMpeg4ProfileToMFCProfile(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eProfile); + pMpeg4Param->LevelIDC = OMXMpeg4LevelToMFCLevel(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eLevel); + pMpeg4Param->FrameQp_B = pVideoEnc->quantization.nQpB; + pMpeg4Param->TimeIncreamentRes = (pExynosInputPort->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; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + /* rate control related parameters */ + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateDisable: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR"); + pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 0; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 9; + break; + case OMX_Video_ControlRateVariable: + default: /*Android default */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 100; + break; + } + + Print_Mpeg4Enc_Param(pEncParam); +} + +static void Set_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncH263Param *pH263Param = NULL; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = pVideoEnc->hCodecHandle; + pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + pEncParam = &pMFCMpeg4Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pH263Param = &pEncParam->codecParam.h263; + pEncParam->eCompressionFormat = VIDEO_CODING_H263; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat); + + /* common parameters */ + pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth; + pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight; + pCommonParam->IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pCommonParam->SliceMode = 0; + pCommonParam->RandomIntraMBRefresh = 0; + pCommonParam->Bitrate = pExynosOutputPort->portDefinition.format.video.nBitrate; + pCommonParam->FrameQp = pVideoEnc->quantization.nQpI; + pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP; + pCommonParam->QSCodeMax = 30; + pCommonParam->QSCodeMin = 10; + pCommonParam->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pCommonParam->LumaPadVal = 0; + pCommonParam->CbPadVal = 0; + pCommonParam->CrPadVal = 0; + + switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_Preprocessor_InputData */ +#ifdef SLP_PLATFORM + case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd: +#endif +#ifdef USE_METADATABUFFERTYPE + case OMX_COLOR_FormatAndroidOpaque: +#endif + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12; + break; + case OMX_SEC_COLOR_FormatNV12Tiled: + case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21; + break; + default: + pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED; + break; + } + + /* H263 specific parameters */ + pH263Param->FrameRate = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]); + /* rate control related parameters */ + switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) { + case OMX_Video_ControlRateVariable: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR"); + pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 0; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 100; + break; + case OMX_Video_ControlRateConstant: + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR"); + pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */ + pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */ + pCommonParam->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: /*Android default */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR"); + pCommonParam->EnableFRMRateControl = 0; + pCommonParam->EnableMBRateControl = 0; + pCommonParam->CBRPeriodRf = 100; + break; + } + + Print_H263Enc_Param(pEncParam); +} + +static void Change_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncMpeg4Param *pMpeg4Param = NULL; + + int setParam = 0; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = pVideoEnc->hCodecHandle; + pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pEncOps = pMFCMpeg4Handle->pEncOps; + + pEncParam = &pMFCMpeg4Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pMpeg4Param = &pEncParam->codecParam.mpeg4; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + setParam = VIDEO_FRAME_I; + pEncOps->Set_FrameType(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + if (pCommonParam->IDRPeriod != (int)pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1) { + setParam = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pEncOps->Set_IDRPeriod(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + if (pCommonParam->Bitrate != (int)pExynosOutputPort->portDefinition.format.video.nBitrate) { + setParam = pExynosOutputPort->portDefinition.format.video.nBitrate; + pEncOps->Set_BitRate(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + if (pMpeg4Param->TimeIncreamentRes != (int)((pExynosInputPort->portDefinition.format.video.xFramerate) >> 16)) { + setParam = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; + pEncOps->Set_FrameRate(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + + Set_Mpeg4Enc_Param(pExynosComponent); +} + +static void Change_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent) +{ + EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncParam *pEncParam = NULL; + ExynosVideoEncCommonParam *pCommonParam = NULL; + ExynosVideoEncH263Param *pH263Param = NULL; + + int setParam = 0; + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = pVideoEnc->hCodecHandle; + pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pEncOps = pMFCMpeg4Handle->pEncOps; + + pEncParam = &pMFCMpeg4Handle->encParam; + pCommonParam = &pEncParam->commonParam; + pH263Param = &pEncParam->codecParam.h263; + + if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) { + setParam = VIDEO_FRAME_I; + pEncOps->Set_FrameType(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + pVideoEnc->IntraRefreshVOP = OMX_FALSE; + } + if (pCommonParam->IDRPeriod != (int)pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1) { + setParam = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pEncOps->Set_IDRPeriod(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + if (pCommonParam->Bitrate != (int)pExynosOutputPort->portDefinition.format.video.nBitrate) { + setParam = pExynosOutputPort->portDefinition.format.video.nBitrate; + pEncOps->Set_BitRate(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + if (pH263Param->FrameRate != (int)((pExynosInputPort->portDefinition.format.video.xFramerate) >> 16)) { + setParam = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16; + pEncOps->Set_FrameRate(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, setParam); + } + + Set_H263Enc_Param(pExynosComponent); +} + +OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + ExynosVideoBuffer *pCodecBuffer; + + if (codecBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + + if (pVirtAddr != NULL) + *pVirtAddr = pCodecBuffer->planes[0].addr; + + if (dataSize != NULL) + *dataSize = pCodecBuffer->planes[0].allocSize; + + pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; + +EXIT: + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecOpen(EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + enum v4l2_memory v4l2MemoryType = V4L2_MEMORY_USERPTR; + + FunctionIn(); + + if (pMpeg4Enc == NULL) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + + /* alloc ops structure */ + pEncOps = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps)); + pInbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps)); + + if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate encoder ops buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pMpeg4Enc->hMFCMpeg4Handle.pEncOps = pEncOps; + pMpeg4Enc->hMFCMpeg4Handle.pInbufOps = pInbufOps; + pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = pOutbufOps; + + /* function pointer mapping */ + pEncOps->nSize = sizeof(ExynosVideoEncOps); + pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps); + + Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps); + + /* check mandatory functions for encoder ops */ + if ((pEncOps->Init == NULL) || (pEncOps->Finalize == NULL) || + (pEncOps->Set_FrameTag == NULL) || (pEncOps->Get_FrameTag == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* check mandatory functions for buffer ops */ + if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || + (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || + (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || + (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || + (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { +#ifdef USE_DMA_BUF + v4l2MemoryType = V4L2_MEMORY_DMABUF; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_DMABUF"); +#else + v4l2MemoryType = V4L2_MEMORY_USERPTR; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_USEPTR"); +#endif + } else { + //v4l2MemoryType = V4L2_MEMORY_MMAP; + v4l2MemoryType = V4L2_MEMORY_DMABUF; //if input port is using Buffer-share mode + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY - DMABUF & MMAP"); + } + + /* alloc context, open, querycap */ + pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.pEncOps->Init(v4l2MemoryType); + if (pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + if (ret != OMX_ErrorNone) { + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pMpeg4Enc->hMFCMpeg4Handle.pEncOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pMpeg4Enc->hMFCMpeg4Handle.pInbufOps = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = NULL; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecClose(EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + FunctionIn(); + + if (pMpeg4Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + if (hMFCHandle != NULL) { + pEncOps->Finalize(hMFCHandle); + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL; + } + if (pOutbufOps != NULL) { + Exynos_OSAL_Free(pOutbufOps); + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = NULL; + } + if (pInbufOps != NULL) { + Exynos_OSAL_Free(pInbufOps); + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps = NULL; + } + if (pEncOps != NULL) { + Exynos_OSAL_Free(pEncOps); + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps = NULL; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pMpeg4Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) + pInbufOps->Run(hMFCHandle); + else if (nPortIndex == OUTPUT_PORT_INDEX) + pOutbufOps->Run(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pMpeg4Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) + pInbufOps->Stop(hMFCHandle); + else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) + pOutbufOps->Stop(hMFCHandle); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + void *hMFCHandle = pMFCMpeg4Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoEncParam *pEncParam = NULL; + + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, nOutbufs; + + FunctionIn(); + + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + Set_Mpeg4Enc_Param(pExynosComponent); + else + Set_H263Enc_Param(pExynosComponent); + + pEncParam = &pMFCMpeg4Handle->encParam; + if (pEncOps->Set_EncParam) { + if(pEncOps->Set_EncParam(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* input buffer info: only 3 config values needed */ + Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); + bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;; + bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth; + bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight; + + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "bufferConf, eColorFormat=%d, w=%d, h=%d", bufferConf.eColorFormat, bufferConf.nFrameWidth, bufferConf.nFrameHeight); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE + ||pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + pInbufOps->Set_Shareable(hMFCHandle); + + if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + inputBufferNumber = MAX_CAMERA_INPUTBUFFER_NUM; /* Need change to number of camera buffer */ + } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + /* should be done before prepare input buffer */ + if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set Enable_Cacheable for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* set input buffer geometry */ + if (pInbufOps->Set_Geometry) { + + if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* setup input buffer */ + if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; + int plane; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY && + pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + planes[plane].addr = pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]; + planes[plane].allocSize = pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane]; + planes[plane].fd = pVideoEnc->pMFCEncInputBuffer[i]->fd[plane]; + } + if (pInbufOps->Register(hMFCHandle, planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) { + ExynosVideoBuffer *pBuffer = NULL; + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + /* get input buffer info */ + if (pInbufOps->Get_Buffer) { + if (pInbufOps->Get_Buffer(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr; + pVideoEnc->pMFCEncInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd; + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize; + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]); + } + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } else { +#ifndef SLP_PLATFORM /* slp platform can go into here */ + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); + ret = OMX_ErrorNotImplemented; + goto EXIT; +#endif + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + void *hMFCHandle = NULL; + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; + if (pVideoEnc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + if (pMpeg4Enc == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + if (nPortIndex == INPUT_PORT_INDEX) { + if (pMpeg4Enc->bSourceStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + if (nPortIndex == OUTPUT_PORT_INDEX) { + if (pMpeg4Enc->bDestinationStart == OMX_FALSE) { + Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecEnqueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + int i, nOutbufs; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + FunctionIn(); + + if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pMpeg4Enc->bSourceStart == OMX_TRUE)) { + Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); + + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + + pInbufOps->Clear_Queue(hMFCHandle); + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pMpeg4Enc->bDestinationStart == OMX_TRUE)) { + OMX_U32 dataLen[2] = {0, 0}; + ExynosVideoBuffer *pBuffer = NULL; + + Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); + Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]); +// Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); +// Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + } + pOutbufOps->Clear_Queue(hMFCHandle); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + void *hMFCHandle = pMFCMpeg4Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoEncParam *pEncParam = NULL; + + ExynosVideoGeometry bufferConf; + OMX_U32 inputBufferNumber = 0; + int i, nOutbufs; + + FunctionIn(); + + if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; + OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); + if (OMXBuffer == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; + OMXBuffer->nFlags = pSrcInputData->nFlags; + Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); + + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + Set_Mpeg4Enc_Param(pExynosComponent); + else + Set_H263Enc_Param(pExynosComponent); + + if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) && + pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE)) { + ret = Mpeg4CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + void *hMFCHandle = pMFCMpeg4Handle->hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoGeometry bufferConf; + int i, nOutbufs, nPlanes, OutBufferSize; + + FunctionIn(); + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { +/*For memory Optimization */ + OutBufferSize = 1024*1024*2;//pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2; + } else { + OutBufferSize = pExynosOutputPort->extendBufferHeader[0].OMXBufferHeader->nAllocLen; + } + + /* set geometry for output (dst) */ + if (pOutbufOps->Set_Geometry) { + /* only 2 config values needed */ + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4; + else + bufferConf.eCompressionFormat = VIDEO_CODING_H263; + bufferConf.nSizeImage = OutBufferSize; + + if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + /* should be done before prepare output buffer */ + if (pOutbufOps->Enable_Cacheable) { + if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + if (pOutbufOps->Set_Shareable) { + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE + ||pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) + pOutbufOps->Set_Shareable(hMFCHandle); + } + int SetupBufferNumber = 0; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) + SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX; + else + SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber); + + if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0}; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + /* Register input buffer */ + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoPlane plane; + pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] = + (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY); + if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->pMFCEncOutputBuffer[i]->fd[0] = + Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]); + pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0] = OutBufferSize; + + plane.addr = pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]; + plane.fd = pVideoEnc->pMFCEncOutputBuffer[i]->fd[0]; + plane.allocSize = pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0]; + + if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + }else if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) { + /* Register input buffer */ + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + ExynosVideoBuffer *pBuffer = NULL; + + pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + + if (pOutbufOps->Get_Buffer) { + if (pOutbufOps->Get_Buffer(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + + for (nPlanes = 0; nPlanes < MFC_OUTPUT_BUFFER_PLANE; nPlanes++) { + pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes] = (void *)pBuffer->planes[nPlanes].addr; + pVideoEnc->pMFCEncOutputBuffer[i]->fd[nPlanes] = pBuffer->planes[nPlanes].fd; + pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[nPlanes] = pBuffer->planes[nPlanes].allocSize; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes]); + } + + pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr, + (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); + } + } + + /* start header encoding */ + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /* Register input buffer */ + /*************/ + /* TBD */ + /*************/ + ExynosVideoPlane plane; + for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) { + plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; + plane.allocSize = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; + if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Component = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Component = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMpeg4Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcMpeg4Component = &pMpeg4Enc->mpeg4Component[pDstMpeg4Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstMpeg4Component, pSrcMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Component = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Component = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pDstH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstH263Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pSrcH263Component = &pMpeg4Enc->h263Component[pDstH263Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstH263Component, pSrcH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE); + else + Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = Exynos_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 = ((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(EXYNOS_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 *pSrcMpeg4Component = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Component = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = Exynos_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 = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pSrcMpeg4Component = &pMpeg4Enc->mpeg4Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcMpeg4Component->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg4Component->eLevel; + } else { + pSrcH263Component = &pMpeg4Enc->h263Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcH263Component->eProfile; + pDstProfileLevel->eLevel = pSrcH263Component->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Component = NULL; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Component = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg4Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstMpeg4Component = &pMpeg4Enc->mpeg4Component[pSrcMpeg4Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstMpeg4Component, pSrcMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Component = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Component = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_OMX_Check_SizeVersion(pSrcH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcH263Component->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + pDstH263Component = &pMpeg4Enc->h263Component[pSrcH263Component->nPortIndex]; + + Exynos_OSAL_Memcpy(pDstH263Component, pSrcH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE)) { + pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + //((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; + } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE)) { + pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + //((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 *pDstMpeg4Component = NULL; + OMX_VIDEO_PARAM_H263TYPE *pDstH263Component = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = Exynos_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 = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + /* + * To do: Check validity of profile & level parameters + */ + + pDstMpeg4Component = &pMpeg4Enc->mpeg4Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg4Component->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg4Component->eLevel = pSrcProfileLevel->eLevel; + } else { + /* + * To do: Check validity of profile & level parameters + */ + + pDstH263Component = &pMpeg4Enc->h263Component[pSrcProfileLevel->nPortIndex]; + pDstH263Component->eProfile = pSrcProfileLevel->eProfile; + pDstH263Component->eLevel = pSrcProfileLevel->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = Exynos_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 = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->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 = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle; + + switch (nIndex) { + case OMX_IndexConfigVideoIntraPeriod: + { + 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 = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + if (ret == OMX_ErrorNone) + pVideoEnc->configChange = OMX_TRUE; + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) { + *pIndexType = OMX_IndexConfigVideoIntraPeriod; + ret = OMX_ErrorNone; + } else { + ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_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; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { /* supports only one role */ + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + codecType = ((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE); + else + Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;; + EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle; + OMX_PTR hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + OMX_COLOR_FORMATTYPE eColorFormat; + + ExynosVideoEncOps *pEncOps = NULL; + ExynosVideoEncBufferOps *pInbufOps = NULL; + ExynosVideoEncBufferOps *pOutbufOps = NULL; + + CSC_METHOD csc_method = CSC_METHOD_SW; + int i = 0; + + FunctionIn(); + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE; + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE; + pVideoEnc->bFirstOutput = OMX_FALSE; + pExynosComponent->bUseFlagEOF = OMX_TRUE; + pExynosComponent->bSaveFlagEOS = OMX_FALSE; + + eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat; + if (pExynosInputPort->bStoreMetaData == OMX_TRUE) { +#ifndef SLP_PLATFORM /* we do not use OMX_COLOR_FormatAndroidOpaque */ + if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + pExynosInputPort->bufferProcessType = BUFFER_COPY; + } else { + pExynosInputPort->bufferProcessType = BUFFER_SHARE; + } +#endif + } else { + if (eColorFormat == OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd || + eColorFormat == OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd) { + pExynosInputPort->bufferProcessType = BUFFER_SHARE; + } else { + pExynosInputPort->bufferProcessType = BUFFER_COPY; + } + } + + /* Mpeg4/H.263 Codec Open */ + ret = Mpeg4CodecOpen(pMpeg4Enc); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + + if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); + /* Use ION Allocator */ + /*Alloc Y-Buffer */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY); + pVideoEnc->pMFCEncInputBuffer[i]->fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; + /*Alloc C-Buffer */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY); + pVideoEnc->pMFCEncInputBuffer[i]->fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; + + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + + if ((pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] == NULL) || + (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] == NULL)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* MFC input buffers are 1 plane. */ + pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[2] = NULL; + pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; + pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); + + Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); + } + } else { + ret = Mpeg4CodecSrcInit(pOMXComponent); + if (ret != OMX_ErrorNone) + goto EXIT; + } + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); + Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + pMpeg4Enc->bSourceStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg4Enc->hSourceStartEvent); + pMpeg4Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalCreate(&pMpeg4Enc->hDestinationStartEvent); + + Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0; + pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp = 0; + + pExynosComponent->getAllDelayBuffer = OMX_FALSE; + +#if 0//defined(USE_CSC_GSCALER) + csc_method = CSC_METHOD_HW; //in case of Use ION buffer. +#endif + pVideoEnc->csc_handle = csc_init(csc_method); + if (pVideoEnc->csc_handle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pVideoEnc->csc_set_format = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle); + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + OMX_PTR hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + + int i = 0, plane = 0; + + FunctionIn(); + + if (pVideoEnc->csc_handle != NULL) { + csc_deinit(pVideoEnc->csc_handle); + pVideoEnc->csc_handle = NULL; + } + + Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationStartEvent); + pMpeg4Enc->hDestinationStartEvent = NULL; + pMpeg4Enc->bDestinationStart = OMX_FALSE; + Exynos_OSAL_SignalTerminate(pMpeg4Enc->hSourceStartEvent); + pMpeg4Enc->hSourceStartEvent = NULL; + pMpeg4Enc->bSourceStart = OMX_FALSE; + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]); + pVideoEnc->pMFCEncInputBuffer[i] = NULL; + } + } + } + + Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); + } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { + if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) { +#ifndef SLP_PLATFORM /* do not use ion */ + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + if (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] != NULL) + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]); + } +#endif + Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]); + pVideoEnc->pMFCEncInputBuffer[i] = NULL; + } + } + + Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); + Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); + } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) { + /*************/ + /* TBD */ + /*************/ + /* Does not require any actions. */ + } + Mpeg4CodecClose(pMpeg4Enc); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + OMX_U32 oneFrameSize = pSrcInputData->dataLen; + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + int i; + + FunctionIn(); + + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) { + ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData); +// if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) + if (ret != OMX_ErrorNone) + goto EXIT; + } + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) { + ret = Mpeg4CodecDstSetup(pOMXComponent); + } + + if (pVideoEnc->configChange == OMX_TRUE) { + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) + Change_Mpeg4Enc_Param(pExynosComponent); + else + Change_H263Enc_Param(pExynosComponent); + + pVideoEnc->configChange = OMX_FALSE; + } + + + if ((pSrcInputData->dataLen >= 0) || + ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL}; + ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE]; + int plane; + + pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp; + pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags); + pEncOps->Set_FrameTag(hMFCHandle, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp); + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + + /* queue work for input buffer */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_Mpeg4Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader); + pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; + pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2; + + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); +//#ifdef USE_METADATABUFFERTYPE + if ((codecReturn == VIDEO_ERROR_NOBUFFERS) && + /*(pExynosInputPort->bStoreMetaData == OMX_TRUE) &&*/ + (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) { + OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0}; + nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * + ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight); + nAllocLen[1] = ALIGN(nAllocLen[0]/2,256); + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane]; + planes[plane].allocSize = nAllocLen[plane]; + planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane]; + } + + /* Register input buffer */ + if (pInbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, + planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); + + } +//#endif + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX); + if (pMpeg4Enc->bSourceStart == OMX_FALSE) { + pMpeg4Enc->bSourceStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + if (pMpeg4Enc->bDestinationStart == OMX_FALSE) { + pMpeg4Enc->bDestinationStart = OMX_TRUE; + Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent); + Exynos_OSAL_SleepMillisec(0); + } + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps; + ExynosVideoBuffer *pVideoBuffer; + + FunctionIn(); + + pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); + + pSrcOutputData->dataLen = 0; + pSrcOutputData->usedDataLen = 0; + pSrcOutputData->remainDataLen = 0; + pSrcOutputData->nFlags = 0; + pSrcOutputData->timeStamp = 0; + + if (pVideoBuffer == NULL) { + pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; + pSrcOutputData->allocSize = 0; + pSrcOutputData->pPrivate = NULL; + pSrcOutputData->bufferHeader = NULL; + } else { + int plane = 0; + for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { + pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; + pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + } + pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize + + pVideoBuffer->planes[1].allocSize + + pVideoBuffer->planes[2].allocSize; + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) { + if (i >= MFC_INPUT_BUFFER_NUM_MAX) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + i++; + } + pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; + pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i]; + } + + /* For Share Buffer */ + pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + OMX_U32 dataLen = 0; + ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; + + FunctionIn(); + + if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer, + (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); + + if (codecReturn != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode; + goto EXIT; + } + Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps; + ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps; + ExynosVideoBuffer *pVideoBuffer; + ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + ExynosVideoGeometry bufferGeometry; + OMX_S32 indexTimestamp = 0; + + FunctionIn(); + + if (pMpeg4Enc->bDestinationStart == OMX_FALSE) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + ret = OMX_ErrorNone; + goto EXIT; + } + + pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp++; + pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; + + pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; + pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; + pDstOutputData->allocSize = pVideoBuffer->planes[0].allocSize; + pDstOutputData->dataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize; + pDstOutputData->usedDataLen = 0; + pDstOutputData->pPrivate = pVideoBuffer; + /* For Share Buffer */ + pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; + + if (pVideoEnc->bFirstOutput == OMX_FALSE) { + OMX_U8 *p = NULL; + + pDstOutputData->timeStamp = 0; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + pVideoEnc->bFirstOutput = OMX_TRUE; + } else { + indexTimestamp = pEncOps->Get_FrameTag(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle); + if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp]; + } else { + pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; + pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; + } + + pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (pVideoBuffer->frameType == VIDEO_FRAME_I) + pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || + ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags); + pDstOutputData->remainDataLen = 0; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = Exynos_Mpeg4Enc_SrcIn(pOMXComponent, pSrcInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosInputPort->bufferProcessType & BUFFER_COPY) { + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + } + if ((pMpeg4Enc->bSourceStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Enc->hSourceStartEvent); + } + + ret = Exynos_Mpeg4Enc_SrcOut(pOMXComponent, pSrcOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent); + } + } + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) { + ret = Exynos_Mpeg4Enc_DstIn(pOMXComponent, pDstInputData); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_Mpeg4Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { + Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME); + Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent); + } + } + ret = Exynos_Mpeg4Enc_DstOut(pOMXComponent, pDstOutputData); + if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__); + pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pExynosComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( + OMX_HANDLETYPE hComponent, + OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType = -1; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_ENC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_ENC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pExynosComponent->codecType = HW_VIDEO_ENC_CODEC; + + pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pExynosComponent->componentName == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4ENC_HANDLE)); + if (pMpeg4Enc == NULL) { + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MPEG4ENC_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + Exynos_OSAL_Memset(pMpeg4Enc, 0, sizeof(EXYNOS_MPEG4ENC_HANDLE)); + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; + pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Enc; + pMpeg4Enc->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG4_ENC); + else + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H263_ENC); + + + /* In case of BUFFER_COPY mode + bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR + bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP + In case of BUFFER_SHARE + bShareableBuf should be TRUE, FALSE is ignored + */ + pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf = OMX_FALSE; //Check bStoreMetaData in Init function + + /* Set componentVersion */ + pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; + pExynosComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Input port */ + pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate= (15 << 16); + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); +#ifdef SLP_PLATFORM + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; +#else + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +#endif + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + /* Output port */ + pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pExynosPort->portDefinition.format.video.nBitrate = 64000; + pExynosPort->portDefinition.format.video.xFramerate= (15 << 16); + pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + if (codecType == CODEC_TYPE_MPEG4) { + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pExynosPort->portDefinition.format.video.pNativeRender = 0; + pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pExynosPort->portDefinition.bEnabled = OMX_TRUE; + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portWayType = WAY2_PORT; + + 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 = &Exynos_Mpeg4Enc_GetParameter; + pOMXComponent->SetParameter = &Exynos_Mpeg4Enc_SetParameter; + pOMXComponent->GetConfig = &Exynos_Mpeg4Enc_GetConfig; + pOMXComponent->SetConfig = &Exynos_Mpeg4Enc_SetConfig; + pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Enc_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; + + pExynosComponent->exynos_codec_componentInit = &Exynos_Mpeg4Enc_Init; + pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Enc_Terminate; + + pVideoEnc->exynos_codec_srcInputProcess = &Exynos_Mpeg4Enc_srcInputBufferProcess; + pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Enc_srcOutputBufferProcess; + pVideoEnc->exynos_codec_dstInputProcess = &Exynos_Mpeg4Enc_dstInputBufferProcess; + pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Enc_dstOutputBufferProcess; + + pVideoEnc->exynos_codec_start = &Mpeg4CodecStart; + pVideoEnc->exynos_codec_stop = &Mpeg4CodecStop; + pVideoEnc->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun; + pVideoEnc->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnqueueAllBuffer; + + pVideoEnc->exynos_checkInputFrame = NULL; + pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; + pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + +#ifndef SLP_PLATFORM /* do not use ion */ + pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); + if (pVideoEnc->hSharedMemory == NULL) { + Exynos_OSAL_Free(pMpeg4Enc); + pMpeg4Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } +#endif + pExynosComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; + EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; +#ifndef SLP_PLATFORM /* do not use ion */ + Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory); +#endif + Exynos_OSAL_Free(pExynosComponent->componentName); + pExynosComponent->componentName = NULL; + + pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; + if (pMpeg4Enc != NULL) { + Exynos_OSAL_Free(pMpeg4Enc); + pMpeg4Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; + } + + ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h new file mode 100644 index 0000000..37792bb --- /dev/null +++ b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h @@ -0,0 +1,86 @@ +/* + * + * 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 Exynos_OMX_Mpeg4enc.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_MPEG4_ENC_COMPONENT +#define EXYNOS_OMX_MPEG4_ENC_COMPONENT + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + +#include "ExynosVideoApi.h" + +typedef enum _CODEC_TYPE +{ + CODEC_TYPE_H263, + CODEC_TYPE_MPEG4 +} CODEC_TYPE; + +typedef struct _EXYNOS_MFC_MPEG4ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; + OMX_U32 indexTimestamp; + OMX_U32 outputIndexTimestamp; + OMX_BOOL bConfiguredMFCSrc; + OMX_BOOL bConfiguredMFCDst; + CODEC_TYPE codecType; + + ExynosVideoDecOps *pEncOps; + ExynosVideoDecBufferOps *pInbufOps; + ExynosVideoDecBufferOps *pOutbufOps; + ExynosVideoEncParam encParam; +} EXYNOS_MFC_MPEG4ENC_HANDLE; + +typedef struct _EXYNOS_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 */ + EXYNOS_MFC_MPEG4ENC_HANDLE hMFCMpeg4Handle; + + OMX_BOOL bSourceStart; + OMX_BOOL bDestinationStart; + OMX_HANDLETYPE hSourceStartEvent; + OMX_HANDLETYPE hDestinationStartEvent; +} EXYNOS_MPEG4ENC_HANDLE; + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/openmax/component/video/enc/mpeg4/Makefile.am b/openmax/component/video/enc/mpeg4/Makefile.am new file mode 100644 index 0000000..dda1a4f --- /dev/null +++ b/openmax/component/video/enc/mpeg4/Makefile.am @@ -0,0 +1,36 @@ +lib_LTLIBRARIES = libOMX.Exynos.M4V.Encoder.la +libdir = @prefix@/lib/omx + +libOMX_Exynos_M4V_Encoder_la_SOURCES = Exynos_OMX_Mpeg4enc.c \ + Exynos_OMX_Mpeg4enc.h \ + library_register.c \ + library_register.h + +libOMX_Exynos_M4V_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/exynos4/libcodec/video/v4l2/libExynosVideoApi.la \ + $(top_builddir)/exynos/libv4l2/libexynosv4l2.la + + +libOMX_Exynos_M4V_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/core \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/enc \ + -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/exynos4/libcsc \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ + -I$(top_srcdir)/exynos/include + + +if BOARD_NONBLOCK_MODE_PROCESS +libOMX_Exynos_M4V_Encoder_la_CFLAGS += -DNONBLOCK_MODE_PROCESS +endif + +if BOARD_USE_METADATABUFFERTYPE +libOMX_Exynos_M4V_Encoder_la_CFLAGS += -DUSE_METADATABUFFERTYPE +endif + +libOMX_Exynos_M4V_Encoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/enc/mpeg4/library_register.c b/openmax/component/video/enc/mpeg4/library_register.c new file mode 100644 index 0000000..34c59ba --- /dev/null +++ b/openmax/component/video/enc/mpeg4/library_register.c @@ -0,0 +1,62 @@ +/* + * + * 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 library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "library_register.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_MPEG4_ENC" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent) +{ + FunctionIn(); + + if (ppExynosComponent == NULL) + goto EXIT; + + /* component 1 - video encoder MPEG4 */ + Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_ENC); + Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE); + ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video encoder H.263 */ + Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_H263_ENC); + Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_H263_ENC_ROLE); + ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} diff --git a/openmax/component/video/enc/mpeg4/library_register.h b/openmax/component/video/enc/mpeg4/library_register.h new file mode 100644 index 0000000..60f6037 --- /dev/null +++ b/openmax/component/video/enc/mpeg4/library_register.h @@ -0,0 +1,59 @@ +/* + * + * 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 library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_MPEG4_ENC_REG +#define EXYNOS_OMX_MPEG4_ENC_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Component.h" +#include "Exynos_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define EXYNOS_OMX_COMPONENT_MPEG4_ENC "OMX.Exynos.MPEG4.Encoder" +#define EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE "video_encoder.mpeg4" + +/* H.263 */ +#define EXYNOS_OMX_COMPONENT_H263_ENC "OMX.Exynos.H263.Encoder" +#define EXYNOS_OMX_COMPONENT_H263_ENC_ROLE "video_encoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/openmax/core/Android.mk b/openmax/core/Android.mk new file mode 100644 index 0000000..4b66d26 --- /dev/null +++ b/openmax/core/Android.mk @@ -0,0 +1,34 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OMX_Component_Register.c \ + Exynos_OMX_Core.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libExynosOMX_Core + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL libExynosOMX_Basecomponent +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils \ + libExynosOMX_Resourcemanager + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_TOP)/component/common + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_SHARED_LIBRARY) + diff --git a/openmax/core/Exynos_OMX_Component_Register.c b/openmax/core/Exynos_OMX_Component_Register.c new file mode 100644 index 0000000..37415c2 --- /dev/null +++ b/openmax/core/Exynos_OMX_Component_Register.c @@ -0,0 +1,264 @@ +/* + * + * 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 Exynos_OMX_Component_Register.c + * @brief Exynos OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OMX_Component.h" +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OSAL_Library.h" +#include "Exynos_OMX_Component_Register.h" +#include "Exynos_OMX_Macros.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_COMP_REGS" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_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 (*Exynos_OMX_COMPONENT_Library_Register)(ExynosRegisterComponentType **exynosComponents); + ExynosRegisterComponentType **exynosComponentsTemp; + EXYNOS_OMX_COMPONENT_REGLIST *componentList; + + FunctionIn(); + + dir = opendir(EXYNOS_OMX_INSTALL_PATH); + if (dir == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + componentList = (EXYNOS_OMX_COMPONENT_REGLIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + Exynos_OSAL_Memset(componentList, 0, sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + libName = Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); + + while ((d = readdir(dir)) != NULL) { + OMX_HANDLETYPE soHandle; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s", d->d_name); + + if (Exynos_OSAL_Strncmp(d->d_name, "libOMX.Exynos.", Exynos_OSAL_Strlen("libOMX.Exynos.")) == 0) { + Exynos_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); + Exynos_OSAL_Strcpy(libName, EXYNOS_OMX_INSTALL_PATH); + Exynos_OSAL_Strcat(libName, d->d_name); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Path & libName : %s", libName); + if ((soHandle = Exynos_OSAL_dlopen(libName, RTLD_LAZY)) != NULL) { + Exynos_OSAL_dlerror(); /* clear error*/ + if ((Exynos_OMX_COMPONENT_Library_Register = Exynos_OSAL_dlsym(soHandle, "Exynos_OMX_COMPONENT_Library_Register")) != NULL) { + int i = 0; + unsigned int j = 0; + + componentNum = (*Exynos_OMX_COMPONENT_Library_Register)(NULL); + exynosComponentsTemp = (ExynosRegisterComponentType **)Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType*) * componentNum); + for (i = 0; i < componentNum; i++) { + exynosComponentsTemp[i] = Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType)); + Exynos_OSAL_Memset(exynosComponentsTemp[i], 0, sizeof(ExynosRegisterComponentType)); + } + (*Exynos_OMX_COMPONENT_Library_Register)(exynosComponentsTemp); + + for (i = 0; i < componentNum; i++) { + Exynos_OSAL_Strcpy(componentList[totalCompNum].component.componentName, exynosComponentsTemp[i]->componentName); + for (j = 0; j < exynosComponentsTemp[i]->totalRoleNum; j++) + Exynos_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], exynosComponentsTemp[i]->roles[j]); + componentList[totalCompNum].component.totalRoleNum = exynosComponentsTemp[i]->totalRoleNum; + + Exynos_OSAL_Strcpy(componentList[totalCompNum].libName, libName); + + totalCompNum++; + } + for (i = 0; i < componentNum; i++) { + Exynos_OSAL_Free(exynosComponentsTemp[i]); + } + + Exynos_OSAL_Free(exynosComponentsTemp); + } else { + if ((errorMsg = Exynos_OSAL_dlerror()) != NULL) + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlsym failed: %s", errorMsg); + } + Exynos_OSAL_dlclose(soHandle); + } else { + Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlopen failed: %s", Exynos_OSAL_dlerror()); + } + } else { + /* not a component name line. skip */ + continue; + } + } + + Exynos_OSAL_Free(libName); + + closedir(dir); + + *compList = componentList; + *compNum = totalCompNum; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_Component_Unregister(EXYNOS_OMX_COMPONENT_REGLIST *componentList) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + Exynos_OSAL_Memset(componentList, 0, sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + Exynos_OSAL_Free(componentList); + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_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 Exynos_OMX_ComponentLoad(EXYNOS_OMX_COMPONENT *exynos_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_HANDLETYPE libHandle; + OMX_COMPONENTTYPE *pOMXComponent; + + FunctionIn(); + + OMX_ERRORTYPE (*Exynos_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + + libHandle = Exynos_OSAL_dlopen((OMX_STRING)exynos_component->libName, RTLD_LAZY); + if (!libHandle) { + ret = OMX_ErrorInvalidComponentName; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); + goto EXIT; + } + + Exynos_OMX_ComponentInit = Exynos_OSAL_dlsym(libHandle, "Exynos_OMX_ComponentInit"); + if (!Exynos_OMX_ComponentInit) { + Exynos_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); + INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); + ret = (*Exynos_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, (OMX_STRING)exynos_component->componentName); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Free(pOMXComponent); + Exynos_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } else { + if (Exynos_OMX_ComponentAPICheck(pOMXComponent) != OMX_ErrorNone) { + if (NULL != pOMXComponent->ComponentDeInit) + pOMXComponent->ComponentDeInit(pOMXComponent); + Exynos_OSAL_Free(pOMXComponent); + Exynos_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + exynos_component->libHandle = libHandle; + exynos_component->pOMXComponent = pOMXComponent; + ret = OMX_ErrorNone; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OMX_ComponentUnload(EXYNOS_OMX_COMPONENT *exynos_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + + FunctionIn(); + + if (!exynos_component) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = exynos_component->pOMXComponent; + if (pOMXComponent != NULL) { + pOMXComponent->ComponentDeInit(pOMXComponent); + Exynos_OSAL_Free(pOMXComponent); + exynos_component->pOMXComponent = NULL; + } + + if (exynos_component->libHandle != NULL) { + Exynos_OSAL_dlclose(exynos_component->libHandle); + exynos_component->libHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + diff --git a/openmax/core/Exynos_OMX_Component_Register.h b/openmax/core/Exynos_OMX_Component_Register.h new file mode 100644 index 0000000..1860978 --- /dev/null +++ b/openmax/core/Exynos_OMX_Component_Register.h @@ -0,0 +1,75 @@ +/* + * + * 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 Exynos_OMX_Component_Register.h + * @brief Exynos OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_COMPONENT_REG +#define EXYNOS_OMX_COMPONENT_REG + +#include "Exynos_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_Component.h" + + +typedef struct _ExynosRegisterComponentType +{ + OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; + OMX_U8 roles[MAX_OMX_COMPONENT_ROLE_NUM][MAX_OMX_COMPONENT_ROLE_SIZE]; + OMX_U32 totalRoleNum; +} ExynosRegisterComponentType; + +typedef struct _EXYNOS_OMX_COMPONENT_REGLIST +{ + ExynosRegisterComponentType component; + OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; +} EXYNOS_OMX_COMPONENT_REGLIST; + +struct EXYNOS_OMX_COMPONENT; +typedef struct _EXYNOS_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 _EXYNOS_OMX_COMPONENT *nextOMXComp; +} EXYNOS_OMX_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum); +OMX_ERRORTYPE Exynos_OMX_Component_Unregister(EXYNOS_OMX_COMPONENT_REGLIST *componentList); +OMX_ERRORTYPE Exynos_OMX_ComponentLoad(EXYNOS_OMX_COMPONENT *exynos_component); +OMX_ERRORTYPE Exynos_OMX_ComponentUnload(EXYNOS_OMX_COMPONENT *exynos_component); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/core/Exynos_OMX_Core.c b/openmax/core/Exynos_OMX_Core.c new file mode 100644 index 0000000..4e12c13 --- /dev/null +++ b/openmax/core/Exynos_OMX_Core.c @@ -0,0 +1,364 @@ +/* + * + * 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 Exynos_OMX_Core.c + * @brief Exynos OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OMX_Core.h" +#include "Exynos_OMX_Component_Register.h" +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_OMX_Resourcemanager.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_OMX_CORE" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +static int gInitialized = 0; +static OMX_U32 gComponentNum = 0; + +static EXYNOS_OMX_COMPONENT_REGLIST *gComponentList = NULL; +static EXYNOS_OMX_COMPONENT *gLoadComponentList = NULL; +static OMX_HANDLETYPE ghLoadComponentListMutex = NULL; + + +OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Init(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (gInitialized == 0) { + if (Exynos_OMX_Component_Register(&gComponentList, &gComponentNum)) { + ret = OMX_ErrorInsufficientResources; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : %s", "OMX_ErrorInsufficientResources"); + goto EXIT; + } + + ret = Exynos_OMX_ResourceManager_Init(); + if (OMX_ErrorNone != ret) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OMX_ResourceManager_Init failed"); + goto EXIT; + } + + ret = Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex); + if (OMX_ErrorNone != ret) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex) failed"); + goto EXIT; + } + + gInitialized = 1; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_Init : %s", "OMX_ErrorNone"); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Deinit(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + Exynos_OSAL_MutexTerminate(ghLoadComponentListMutex); + ghLoadComponentListMutex = NULL; + + Exynos_OMX_ResourceManager_Deinit(); + + if (OMX_ErrorNone != Exynos_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 Exynos_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 Exynos_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; + EXYNOS_OMX_COMPONENT *loadComponent; + EXYNOS_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; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ComponentName : %s", cComponentName); + + for (i = 0; i < gComponentNum; i++) { + if (Exynos_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { + loadComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT)); + Exynos_OSAL_Memset(loadComponent, 0, sizeof(EXYNOS_OMX_COMPONENT)); + + Exynos_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); + Exynos_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); + ret = Exynos_OMX_ComponentLoad(loadComponent); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Free(loadComponent); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData); + if (ret != OMX_ErrorNone) { + Exynos_OMX_ComponentUnload(loadComponent); + Exynos_OSAL_Free(loadComponent); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + Exynos_OSAL_MutexLock(ghLoadComponentListMutex); + if (gLoadComponentList == NULL) { + gLoadComponentList = loadComponent; + } else { + currentComponent = gLoadComponentList; + while (currentComponent->nextOMXComp != NULL) { + currentComponent = currentComponent->nextOMXComp; + } + currentComponent->nextOMXComp = loadComponent; + } + Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); + + *pHandle = loadComponent->pOMXComponent; + ret = OMX_ErrorNone; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_GetHandle : %s", "OMX_ErrorNone"); + goto EXIT; + } + } + + ret = OMX_ErrorComponentNotFound; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_COMPONENT *currentComponent; + EXYNOS_OMX_COMPONENT *deleteComponent; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + if (!hComponent) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_MutexLock(ghLoadComponentListMutex); + currentComponent = gLoadComponentList; + if (gLoadComponentList->pOMXComponent == hComponent) { + deleteComponent = gLoadComponentList; + gLoadComponentList = gLoadComponentList->nextOMXComp; + } else { + while ((currentComponent != NULL) && (((EXYNOS_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) + currentComponent = currentComponent->nextOMXComp; + + if (((EXYNOS_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) { + deleteComponent = currentComponent->nextOMXComp; + currentComponent->nextOMXComp = deleteComponent->nextOMXComp; + } else if (currentComponent == NULL) { + ret = OMX_ErrorComponentNotFound; + Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); + goto EXIT; + } + } + Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); + + Exynos_OMX_ComponentUnload(deleteComponent); + Exynos_OSAL_Free(deleteComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_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 Exynos_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI) +{ + OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; + +EXIT: + return ret; +} + +OMX_API OMX_ERRORTYPE Exynos_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 (Exynos_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { + if (compNames != NULL) { + Exynos_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); + } + *pNumComps = (*pNumComps + 1); + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE Exynos_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 (Exynos_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++) { + Exynos_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); + } + } + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/core/Exynos_OMX_Core.h b/openmax/core/Exynos_OMX_Core.h new file mode 100644 index 0000000..655becd --- /dev/null +++ b/openmax/core/Exynos_OMX_Core.h @@ -0,0 +1,89 @@ +/* + * + * 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 Exynos_OMX_Core.h + * @brief Exynos OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_CORE +#define EXYNOS_OMX_CORE + +#include "Exynos_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SLP_PLATFORM /* build env */ +#define Exynos_OMX_Init OMX_Init +#define Exynos_OMX_Deinit OMX_Deinit +#define Exynos_OMX_ComponentNameEnum OMX_ComponentNameEnum +#define Exynos_OMX_GetHandle OMX_GetHandle +#define Exynos_OMX_FreeHandle OMX_FreeHandle +#define Exynos_OMX_SetupTunnel OMX_SetupTunnel +#define Exynos_OMX_GetContentPipe OMX_GetContentPipe +#define Exynos_OMX_GetComponentsOfRole OMX_GetComponentsOfRole +#define Exynos_OMX_GetRolesOfComponent OMX_GetRolesOfComponent +#endif + +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Init(void); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Deinit(void); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE *pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE *pCallBacks); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE Exynos_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE Exynos_OMX_GetComponentsOfRole( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); +EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE Exynos_OMX_GetRolesOfComponent( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openmax/core/Makefile.am b/openmax/core/Makefile.am new file mode 100644 index 0000000..1a7f43f --- /dev/null +++ b/openmax/core/Makefile.am @@ -0,0 +1,29 @@ +lib_LTLIBRARIES = libExynosOMX_Core.la + +libExynosOMX_Core_la_SOURCES = Exynos_OMX_Component_Register.c \ + Exynos_OMX_Component_Register.h \ + Exynos_OMX_Core.c \ + Exynos_OMX_Core.h + +libExynosOMX_Core_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ + $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la + +libExynosOMX_Core_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/component/common + +includelibExynosOMX_Coredir = $(includedir)/libomxil-e3250 +includelibExynosOMX_Core_HEADERS = $(top_srcdir)/openmax/include/khronos/OMX_Audio.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Core.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Image.h \ + $(top_srcdir)/openmax/include/khronos/OMX_IVCommon.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Types.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Component.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Index.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Other.h \ + $(top_srcdir)/openmax/include/khronos/OMX_Video.h \ + $(top_srcdir)/openmax/include/khronos/OMX_ContentPipe.h \ + $(top_srcdir)/openmax/include/exynos/Exynos_OMX_Def.h \ + $(top_srcdir)/openmax/include/exynos/Exynos_OMX_Macros.h diff --git a/openmax/include/exynos/Exynos_OMX_Def.h b/openmax/include/exynos/Exynos_OMX_Def.h new file mode 100644 index 0000000..6b4acbb --- /dev/null +++ b/openmax/include/exynos/Exynos_OMX_Def.h @@ -0,0 +1,293 @@ +/* + * + * 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 Exynos_OMX_Def.h + * @brief Exynos_OMX specific define + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_DEF +#define EXYNOS_OMX_DEF + +#include "OMX_Types.h" +#include "OMX_IVCommon.h" + +#define VERSIONMAJOR_NUMBER 1 +#ifndef SLP_PLATFORM /* omx version */ +#define VERSIONMINOR_NUMBER 0 +#else +#define VERSIONMINOR_NUMBER 1 +#endif +#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 40 +#define MAX_FLAGS 40 + +#define MAX_BUFFER_PLANE 3 + +#ifdef SLP_PLATFORM /* build env */ +#define EXYNOS_OMX_INSTALL_PATH "/usr/lib/omx/" +#else +#define EXYNOS_OMX_INSTALL_PATH "/system/lib/omx/" +#endif + +typedef enum _EXYNOS_CODEC_TYPE +{ + SW_CODEC, + HW_VIDEO_DEC_CODEC, + HW_VIDEO_ENC_CODEC, + HW_AUDIO_DEC_CODEC, + HW_AUDIO_ENC_CODEC +} EXYNOS_CODEC_TYPE; + +typedef struct _EXYNOS_OMX_PRIORITYMGMTTYPE +{ + OMX_U32 nGroupPriority; /* the value 0 represents the highest priority */ + /* for a group of components */ + OMX_U32 nGroupID; +} EXYNOS_OMX_PRIORITYMGMTTYPE; + +typedef enum _EXYNOS_OMX_INDEXTYPE +{ +#define EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.ThumbnailMode" + OMX_IndexVendorThumbnailMode = 0x7F000001, +#define EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD "OMX.SEC.index.VideoIntraPeriod" + OMX_IndexConfigVideoIntraPeriod = 0x7F000002, +#ifdef USE_S3D_SUPPORT +#define EXYNOS_INDEX_PARAM_GET_S3D "OMX.SEC.index.S3DMode" + OMX_IndexVendorS3DMode = 0x7F000003, +#endif + +#ifdef SLP_PLATFORM +#define EXYNOS_INDEX_PARAM_ENABLE_PB "OMX.SEC.index.enablePlatformSpecificBuffers" + OMX_IndexParamEnablePlatformSpecificBuffers = 0x7F000011, +#else + /* for Android Native Window */ +#define EXYNOS_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers" + OMX_IndexParamEnableAndroidBuffers = 0x7F000011, +#endif +#define EXYNOS_INDEX_PARAM_GET_ANB "OMX.google.android.index.getAndroidNativeBufferUsage" + OMX_IndexParamGetAndroidNativeBuffer = 0x7F000012, +#define EXYNOS_INDEX_PARAM_USE_ANB "OMX.google.android.index.useAndroidNativeBuffer" + OMX_IndexParamUseAndroidNativeBuffer = 0x7F000013, + /* for Android Store Metadata Inbuffer */ +#define EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.google.android.index.storeMetaDataInBuffers" + OMX_IndexParamStoreMetaDataBuffer = 0x7F000014, + /* prepend SPS/PPS to I/IDR for H.264 Encoder */ +#define EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR "OMX.SEC.index.prependSPSPPSToIDRFrames" + OMX_IndexParamPrependSPSPPSToIDR = 0x7F000015, +#ifdef SLP_PLATFORM + /* avi demux timestamp reorder */ +#define EXYNOS_INDEX_PARAM_ENABLE_TS_REORDER "OMX.SEC.index.enableTimestampReorder" + OMX_IndexParamEnableTimestampReorder = 0x7F000016, + + /* DMA FD output for hdcp */ +#define EXYNOS_INDEX_PARAM_ENC_SHARED_OUTPUT_FD "OMX.SEC.index.encoderSharedOutputFD" + OMX_IndexParamSharedOutputFD = 0x7F000017, +#endif + + + /* for Android PV OpenCore*/ + OMX_COMPONENT_CAPABILITY_TYPE_INDEX = 0xFF7A347 +} EXYNOS_OMX_INDEXTYPE; + +typedef enum _EXYNOS_OMX_ERRORTYPE +{ + OMX_ErrorNoEOF = (OMX_S32) 0x90000001, + OMX_ErrorInputDataDecodeYet = (OMX_S32) 0x90000002, + OMX_ErrorInputDataEncodeYet = (OMX_S32) 0x90000003, + OMX_ErrorCodecInit = (OMX_S32) 0x90000004, + OMX_ErrorCodecDecode = (OMX_S32) 0x90000005, + OMX_ErrorCodecEncode = (OMX_S32) 0x90000006, + OMX_ErrorCodecFlush = (OMX_S32) 0x90000007, + OMX_ErrorOutputBufferUseYet = (OMX_S32) 0x90000008, + OMX_ErrorCorruptedFrame = (OMX_S32) 0x90000009 +} EXYNOS_OMX_ERRORTYPE; + +typedef enum _EXYNOS_OMX_COMMANDTYPE +{ + EXYNOS_OMX_CommandComponentDeInit = 0x7F000001, + EXYNOS_OMX_CommandEmptyBuffer, + EXYNOS_OMX_CommandFillBuffer, + EXYNOS_OMX_CommandFakeBuffer +} EXYNOS_OMX_COMMANDTYPE; + +typedef enum _EXYNOS_OMX_TRANS_STATETYPE { + EXYNOS_OMX_TransStateInvalid, + EXYNOS_OMX_TransStateLoadedToIdle, + EXYNOS_OMX_TransStateIdleToExecuting, + EXYNOS_OMX_TransStateExecutingToIdle, + EXYNOS_OMX_TransStateIdleToLoaded, + EXYNOS_OMX_TransStateMax = 0X7FFFFFFF +} EXYNOS_OMX_TRANS_STATETYPE; + +typedef enum _EXYNOS_OMX_COLOR_FORMATTYPE { +#ifdef SLP_PLATFORM /* dmabuf fd color format */ + OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd = 0x7F000001, /* use same value with phyaddr */ + OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd = 0x7F000002, +#else + OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */ + OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002, +#endif + OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003, + OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, /* 0x7FC00002 */ + OMX_SEC_COLOR_FormatNV21LPhysicalAddress = 0x7F000010, + OMX_SEC_COLOR_FormatNV21Linear = 0x7F000011, + /* to copy a encoded data for drm component using gsc or fimc */ + OMX_SEC_COLOR_FormatEncodedData = OMX_COLOR_FormatYCbYCr, + +#ifdef USE_KHRONOS_OMX_HEADER + /* for Android SurfaceMediaSource*/ + OMX_COLOR_FormatAndroidOpaque = 0x7F000789 +#endif +}EXYNOS_OMX_COLOR_FORMATTYPE; + +typedef enum _EXYNOS_OMX_SUPPORTFORMAT_TYPE +{ + supportFormat_0 = 0x00, + supportFormat_1, + supportFormat_2, + supportFormat_3, + supportFormat_4, + supportFormat_5, + supportFormat_6, + supportFormat_7 +} EXYNOS_OMX_SUPPORTFORMAT_TYPE; + +typedef enum _EXYNOS_OMX_BUFFERPROCESS_TYPE +{ + BUFFER_DEFAULT = 0x00, + BUFFER_COPY = 0x01, + BUFFER_SHARE = 0x02, + BUFFER_METADATA = 0x04, + BUFFER_PBSHARE = 0x08 /* to get yuv output for some application */ +} EXYNOS_OMX_BUFFERPROCESS_TYPE; + +typedef struct _EXYNOS_OMX_VIDEO_PROFILELEVEL +{ + OMX_S32 profile; + OMX_S32 level; +} EXYNOS_OMX_VIDEO_PROFILELEVEL; + +#ifdef USE_S3D_SUPPORT +typedef enum _EXYNOS_OMX_FPARGMT_TYPE +{ + OMX_SEC_FPARGMT_CHECKERBRD_INTERL = 0x00, + OMX_SEC_FPARGMT_COLUMN_INTERL = 0x01, + OMX_SEC_FPARGMT_ROW_INTERL = 0x02, + OMX_SEC_FPARGMT_SIDE_BY_SIDE = 0x03, + OMX_SEC_FPARGMT_TOP_BOTTOM = 0x04, + OMX_SEC_FPARGMT_TEMPORAL_INTERL = 0x05, + OMX_SEC_FPARGMT_NONE = 0x0A +} EXYNOS_OMX_FPARGMT_TYPE; +#endif + +#ifdef USE_KHRONOS_OMX_HEADER +#define OMX_VIDEO_CodingVPX 0x09 /**< Google VPX, formerly known as On2 VP8 */ +#endif + +#ifndef __OMX_EXPORTS +#define __OMX_EXPORTS +#define EXYNOS_EXPORT_REF __attribute__((visibility("default"))) +#define EXYNOS_IMPORT_REF __attribute__((visibility("default"))) +#endif + +#ifdef SLP_PLATFORM +/* for using ST12, set the hw addr at SCMN_IMGB type buffer */ +#define SCMN_IMGB_MAX_PLANE (4) /* max channel count */ + +/* image buffer definition + +------------------------------------------+ --- + | | ^ + | a[], p[] | | + | +---------------------------+ --- | | + | | | ^ | | + | |<---------- w[] ---------->| | | | + | | | | | | + | | | | + | | | h[] | e[] + | | | | + | | | | | | + | | | | | | + | | | v | | + | +---------------------------+ --- | | + | | v + +------------------------------------------+ --- + + |<----------------- s[] ------------------>| +*/ + +typedef struct +{ + int w[SCMN_IMGB_MAX_PLANE]; /* width of each image plane */ + int h[SCMN_IMGB_MAX_PLANE]; /* height of each image plane */ + int s[SCMN_IMGB_MAX_PLANE]; /* stride of each image plane */ + int e[SCMN_IMGB_MAX_PLANE]; /* elevation of each image plane */ + void * a[SCMN_IMGB_MAX_PLANE]; /* user space address of each image plane */ + void * p[SCMN_IMGB_MAX_PLANE]; /* physical address of each image plane, if needs */ + int cs; /* color space type of image */ + int x; /* left postion, if needs */ + int y; /* top position, if needs */ + int __dummy2; /* to align memory */ + int data[16]; /* arbitrary data */ + + /* dmabuf fd */ + int fd[SCMN_IMGB_MAX_PLANE]; + + /* flag for buffer share */ + int buf_share_method; + + /* Y plane size in case of ST12 */ + int y_size; + /* UV plane size in case of ST12 */ + int uv_size; + + /* Tizen buffer object of each image plane */ + void *bo[SCMN_IMGB_MAX_PLANE]; + + /* JPEG data */ + void *jpeg_data; + /* JPEG size */ + int jpeg_size; + + /* tzmem buffer */ + int tz_enable; +} SCMN_IMGB; + + +typedef enum { + MEMORY_PADDR = 0, + MEMORY_DMABUF, +} SSBSIP_MFC_MEMORY_TYPE; + + +#endif + +#endif diff --git a/openmax/include/exynos/Exynos_OMX_Macros.h b/openmax/include/exynos/Exynos_OMX_Macros.h new file mode 100644 index 0000000..82ac358 --- /dev/null +++ b/openmax/include/exynos/Exynos_OMX_Macros.h @@ -0,0 +1,72 @@ +/* + * + * 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 Exynos_OMX_Macros.h + * @brief Macros + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OMX_MACROS +#define EXYNOS_OMX_MACROS + +#include "Exynos_OMX_Def.h" +#include "Exynos_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 { \ + Exynos_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 EXYNOS_TUNNEL_ESTABLISHED 0x0001 +#define EXYNOS_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_BEING_FLUSHED_OR_DISABLED(port) ((port->bIsPortFlushed == OMX_TRUE) || (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 & EXYNOS_TUNNEL_ESTABLISHED) +#define CHECK_PORT_BUFFER_SUPPLIER(port) (port->tunnelFlags & EXYNOS_TUNNEL_IS_SUPPLIER) + +#define RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(pDst, pSrc) \ + do { \ + (pDst)->bEnabled = (pSrc)->bEnabled; \ + } while (0) + +#endif diff --git a/openmax/include/khronos/OMX_Audio.h b/openmax/include/khronos/OMX_Audio.h new file mode 100644 index 0000000..04f1a99 --- /dev/null +++ b/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/openmax/include/khronos/OMX_Component.h b/openmax/include/khronos/OMX_Component.h new file mode 100644 index 0000000..d595640 --- /dev/null +++ b/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/openmax/include/khronos/OMX_ContentPipe.h b/openmax/include/khronos/OMX_ContentPipe.h new file mode 100644 index 0000000..5f6310c --- /dev/null +++ b/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/openmax/include/khronos/OMX_Core.h b/openmax/include/khronos/OMX_Core.h new file mode 100644 index 0000000..a076f2f --- /dev/null +++ b/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/openmax/include/khronos/OMX_IVCommon.h b/openmax/include/khronos/OMX_IVCommon.h new file mode 100644 index 0000000..4c4995c --- /dev/null +++ b/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/openmax/include/khronos/OMX_Image.h b/openmax/include/khronos/OMX_Image.h new file mode 100644 index 0000000..a6d4666 --- /dev/null +++ b/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/openmax/include/khronos/OMX_Index.h b/openmax/include/khronos/OMX_Index.h new file mode 100644 index 0000000..44d4ea7 --- /dev/null +++ b/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/openmax/include/khronos/OMX_Types.h b/openmax/include/khronos/OMX_Types.h new file mode 100644 index 0000000..31be916 --- /dev/null +++ b/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/openmax/include/khronos/OMX_Video.h b/openmax/include/khronos/OMX_Video.h new file mode 100644 index 0000000..163e450 --- /dev/null +++ b/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/openmax/osal/Android.mk b/openmax/osal/Android.mk new file mode 100644 index 0000000..7cf24c2 --- /dev/null +++ b/openmax/osal/Android.mk @@ -0,0 +1,55 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + Exynos_OSAL_Event.c \ + Exynos_OSAL_Queue.c \ + Exynos_OSAL_ETC.c \ + Exynos_OSAL_Mutex.c \ + Exynos_OSAL_Thread.c \ + Exynos_OSAL_Memory.c \ + Exynos_OSAL_Semaphore.c \ + Exynos_OSAL_Library.c \ + Exynos_OSAL_Log.c \ + Exynos_OSAL_SharedMemory.c + +ifeq ($(BOARD_USE_ANB), true) +LOCAL_SRC_FILES += \ + Exynos_OSAL_Android.cpp +endif + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libExynosOMX_OSAL + +LOCAL_CFLAGS := + +ifeq ($(BOARD_USE_ANB_OUTBUF_SHARE), true) +LOCAL_CFLAGS += -DUSE_ANB_OUTBUF_SHARE +endif + +ifeq ($(BOARD_USE_DMA_BUF), true) +LOCAL_CFLAGS += -DUSE_DMA_BUF +endif + +LOCAL_STATIC_LIBRARIES := liblog libcutils libExynosVideoApi + +LOCAL_C_INCLUDES := \ + $(EXYNOS_OMX_INC)/exynos \ + $(EXYNOS_OMX_TOP)/osal \ + $(EXYNOS_OMX_COMPONENT)/common \ + $(EXYNOS_OMX_COMPONENT)/video/dec \ + $(EXYNOS_VIDEO_CODEC)/v4l2/include \ + $(TOP)/hardware/samsung_slsi/exynos/include \ + $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include + +ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true) +LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER +LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos +else +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/hardware +LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax +endif + +include $(BUILD_STATIC_LIBRARY) diff --git a/openmax/osal/Exynos_OSAL_ETC.c b/openmax/osal/Exynos_OSAL_ETC.c new file mode 100644 index 0000000..e6d73ed --- /dev/null +++ b/openmax/osal/Exynos_OSAL_ETC.c @@ -0,0 +1,237 @@ +/* + * + * 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 Exynos_OSAL_ETC.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_ETC.h" +#include "Exynos_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 Exynos_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src) +{ + return strcpy(dest, src); +} + +OMX_PTR Exynos_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num) +{ + return strncpy(dest, src, num); +} + +OMX_S32 Exynos_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2) +{ + return strcmp(str1, str2); +} + +OMX_S32 Exynos_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num) +{ + return strncmp(str1, str2, num); +} + +OMX_PTR Exynos_OSAL_Strcat(OMX_PTR dest, OMX_PTR src) +{ + return strcat(dest, src); +} + +OMX_PTR Exynos_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num) +{ + return strncat(dest, src, num); +} + +size_t Exynos_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 Exynos_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 Exynos_OSAL_PerfStart(PERF_ID_TYPE id) +{ + gettimeofday(&perfStart[id], NULL); +} + +void Exynos_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 Exynos_OSAL_PerfFrame(PERF_ID_TYPE id) +{ + return perfTime[id]; +} + +OMX_U32 Exynos_OSAL_PerfTotal(PERF_ID_TYPE id) +{ + return totalPerfTime[id]; +} + +OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id) +{ + return perfFrameCount[id]; +} + +int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id) +{ + return perfOver30ms[id]; +} + +void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id) +{ + OMX_U32 perfTotal; + int frameCount; + + frameCount = Exynos_OSAL_PerfFrameCount(id); + perfTotal = Exynos_OSAL_PerfTotal(id); + + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "%s Frame Count: %d", prefix, frameCount); + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "%s Avg Time: %.2f ms, Over 30ms: %d", + prefix, (float)perfTotal / (float)(frameCount * 1000), + Exynos_OSAL_PerfOver30ms(id)); +} diff --git a/openmax/osal/Exynos_OSAL_ETC.h b/openmax/osal/Exynos_OSAL_ETC.h new file mode 100644 index 0000000..efbc51d --- /dev/null +++ b/openmax/osal/Exynos_OSAL_ETC.h @@ -0,0 +1,66 @@ +/* + * + * 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 Exynos_OSAL_ETC.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_ETC +#define Exynos_OSAL_ETC + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR Exynos_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src); +OMX_S32 Exynos_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num); +OMX_S32 Exynos_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2); +OMX_PTR Exynos_OSAL_Strcat(OMX_PTR dest, OMX_PTR src); +size_t Exynos_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 Exynos_OSAL_PerfInit(PERF_ID_TYPE id); +void Exynos_OSAL_PerfStart(PERF_ID_TYPE id); +void Exynos_OSAL_PerfStop(PERF_ID_TYPE id); +OMX_U32 Exynos_OSAL_PerfFrame(PERF_ID_TYPE id); +OMX_U32 Exynos_OSAL_PerfTotal(PERF_ID_TYPE id); +OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id); +int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id); +void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Event.c b/openmax/osal/Exynos_OSAL_Event.c new file mode 100644 index 0000000..ef14f85 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Event.c @@ -0,0 +1,217 @@ +/* + * + * 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 Exynos_OSAL_Event.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + + +#include +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_Event.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "Exynos_OSAL_EVENT" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +OMX_ERRORTYPE Exynos_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle) +{ + Exynos_OSAL_THREADEVENT *event; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + event = (Exynos_OSAL_THREADEVENT *)Exynos_OSAL_Malloc(sizeof(Exynos_OSAL_THREADEVENT)); + if (!event) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + Exynos_OSAL_Memset(event, 0, sizeof(Exynos_OSAL_THREADEVENT)); + event->signal = OMX_FALSE; + + ret = Exynos_OSAL_MutexCreate(&event->mutex); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Free(event); + goto EXIT; + } + + if (pthread_cond_init(&event->condition, NULL)) { + Exynos_OSAL_MutexTerminate(event->mutex); + Exynos_OSAL_Free(event); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + *eventHandle = (OMX_HANDLETYPE)event; + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle) +{ + Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = Exynos_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 = Exynos_OSAL_MutexUnlock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = Exynos_OSAL_MutexTerminate(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + Exynos_OSAL_Free(event); + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_SignalReset(OMX_HANDLETYPE eventHandle) +{ + Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = Exynos_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_FALSE; + + Exynos_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_SignalSet(OMX_HANDLETYPE eventHandle) +{ + Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = Exynos_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_TRUE; + pthread_cond_signal(&event->condition); + + Exynos_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms) +{ + Exynos_OSAL_THREADEVENT *event = (Exynos_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 = Exynos_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; + } + } + } + + Exynos_OSAL_MutexUnlock(event->mutex); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/openmax/osal/Exynos_OSAL_Event.h b/openmax/osal/Exynos_OSAL_Event.h new file mode 100644 index 0000000..f7ccd89 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Event.h @@ -0,0 +1,61 @@ +/* + * + * 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 Exynos_OSAL_Event.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_EVENT +#define Exynos_OSAL_EVENT + +#include +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#define DEF_MAX_WAIT_TIME 0xFFFFFFFF + +typedef struct _Exynos_OSAL_THREADEVENT +{ + OMX_BOOL signal; + OMX_HANDLETYPE mutex; + pthread_cond_t condition; +} Exynos_OSAL_THREADEVENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE Exynos_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle); +OMX_ERRORTYPE Exynos_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE Exynos_OSAL_SignalReset(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE Exynos_OSAL_SignalSet(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE Exynos_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Library.c b/openmax/osal/Exynos_OSAL_Library.c new file mode 100644 index 0000000..88775ee --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Library.c @@ -0,0 +1,54 @@ +/* + * + * 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 Exynos_OSAL_Library.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + + +#include +#include +#include +#include + +#include "Exynos_OSAL_Library.h" + + +void *Exynos_OSAL_dlopen(const char *filename, int flag) +{ + return dlopen(filename, flag); +} + +void *Exynos_OSAL_dlsym(void *handle, const char *symbol) +{ + return dlsym(handle, symbol); +} + +int Exynos_OSAL_dlclose(void *handle) +{ + return dlclose(handle); +} + +const char *Exynos_OSAL_dlerror(void) +{ + return dlerror(); +} diff --git a/openmax/osal/Exynos_OSAL_Library.h b/openmax/osal/Exynos_OSAL_Library.h new file mode 100644 index 0000000..16bbd2a --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Library.h @@ -0,0 +1,46 @@ +/* + * + * 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 Exynos_OSAL_Library.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_LIBRARY +#define Exynos_OSAL_LIBRARY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void *Exynos_OSAL_dlopen(const char *filename, int flag); +void *Exynos_OSAL_dlsym(void *handle, const char *symbol); +int Exynos_OSAL_dlclose(void *handle); +const char *Exynos_OSAL_dlerror(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Log.c b/openmax/osal/Exynos_OSAL_Log.c new file mode 100644 index 0000000..0d31d8b --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Log.c @@ -0,0 +1,115 @@ +/* + * + * 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 Exynos_OSAL_Log.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ +#ifndef SLP_PLATFORM /* build env */ +#include +#else +#ifdef USE_DLOG +#include +#define DLOG_TAG "OMX_LOG" +#endif +#include +#include +#endif + +#include "Exynos_OSAL_Log.h" + +#ifdef SLP_PLATFORM /* build env */ +static int component_debug_level = -1; +#endif + +void _Exynos_OSAL_Log(EXYNOS_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) +{ +#ifndef SLP_PLATFORM + va_list argptr; + + va_start(argptr, msg); + + switch (logLevel) { + case EXYNOS_LOG_TRACE: + __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); + break; + case EXYNOS_LOG_INFO: + __android_log_vprint(ANDROID_LOG_INFO, tag, msg, argptr); + break; + case EXYNOS_LOG_WARNING: + __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); + break; + case EXYNOS_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); +#else +#ifdef USE_DLOG + va_list argptr; + + if (component_debug_level < 0) { + component_debug_level = getenv("OMX_DEBUG") ? atoi(getenv("OMX_DEBUG")) : OMX_DEBUG_LEVEL; + } else { + if ((int)logLevel < component_debug_level) return; + } + + va_start(argptr, msg); + + switch (logLevel) { + case EXYNOS_LOG_VERVOSE: + case EXYNOS_LOG_TRACE: + SLOG_VA (LOG_DEBUG, DLOG_TAG, msg, argptr); + break; + case EXYNOS_LOG_INFO: + SLOG_VA (LOG_INFO, DLOG_TAG, msg, argptr); + break; + case EXYNOS_LOG_WARNING: + SLOG_VA (LOG_WARN, DLOG_TAG, msg, argptr); + break; + case EXYNOS_LOG_ERROR: + SLOG_VA (LOG_ERROR, DLOG_TAG, msg, argptr); + break; + default: + SLOG_VA (LOG_DEBUG, DLOG_TAG, msg, argptr); + break; + } + + va_end(argptr); +#else + va_list argptr; + + if (component_debug_level < 0) { + component_debug_level = getenv("OMX_DEBUG") ? atoi(getenv("OMX_DEBUG")) : OMX_DEBUG_LEVEL; + } else { + if ((int)logLevel < component_debug_level) return; + } + + va_start(argptr, msg); + vprintf(msg, argptr); + va_end(argptr); + printf("\n"); +#endif +#endif +} diff --git a/openmax/osal/Exynos_OSAL_Log.h b/openmax/osal/Exynos_OSAL_Log.h new file mode 100644 index 0000000..3e14116 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Log.h @@ -0,0 +1,108 @@ +/* + * + * 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 Exynos_OSAL_Log.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + * 2012.8.27 : Add trace function + */ + +#ifndef EXYNOS_OSAL_LOG +#define EXYNOS_OSAL_LOG + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SLP_PLATFORM +#ifndef EXYNOS_LOG_OFF +#define EXYNOS_LOG +#endif + +#ifndef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_LOG" +#endif + +#ifdef EXYNOS_TRACE_ON +#define EXYNOS_TRACE +#endif +#endif /* SLP_PLATFORM */ + +typedef enum _LOG_LEVEL +{ +#ifdef SLP_PLATFORM + EXYNOS_LOG_VERVOSE, +#endif + EXYNOS_LOG_TRACE, + EXYNOS_LOG_INFO, + EXYNOS_LOG_WARNING, + EXYNOS_LOG_ERROR +} EXYNOS_LOG_LEVEL; + +#ifndef SLP_PLATFORM + +#ifdef EXYNOS_LOG +#define Exynos_OSAL_Log(a, ...) ((void)_Exynos_OSAL_Log(a, EXYNOS_LOG_TAG, __VA_ARGS__)) +#else +#define Exynos_OSAL_Log(a, ...) \ + do { \ + if (a == EXYNOS_LOG_ERROR) \ + ((void)_Exynos_OSAL_Log(a, EXYNOS_LOG_TAG, __VA_ARGS__)); \ + } while (0) +#endif + +#ifdef EXYNOS_TRACE +#define FunctionIn() _Exynos_OSAL_Log(EXYNOS_LOG_TRACE, EXYNOS_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) +#define FunctionOut() _Exynos_OSAL_Log(EXYNOS_LOG_TRACE, EXYNOS_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) +#else +#define FunctionIn() ((void *)0) +#define FunctionOut() ((void *)0) +#endif + +#else /* SLP_PLATFORM */ + +#define OMX_DEBUG_LEVEL 2 /* EXYNOS_LOG_INFO */ + +#define ALOGV(...) Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, __VA_ARGS__) +#define ALOGD(...) Exynos_OSAL_Log(EXYNOS_LOG_TRACE, __VA_ARGS__) +#define ALOGI(...) Exynos_OSAL_Log(EXYNOS_LOG_INFO, __VA_ARGS__) +#define ALOGW(...) Exynos_OSAL_Log(EXYNOS_LOG_WARNING, __VA_ARGS__) +#define ALOGE(...) Exynos_OSAL_Log(EXYNOS_LOG_ERROR, __VA_ARGS__) + +#ifndef EXYNOS_LOG_TAG +#define Exynos_OSAL_Log(a, ...) _Exynos_OSAL_Log(a, "EXYNOS_LOG", __VA_ARGS__) +#define FunctionIn() _Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_LOG", "%s In , Line: %d", __FUNCTION__, __LINE__) +#define FunctionOut() _Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_LOG", "%s Out , Line: %d", __FUNCTION__, __LINE__) +#else +#define Exynos_OSAL_Log(a, ...) _Exynos_OSAL_Log(a, EXYNOS_LOG_TAG, EXYNOS_LOG_TAG"] "__VA_ARGS__) +#define FunctionIn() _Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, EXYNOS_LOG_TAG, EXYNOS_LOG_TAG"] %s In , Line: %d", __FUNCTION__, __LINE__) +#define FunctionOut() _Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, EXYNOS_LOG_TAG, EXYNOS_LOG_TAG"] %s Out , Line: %d", __FUNCTION__, __LINE__) +#endif + +#endif /* SLP_PLATFORM */ + +extern void _Exynos_OSAL_Log(EXYNOS_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Memory.c b/openmax/osal/Exynos_OSAL_Memory.c new file mode 100644 index 0000000..70552c4 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Memory.c @@ -0,0 +1,79 @@ +/* + * + * 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 Exynos_OSAL_Memory.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" + +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +static int mem_cnt = 0; + +OMX_PTR Exynos_OSAL_Malloc(OMX_U32 size) +{ + mem_cnt++; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "alloc count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "alloc count: %d", mem_cnt); +#endif + + return (OMX_PTR)malloc(size); +} + +void Exynos_OSAL_Free(OMX_PTR addr) +{ + mem_cnt--; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "free count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "free count: %d", mem_cnt); +#endif + + if (addr) + free(addr); + + return; +} + +OMX_PTR Exynos_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n) +{ + return memset(dest, c, n); +} + +OMX_PTR Exynos_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memcpy(dest, src, n); +} + +OMX_PTR Exynos_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memmove(dest, src, n); +} diff --git a/openmax/osal/Exynos_OSAL_Memory.h b/openmax/osal/Exynos_OSAL_Memory.h new file mode 100644 index 0000000..757d81c --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Memory.h @@ -0,0 +1,48 @@ +/* + * + * 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 Exynos_OSAL_Memory.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_MEMORY +#define Exynos_OSAL_MEMORY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR Exynos_OSAL_Malloc(OMX_U32 size); +void Exynos_OSAL_Free(OMX_PTR addr); +OMX_PTR Exynos_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n); +OMX_PTR Exynos_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n); +OMX_PTR Exynos_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openmax/osal/Exynos_OSAL_Mutex.c b/openmax/osal/Exynos_OSAL_Mutex.c new file mode 100644 index 0000000..4ef773c --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Mutex.c @@ -0,0 +1,92 @@ +/* + * + * 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 Exynos_OSAL_Mutex.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Mutex.h" + +OMX_ERRORTYPE Exynos_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle) +{ + pthread_mutex_t *mutex; + + mutex = (pthread_mutex_t *)Exynos_OSAL_Malloc(sizeof(pthread_mutex_t)); + if (!mutex) + return OMX_ErrorInsufficientResources; + + if (pthread_mutex_init(mutex, NULL) != 0) { + Exynos_OSAL_Free(mutex); + return OMX_ErrorUndefined; + } + + *mutexHandle = (OMX_HANDLETYPE)mutex; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_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; + + Exynos_OSAL_Free(mutex); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_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 Exynos_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/openmax/osal/Exynos_OSAL_Mutex.h b/openmax/osal/Exynos_OSAL_Mutex.h new file mode 100644 index 0000000..d8875ed --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Mutex.h @@ -0,0 +1,47 @@ +/* + * + * 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 Exynos_OSAL_Mutex.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create +*/ + +#ifndef Exynos_OSAL_MUTEX +#define Exynos_OSAL_MUTEX + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle); +OMX_ERRORTYPE Exynos_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE Exynos_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE Exynos_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Platform_Specific.c b/openmax/osal/Exynos_OSAL_Platform_Specific.c new file mode 100755 index 0000000..004049a --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Platform_Specific.c @@ -0,0 +1,751 @@ +/* + * 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 Exynos_OSAL_Platform_Specific.c + * @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 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include + +#include "Exynos_OSAL_Semaphore.h" +#include "Exynos_OMX_Baseport.h" +#include "Exynos_OMX_Basecomponent.h" +#include "Exynos_OMX_Macros.h" +#include "Exynos_OMX_Vdec.h" +#include "Exynos_OSAL_Platform_Specific.h" +#include "exynos_format.h" + +#include "ExynosVideoApi.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "Exynos_OSAL_PB" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE Exynos_OSAL_LockPBHandle( + 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 planes) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + +#if 0 + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + buffer_handle_t bufferHandle = (buffer_handle_t) handle; +#ifdef USE_DMA_BUF + private_handle_t *priv_hnd = (private_handle_t *) bufferHandle; +#endif + Rect bounds(width, height); + ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes; + void *vaddr[MAX_BUFFER_PLANE]; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); + + int usage = 0; + + switch (format) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12Tiled: + 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) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.lock() fail", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + +#ifdef USE_DMA_BUF + vplanes[0].fd = priv_hnd->fd; + vplanes[0].offset = 0; + vplanes[1].fd = priv_hnd->u_fd; + vplanes[1].offset = priv_hnd->uoffset; + vplanes[2].fd = priv_hnd->v_fd; + vplanes[2].offset = priv_hnd->voffset; +#endif + vplanes[0].addr = vaddr[0]; + vplanes[1].addr = vaddr[1]; + vplanes[2].addr = vaddr[2]; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_UnlockPBHandle(OMX_IN OMX_U32 handle) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; +#ifdef SLP_PLATFORM +#else + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + buffer_handle_t bufferHandle = (buffer_handle_t) handle; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle); + + if (mapper.unlock(bufferHandle) != 0) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.unlock() fail", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle); +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_LockPB( + 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 planes) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; +#ifdef SLP_PLATFORM + + ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes; + SCMN_IMGB *buffer = (SCMN_IMGB *) pBuffer; + + + vplanes[0].fd = buffer->fd[0]; + vplanes[0].offset = 0; + vplanes[1].fd = buffer->fd[1]; + vplanes[1].offset = 0; //priv_hnd->uoffset; + vplanes[2].fd = 0; //priv_hnd->v_fd; + vplanes[2].offset = 0; //priv_hnd->voffset; + + vplanes[0].addr = buffer->a[0]; //vaddr[0]; + vplanes[1].addr = buffer->a[1]; //vaddr[1]; + vplanes[2].addr = NULL; //vaddr[2]; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OSAL_LockPB:fd[0](%d) fd[1](%d) a[0](%p) a[1](%p)", + buffer->fd[0], buffer->fd[1], buffer->a[0], buffer->a[1]); +#else + android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; + + ret = Exynos_OSAL_LockPBHandle((OMX_U32)pANB->handle, width, height, format, planes); + *pStride = pANB->stride; +#endif + +EXIT: + FunctionOut(); + + return ret; +} + +#ifdef SLP_PLATFORM +OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort,EXYNOS_OMX_BASEPORT *pExynosInPort) +#else +OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, EXYNOS_OMX_DATA *pData) +#endif +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; +#ifdef SLP_PLATFORM + SCMN_IMGB *pSlpOutBuf = NULL; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + + pSlpOutBuf = (SCMN_IMGB *)pBuffer; + if (pSlpOutBuf == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pBuffer is NULL!"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + memset(pSlpOutBuf, 0, sizeof(SCMN_IMGB)); + + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pData->extInfo; + + if (pExynosPort->cropRectangle.nWidth != 0 && pExynosPort->cropRectangle.nHeight != 0) { + /* modify for h264 trim */ + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "this has cropRectangle(h264).crop.nWidth = %d, crop.nHeight = %d", + pExynosPort->cropRectangle.nWidth, pExynosPort->cropRectangle.nHeight); + pSlpOutBuf->w[0] = pExynosPort->cropRectangle.nWidth; + pSlpOutBuf->w[1] = pExynosPort->cropRectangle.nWidth; + pSlpOutBuf->h[0] = pExynosPort->cropRectangle.nHeight; + pSlpOutBuf->h[1] = (pExynosPort->cropRectangle.nHeight/2); + + pSlpOutBuf->s[0] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ + pSlpOutBuf->s[1] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); + pSlpOutBuf->e[0] = ALIGN(pExynosPort->cropRectangle.nHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ + pSlpOutBuf->e[1] = ALIGN((pExynosPort->cropRectangle.nHeight/2), S5P_FIMV_NV12MT_VALIGN); + } else { + pSlpOutBuf->w[0] = pBufferInfo->imageWidth; + pSlpOutBuf->w[1] = pBufferInfo->imageWidth; + pSlpOutBuf->h[0] = pBufferInfo->imageHeight; + pSlpOutBuf->h[1] = (pBufferInfo->imageHeight/2); + + pSlpOutBuf->s[0] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ + pSlpOutBuf->s[1] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); + pSlpOutBuf->e[0] = ALIGN(pBufferInfo->imageHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ + pSlpOutBuf->e[1] = ALIGN((pBufferInfo->imageHeight/2), S5P_FIMV_NV12MT_VALIGN); + } + + + +/* + if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { + pSlpOutBuf->a[0] = 0; + pSlpOutBuf->a[1] = 0; + } else { +*/ + pSlpOutBuf->a[0] = pData->buffer.multiPlaneBuffer.dataBuffer[0]; + pSlpOutBuf->a[1] = pData->buffer.multiPlaneBuffer.dataBuffer[1]; +// } + pSlpOutBuf->a[2] = 0; /* omx do not use this plane */ + + pSlpOutBuf->fd[0] = pData->buffer.multiPlaneBuffer.fd[0]; + pSlpOutBuf->fd[1] = pData->buffer.multiPlaneBuffer.fd[1]; + pSlpOutBuf->fd[2] = 0; + + if(pExynosInPort->portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + pSlpOutBuf->y_size = calc_plane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); + pSlpOutBuf->uv_size = calc_plane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"H264 foramt and y_size=%d, uv_size=%d",pSlpOutBuf->y_size,pSlpOutBuf->uv_size); + } else { + pSlpOutBuf->y_size= calc_yplane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); + pSlpOutBuf->uv_size = calc_uvplane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"foramt is %d, and y_size=%d, uv_size=%d",pExynosInPort->portDefinition.format.video.eCompressionFormat ,pSlpOutBuf->y_size,pSlpOutBuf->uv_size); + } + + + pSlpOutBuf->buf_share_method = 1; /* use fd mode */ + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->fd[2]); +#else + android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; + + ret = Exynos_OSAL_UnlockPBHandle((OMX_U32)pANB->handle); +#endif +EXIT: + FunctionOut(); + + return ret; +} + +#if 0 +OMX_ERRORTYPE useAndroidNativeBuffer( + EXYNOS_OMX_BASEPORT *pExynosPort, + 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; + OMX_U32 width, height; + OMX_U32 stride; + ExynosVideoPlane planes[MAX_BUFFER_PLANE]; + + FunctionIn(); + + if (pExynosPort == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pExynosPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) { + if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader; + pExynosPort->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; + + width = pExynosPort->portDefinition.format.video.nFrameWidth; + height = pExynosPort->portDefinition.format.video.nFrameHeight; + Exynos_OSAL_LockPB(temp_bufferHeader->pBuffer, width, height, + pExynosPort->portDefinition.format.video.eColorFormat, + &stride, planes); +#ifdef USE_DMA_BUF + pExynosPort->extendBufferHeader[i].buf_fd[0] = planes[0].fd; + pExynosPort->extendBufferHeader[i].buf_fd[1] = planes[1].fd; + pExynosPort->extendBufferHeader[i].buf_fd[2] = planes[2].fd; +#endif + pExynosPort->extendBufferHeader[i].pYUVBuf[0] = planes[0].addr; + pExynosPort->extendBufferHeader[i].pYUVBuf[1] = planes[1].addr; + pExynosPort->extendBufferHeader[i].pYUVBuf[2] = planes[2].addr; + Exynos_OSAL_UnlockANB(temp_bufferHeader->pBuffer); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ", + i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], + pExynosPort->extendBufferHeader[i].pYUVBuf[1]); + + pExynosPort->assignedBufferNum++; + if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { + pExynosPort->portDefinition.bPopulated = OMX_TRUE; + /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */ + Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource); + /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + + goto EXIT; + } + } + + Exynos_OSAL_Free(temp_bufferHeader); + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} +#endif + +OMX_ERRORTYPE Exynos_OSAL_GetPBParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { +#if 0 /* SLP_PLATFORM */ + case OMX_IndexParamGetAndroidNativeBuffer: + { + GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__); + + ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pExynosComponent->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 |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP + | GRALLOC_USAGE_HW_ION | GRALLOC_USAGE_HWC_HWOVERLAY); + } + break; +#endif + default: + { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_SetPBParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pExynosComponent->currentState == OMX_StateInvalid ) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + switch (nIndex) { +#ifdef SLP_PLATFORM + case OMX_IndexParamEnablePlatformSpecificBuffers: +#else + case OMX_IndexParamEnableAndroidBuffers: +#endif + { + EnableGemBuffersParams *pPBParams = (EnableGemBuffersParams *) ComponentParameterStructure; + OMX_U32 portIndex = pPBParams->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamEnablePlatformSpecificBuffers", __func__); + + ret = Exynos_OMX_Check_SizeVersion(pPBParams, sizeof(EnableGemBuffersParams)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(EnableGemBuffersParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + +#ifdef SLP_PLATFORM + /* PB and DPB Buffer Sharing */ + if ((portIndex == OUTPUT_PORT_INDEX) && + ((pExynosPort->bufferProcessType & BUFFER_PBSHARE) == BUFFER_PBSHARE)) { + pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "output buffer sharing mode is on"); + } + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "pExynosPort->portDefinition.format.video.eColorFormat: 0x%x", pExynosPort->portDefinition.format.video.eColorFormat); +#else + if ((portIndex == OUTPUT_PORT_INDEX) && + (pExynosPort->bufferProcessType & BUFFER_COPY)) { + pExynosPort->bufferProcessType = BUFFER_COPY; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } +#endif + pExynosPort->bIsPBEnabled = pPBParams->enable; + Exynos_OSAL_Log(EXYNOS_LOG_INFO, "pExynosPort->bIsPBEnabled: %d", pExynosPort->bIsPBEnabled); + } + break; + +#if 0 /* SLP_PLATFORM */ + case OMX_IndexParamUseAndroidNativeBuffer: + { + UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + android_native_buffer_t *pANB; + OMX_U32 nSizeBytes; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex); + + ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (pExynosPort->portState != OMX_StateIdle) { + Exynos_OSAL_Log(EXYNOS_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(pExynosPort, + pANBParams->bufferHeader, + pANBParams->nPortIndex, + pANBParams->pAppPrivate, + nSizeBytes, + (OMX_U8 *) pANB); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer is failed: err=0x%x", __func__,ret); + goto EXIT; + } + } + break; + + case OMX_IndexParamStoreMetaDataBuffer: + { + StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure; + OMX_U32 portIndex = pANBParams->nPortIndex; + EXYNOS_OMX_BASEPORT *pExynosPort = NULL; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__); + + ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(StoreMetaDataInBuffersParams)); + if (ret != OMX_ErrorNone) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__); + goto EXIT; + } + + if (portIndex >= pExynosComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pExynosPort = &pExynosComponent->pExynosPort[portIndex]; + if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pExynosPort->bStoreMetaData = pANBParams->bStoreMetaData; + } + break; +#endif + default: + { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex); + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +#if 0 // we can remove this later. +OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer, + OMX_OUT OMX_PTR *ppBuf) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + MetadataBufferType type; + + 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 */ + Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType)); + + if (type == kMetadataBufferTypeCameraSource) { + void *pAddress = NULL; + + /* Address. of Y */ + Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *)); + ppBuf[0] = (void *)pAddress; + + /* Address. of CbCr */ + Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *)); + ppBuf[1] = (void *)pAddress; + + } else if (type == kMetadataBufferTypeGrallocSource) { + buffer_handle_t pBufHandle; + + /* buffer_handle_t */ + Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t)); + ppBuf[0] = (OMX_PTR)pBufHandle; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_COLOR_FORMATTYPE Exynos_OSAL_Hal2OMXPixelFormat( + unsigned int hal_format) +{ + OMX_COLOR_FORMATTYPE omx_format; + switch (hal_format) { + case HAL_PIXEL_FORMAT_YCbCr_422_I: + omx_format = OMX_COLOR_FormatYCbYCr; + break; + 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_COLOR_FORMATTYPE)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 Exynos_OSAL_OMX2HalPixelFormat( + OMX_COLOR_FORMATTYPE omx_format) +{ + unsigned int hal_format; + switch (omx_format) { + case OMX_COLOR_FormatYCbYCr: + hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I; + break; + 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; +} +#endif + +#ifdef __cplusplus +} +#endif diff --git a/openmax/osal/Exynos_OSAL_Platform_Specific.h b/openmax/osal/Exynos_OSAL_Platform_Specific.h new file mode 100755 index 0000000..488b93e --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Platform_Specific.h @@ -0,0 +1,100 @@ +/* + * 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 Exynos_OSAL_Platform_Specific.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 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_PLATFORM_SPECIFIC +#define Exynos_OSAL_PLATFORM_SPECIFIC + +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_Index.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct GstOmxDecOutputBuffer GstOmxDecOutputBuffer; +typedef struct EnableGemBuffersParams EnableGemBuffersParams; + +struct GstOmxDecOutputBuffer { + int fd_y; + int fd_uv; + void *vaddr_y; + void *vaddr_uv; +}; + +struct EnableGemBuffersParams +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL enable; +}; + +OMX_ERRORTYPE Exynos_OSAL_GetPBParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE Exynos_OSAL_SetPBParameter(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); + +OMX_ERRORTYPE Exynos_OSAL_LockPB(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 planes); + +#ifdef SLP_PLATFORM +OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, OMX_IN EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_BASEPORT *pExynosInPort); +#else +OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, OMX_IN EXYNOS_OMX_DATA *pData); +#endif + + +OMX_ERRORTYPE Exynos_OSAL_LockPBHandle(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 planes); + +OMX_ERRORTYPE Exynos_OSAL_UnlockPBHandle(OMX_IN OMX_U32 pBuffer); + +OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer, + OMX_OUT OMX_PTR *pOutBuffer); + +#if 0 /* SLP_PLATFORM */ +OMX_ERRORTYPE Exynos_OSAL_CheckPB(OMX_IN EXYNOS_OMX_DATA *pBuffer, + OMX_OUT OMX_BOOL *bIsPBEnabled); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Queue.c b/openmax/osal/Exynos_OSAL_Queue.c new file mode 100644 index 0000000..fa9583c --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Queue.c @@ -0,0 +1,195 @@ +/* + * + * 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 Exynos_OSAL_Queue.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + + +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Mutex.h" +#include "Exynos_OSAL_Queue.h" + + +OMX_ERRORTYPE Exynos_OSAL_QueueCreate(EXYNOS_QUEUE *queueHandle, int maxNumElem) +{ + int i = 0; + EXYNOS_QElem *newqelem = NULL; + EXYNOS_QElem *currentqelem = NULL; + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + ret = Exynos_OSAL_MutexCreate(&queue->qMutex); + if (ret != OMX_ErrorNone) + return ret; + + queue->first = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem)); + if (queue->first == NULL) + return OMX_ErrorInsufficientResources; + + Exynos_OSAL_Memset(queue->first, 0, sizeof(EXYNOS_QElem)); + currentqelem = queue->last = queue->first; + queue->numElem = 0; + queue->maxNumElem = maxNumElem; + for (i = 0; i < (queue->maxNumElem - 2); i++) { + newqelem = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem)); + if (newqelem == NULL) { + while (queue->first != NULL) { + currentqelem = queue->first->qNext; + Exynos_OSAL_Free((OMX_PTR)queue->first); + queue->first = currentqelem; + } + return OMX_ErrorInsufficientResources; + } else { + Exynos_OSAL_Memset(newqelem, 0, sizeof(EXYNOS_QElem)); + currentqelem->qNext = newqelem; + currentqelem = newqelem; + } + } + + currentqelem->qNext = queue->first; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_OSAL_QueueTerminate(EXYNOS_QUEUE *queueHandle) +{ + int i = 0; + EXYNOS_QElem *currentqelem = NULL; + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + for ( i = 0; i < (queue->maxNumElem - 2); i++) { + currentqelem = queue->first->qNext; + Exynos_OSAL_Free(queue->first); + queue->first = currentqelem; + } + + if(queue->first) { + Exynos_OSAL_Free(queue->first); + queue->first = NULL; + } + + ret = Exynos_OSAL_MutexTerminate(queue->qMutex); + + return ret; +} + +int Exynos_OSAL_Queue(EXYNOS_QUEUE *queueHandle, void *data) +{ + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + Exynos_OSAL_MutexLock(queue->qMutex); + + if ((queue->last->data != NULL) || (queue->numElem >= queue->maxNumElem)) { + Exynos_OSAL_MutexUnlock(queue->qMutex); + return -1; + } + queue->last->data = data; + queue->last = queue->last->qNext; + queue->numElem++; + + Exynos_OSAL_MutexUnlock(queue->qMutex); + return 0; +} + +void *Exynos_OSAL_Dequeue(EXYNOS_QUEUE *queueHandle) +{ + void *data = NULL; + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + if (queue == NULL) + return NULL; + + Exynos_OSAL_MutexLock(queue->qMutex); + + if ((queue->first->data == NULL) || (queue->numElem <= 0)) { + Exynos_OSAL_MutexUnlock(queue->qMutex); + return NULL; + } + data = queue->first->data; + queue->first->data = NULL; + queue->first = queue->first->qNext; + queue->numElem--; + + Exynos_OSAL_MutexUnlock(queue->qMutex); + return data; +} + +int Exynos_OSAL_GetElemNum(EXYNOS_QUEUE *queueHandle) +{ + int ElemNum = 0; + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + Exynos_OSAL_MutexLock(queue->qMutex); + ElemNum = queue->numElem; + Exynos_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + +int Exynos_OSAL_SetElemNum(EXYNOS_QUEUE *queueHandle, int ElemNum) +{ + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + Exynos_OSAL_MutexLock(queue->qMutex); + queue->numElem = ElemNum; + Exynos_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + +int Exynos_OSAL_ResetQueue(EXYNOS_QUEUE *queueHandle) +{ + EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle; + EXYNOS_QElem *currentqelem = NULL; + + if (queue == NULL) + return -1; + + Exynos_OSAL_MutexLock(queue->qMutex); + queue->first->data = NULL; + currentqelem = queue->first->qNext; + while (currentqelem != queue->first) { + currentqelem->data = NULL; + currentqelem = currentqelem->qNext; + } + queue->last = queue->first; + queue->numElem = 0x00; + Exynos_OSAL_MutexUnlock(queue->qMutex); + + return 0; +} diff --git a/openmax/osal/Exynos_OSAL_Queue.h b/openmax/osal/Exynos_OSAL_Queue.h new file mode 100644 index 0000000..6300b45 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Queue.h @@ -0,0 +1,68 @@ +/* + * + * 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 Exynos_OSAL_Queue.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OSAL_QUEUE +#define EXYNOS_OSAL_QUEUE + +#include "OMX_Types.h" +#include "OMX_Core.h" + +#define QUEUE_ELEMENTS 10 +#define MAX_QUEUE_ELEMENTS 40 + +typedef struct _EXYNOS_QElem +{ + void *data; + struct _EXYNOS_QElem *qNext; +} EXYNOS_QElem; + +typedef struct _EXYNOS_QUEUE +{ + EXYNOS_QElem *first; + EXYNOS_QElem *last; + int numElem; + int maxNumElem; + OMX_HANDLETYPE qMutex; +} EXYNOS_QUEUE; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OSAL_QueueCreate(EXYNOS_QUEUE *queueHandle, int maxNumElem); +OMX_ERRORTYPE Exynos_OSAL_QueueTerminate(EXYNOS_QUEUE *queueHandle); +int Exynos_OSAL_Queue(EXYNOS_QUEUE *queueHandle, void *data); +void *Exynos_OSAL_Dequeue(EXYNOS_QUEUE *queueHandle); +int Exynos_OSAL_GetElemNum(EXYNOS_QUEUE *queueHandle); +int Exynos_OSAL_SetElemNum(EXYNOS_QUEUE *queueHandle, int ElemNum); +int Exynos_OSAL_ResetQueue(EXYNOS_QUEUE *queueHandle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_Semaphore.c b/openmax/osal/Exynos_OSAL_Semaphore.c new file mode 100644 index 0000000..4827266 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Semaphore.c @@ -0,0 +1,151 @@ +/* + * + * 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 Exynos_OSAL_Semaphore.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Semaphore.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_LOG_SEMA" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +OMX_ERRORTYPE Exynos_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle) +{ + sem_t *sema; + + sema = (sem_t *)Exynos_OSAL_Malloc(sizeof(sem_t)); + if (!sema) + return OMX_ErrorInsufficientResources; + + if (sem_init(sema, 0, 0) != 0) { + Exynos_OSAL_Free(sema); + return OMX_ErrorUndefined; + } + + *semaphoreHandle = (OMX_HANDLETYPE)sema; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_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; + + Exynos_OSAL_Free(sema); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_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 Exynos_OSAL_SemaphoreTryWait(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + FunctionIn(); + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_trywait(sema) != 0) + return OMX_ErrorUndefined; + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE Exynos_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 Exynos_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 Exynos_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/openmax/osal/Exynos_OSAL_Semaphore.h b/openmax/osal/Exynos_OSAL_Semaphore.h new file mode 100644 index 0000000..8618407 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Semaphore.h @@ -0,0 +1,50 @@ +/* + * + * 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 Exynos_OSAL_Semaphore.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_SEMAPHORE +#define Exynos_OSAL_SEMAPHORE + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle); +OMX_ERRORTYPE Exynos_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE Exynos_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE Exynos_OSAL_SemaphoreTryWait(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE Exynos_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE Exynos_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val); +OMX_ERRORTYPE Exynos_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Exynos_OSAL_SharedMemory.c b/openmax/osal/Exynos_OSAL_SharedMemory.c new file mode 100644 index 0000000..6fa1a25 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_SharedMemory.c @@ -0,0 +1,489 @@ +/* + * + * 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 Exynos_OSAL_SharedMemory.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include +#include +#include +#ifndef SLP_PLATFORM /* build env */ +#include +#include +#endif +#include +#include + +#include "Exynos_OSAL_SharedMemory.h" +#include "ion.h" + +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + +static int mem_cnt = 0; + +struct EXYNOS_SHAREDMEM_LIST; +typedef struct _EXYNOS_SHAREDMEM_LIST +{ + OMX_U32 IONBuffer; + OMX_PTR mapAddr; + OMX_U32 allocSize; + bool owner; + struct _EXYNOS_SHAREDMEM_LIST *pNextMemory; +} EXYNOS_SHAREDMEM_LIST; + +typedef struct _EXYNOS_SHARED_MEMORY +{ + OMX_HANDLETYPE hIONHandle; + EXYNOS_SHAREDMEM_LIST *pAllocMemory; + OMX_HANDLETYPE hSMMutex; +} EXYNOS_SHARED_MEMORY; + + +OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open() +{ + EXYNOS_SHARED_MEMORY *pHandle = NULL; + ion_client IONClient = 0; + + pHandle = (EXYNOS_SHARED_MEMORY *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHARED_MEMORY)); + Exynos_OSAL_Memset(pHandle, 0, sizeof(EXYNOS_SHARED_MEMORY)); + if (pHandle == NULL) + goto EXIT; + + IONClient = (OMX_HANDLETYPE)ion_client_create(); + if (IONClient <= 0) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_client_create Error: %d", IONClient); + Exynos_OSAL_Free((void *)pHandle); + pHandle = NULL; + goto EXIT; + } + + pHandle->hIONHandle = IONClient; + + Exynos_OSAL_MutexCreate(&pHandle->hSMMutex); + +EXIT: + return (OMX_HANDLETYPE)pHandle; +} + +void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL; + + if (pHandle == NULL) + goto EXIT; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pCurrentElement = pSMList = pHandle->pAllocMemory; + + while (pCurrentElement != NULL) { + pDeleteElement = pCurrentElement; + pCurrentElement = pCurrentElement->pNextMemory; + + if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail"); + + pDeleteElement->mapAddr = NULL; + pDeleteElement->allocSize = 0; + + if (pDeleteElement->owner) + ion_free(pDeleteElement->IONBuffer); + pDeleteElement->IONBuffer = 0; + + Exynos_OSAL_Free(pDeleteElement); + + mem_cnt--; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt); + } + + pHandle->pAllocMemory = pSMList = NULL; + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + Exynos_OSAL_MutexTerminate(pHandle->hSMMutex); + pHandle->hSMMutex = NULL; + + ion_client_destroy((ion_client)pHandle->hIONHandle); + pHandle->hIONHandle = NULL; + + Exynos_OSAL_Free(pHandle); + +EXIT: + return; +} + +OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pElement = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + ion_buffer IONBuffer = 0; + OMX_PTR pBuffer = NULL; + unsigned int mask; + unsigned int flag; + + if (pHandle == NULL) + goto EXIT; + + pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST)); + Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST)); + pElement->owner = true; + + switch (memoryType) { + case SECURE_MEMORY: + mask = ION_HEAP_EXYNOS_CONTIG_MASK; + flag = ION_EXYNOS_FIMD_VIDEO_MASK; + break; + case NORMAL_MEMORY: + mask = ION_HEAP_EXYNOS_MASK; + flag = 0; + break; + case SYSTEM_MEMORY: + mask = ION_HEAP_SYSTEM_MASK; + flag = ION_FLAG_CACHED; + break; + default: + pBuffer = NULL; + goto EXIT; + break; + } + + IONBuffer = ion_alloc((ion_client)pHandle->hIONHandle, size, 0, mask, flag); + + if (IONBuffer <= 0) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer); + Exynos_OSAL_Free((OMX_PTR)pElement); + goto EXIT; + } + + pBuffer = ion_map(IONBuffer, size, 0); + if (pBuffer == MAP_FAILED) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error"); + ion_free(IONBuffer); + Exynos_OSAL_Free((OMX_PTR)pElement); + pBuffer = NULL; + goto EXIT; + } + + pElement->IONBuffer = IONBuffer; + pElement->mapAddr = pBuffer; + pElement->allocSize = size; + pElement->pNextMemory = NULL; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + pHandle->pAllocMemory = pSMList = pElement; + } else { + pCurrentElement = pSMList; + while (pCurrentElement->pNextMemory != NULL) { + pCurrentElement = pCurrentElement->pNextMemory; + } + pCurrentElement->pNextMemory = pElement; + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + mem_cnt++; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory alloc count: %d", mem_cnt); +#endif + +EXIT: + return pBuffer; +} + +void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL; + + if (pHandle == NULL) + goto EXIT; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + goto EXIT; + } + + pCurrentElement = pSMList; + if (pSMList->mapAddr == pBuffer) { + pDeleteElement = pSMList; + pHandle->pAllocMemory = pSMList = pSMList->pNextMemory; + } else { + while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer)) + pCurrentElement = pCurrentElement->pNextMemory; + + if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) { + pDeleteElement = pCurrentElement->pNextMemory; + pCurrentElement->pNextMemory = pDeleteElement->pNextMemory; + } else { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory"); + goto EXIT; + } + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail"); + goto EXIT; + } + pDeleteElement->mapAddr = NULL; + pDeleteElement->allocSize = 0; + + if (pDeleteElement->owner) + ion_free(pDeleteElement->IONBuffer); + pDeleteElement->IONBuffer = 0; + + Exynos_OSAL_Free(pDeleteElement); + + mem_cnt--; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory free count: %d", mem_cnt); +#endif + +EXIT: + return; +} + +#ifdef USE_DMA_BUF +OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int ionfd) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pElement = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + ion_buffer IONBuffer = 0; + OMX_PTR pBuffer = NULL; + + if (pHandle == NULL) + goto EXIT; + + pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST)); + Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST)); + + IONBuffer = (OMX_PTR)ionfd; + + if (IONBuffer <= 0) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer); + Exynos_OSAL_Free((void*)pElement); + goto EXIT; + } + + pBuffer = ion_map(IONBuffer, size, 0); + if (pBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error"); + ion_free(IONBuffer); + Exynos_OSAL_Free((void*)pElement); + goto EXIT; + } + + pElement->IONBuffer = IONBuffer; + pElement->mapAddr = pBuffer; + pElement->allocSize = size; + pElement->pNextMemory = NULL; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + pHandle->pAllocMemory = pSMList = pElement; + } else { + pCurrentElement = pSMList; + while (pCurrentElement->pNextMemory != NULL) { + pCurrentElement = pCurrentElement->pNextMemory; + } + pCurrentElement->pNextMemory = pElement; + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + mem_cnt++; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory alloc count: %d", mem_cnt); +#endif + +EXIT: + return pBuffer; +} + +void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int ionfd) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL; + + if (pHandle == NULL) + goto EXIT; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + goto EXIT; + } + + pCurrentElement = pSMList; + if (pSMList->IONBuffer == ionfd) { + pDeleteElement = pSMList; + pHandle->pAllocMemory = pSMList = pSMList->pNextMemory; + } else { + while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd)) + pCurrentElement = pCurrentElement->pNextMemory; + + if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) { + pDeleteElement = pCurrentElement->pNextMemory; + pCurrentElement->pNextMemory = pDeleteElement->pNextMemory; + } else { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory"); + goto EXIT; + } + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail"); + goto EXIT; + } + pDeleteElement->mapAddr = NULL; + pDeleteElement->allocSize = 0; + pDeleteElement->IONBuffer = 0; + + Exynos_OSAL_Free(pDeleteElement); + + mem_cnt--; +#ifndef SLP_PLATFORM + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt); +#else + Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory free count: %d", mem_cnt); +#endif + +EXIT: + return; +} +#endif + +int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + EXYNOS_SHAREDMEM_LIST *pFindElement = NULL; + int ion_addr = 0; + if (pHandle == NULL || pBuffer == NULL) + goto EXIT; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + goto EXIT; + } + + pCurrentElement = pSMList; + if (pSMList->mapAddr == pBuffer) { + pFindElement = pSMList; + } else { + while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer)) + pCurrentElement = pCurrentElement->pNextMemory; + + if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) { + pFindElement = pCurrentElement->pNextMemory; + } else { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory"); + goto EXIT; + } + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + ion_addr = pFindElement->IONBuffer; + +EXIT: + return ion_addr; +} + +OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr) +{ + EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle; + EXYNOS_SHAREDMEM_LIST *pSMList = NULL; + EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL; + EXYNOS_SHAREDMEM_LIST *pFindElement = NULL; + OMX_PTR pBuffer = NULL; + if (pHandle == NULL || ion_addr == 0) + goto EXIT; + + Exynos_OSAL_MutexLock(pHandle->hSMMutex); + pSMList = pHandle->pAllocMemory; + if (pSMList == NULL) { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + goto EXIT; + } + + pCurrentElement = pSMList; + if (pSMList->IONBuffer == ion_addr) { + pFindElement = pSMList; + } else { + while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ion_addr)) + pCurrentElement = pCurrentElement->pNextMemory; + + if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) && + (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ion_addr)) { + pFindElement = pCurrentElement->pNextMemory; + } else { + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory"); + goto EXIT; + } + } + Exynos_OSAL_MutexUnlock(pHandle->hSMMutex); + + pBuffer = pFindElement->mapAddr; + +EXIT: + return pBuffer; +} diff --git a/openmax/osal/Exynos_OSAL_SharedMemory.h b/openmax/osal/Exynos_OSAL_SharedMemory.h new file mode 100644 index 0000000..6b644c7 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_SharedMemory.h @@ -0,0 +1,56 @@ +/* + * + * 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 Exynos_OSAL_SharedMemory.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Taehwan Kim (t_h.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef EXYNOS_OSAL_SHAREDMEMORY +#define EXYNOS_OSAL_SHAREDMEMORY + +#include "OMX_Types.h" + +typedef enum _MEMORY_TYPE +{ + NORMAL_MEMORY = 0x00, + SECURE_MEMORY = 0x01, + SYSTEM_MEMORY = 0x02 +} MEMORY_TYPE; + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open(); +void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle); +OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType); +void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer); +int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer); +OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/openmax/osal/Exynos_OSAL_Thread.c b/openmax/osal/Exynos_OSAL_Thread.c new file mode 100644 index 0000000..9e9554f --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Thread.c @@ -0,0 +1,158 @@ +/* + * + * 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 Exynos_OSAL_Thread.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Exynos_OSAL_Memory.h" +#include "Exynos_OSAL_Thread.h" + +#undef EXYNOS_LOG_TAG +#define EXYNOS_LOG_TAG "EXYNOS_LOG_THREAD" +#define EXYNOS_LOG_OFF +#include "Exynos_OSAL_Log.h" + + +typedef struct _EXYNOS_THREAD_HANDLE_TYPE +{ + pthread_t pthread; + pthread_attr_t attr; + struct sched_param schedparam; + int stack_size; +} EXYNOS_THREAD_HANDLE_TYPE; + + +OMX_ERRORTYPE Exynos_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument) +{ + FunctionIn(); + + int result = 0; + int detach_ret = 0; + EXYNOS_THREAD_HANDLE_TYPE *thread; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + thread = Exynos_OSAL_Malloc(sizeof(EXYNOS_THREAD_HANDLE_TYPE)); + Exynos_OSAL_Memset(thread, 0, sizeof(EXYNOS_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) { + Exynos_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: + Exynos_OSAL_Free(thread); + *threadHandle = NULL; + ret = OMX_ErrorInsufficientResources; + break; + default: + Exynos_OSAL_Free(thread); + *threadHandle = NULL; + ret = OMX_ErrorUndefined; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pthread_join(thread->pthread, NULL) != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + Exynos_OSAL_Free(thread); + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle) +{ + EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) + return OMX_ErrorBadParameter; + + /* thread_cancel(thread->pthread); */ + pthread_exit(&thread->pthread); + pthread_join(thread->pthread, NULL); + + Exynos_OSAL_Free(thread); + return OMX_ErrorNone; +} + +void Exynos_OSAL_ThreadExit(void *value_ptr) +{ + pthread_exit(value_ptr); + return; +} + +void Exynos_OSAL_SleepMillisec(OMX_U32 ms) +{ + usleep(ms * 1000); + return; +} diff --git a/openmax/osal/Exynos_OSAL_Thread.h b/openmax/osal/Exynos_OSAL_Thread.h new file mode 100644 index 0000000..2048cb9 --- /dev/null +++ b/openmax/osal/Exynos_OSAL_Thread.h @@ -0,0 +1,48 @@ +/* + * + * 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 Exynos_OSAL_Thread.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 2.0.0 + * @history + * 2012.02.20 : Create + */ + +#ifndef Exynos_OSAL_THREAD +#define Exynos_OSAL_THREAD + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE Exynos_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument); +OMX_ERRORTYPE Exynos_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle); +OMX_ERRORTYPE Exynos_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle); +void Exynos_OSAL_ThreadExit(void *value_ptr); +void Exynos_OSAL_SleepMillisec(OMX_U32 ms); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openmax/osal/Makefile.am b/openmax/osal/Makefile.am new file mode 100644 index 0000000..4509e8a --- /dev/null +++ b/openmax/osal/Makefile.am @@ -0,0 +1,40 @@ +lib_LTLIBRARIES = libExynosOMX_OSAL.la + +libExynosOMX_OSAL_la_SOURCES = Exynos_OSAL_Event.c \ + Exynos_OSAL_Event.h \ + Exynos_OSAL_Queue.c \ + Exynos_OSAL_Queue.h \ + Exynos_OSAL_ETC.c \ + Exynos_OSAL_ETC.h \ + Exynos_OSAL_Mutex.c \ + Exynos_OSAL_Mutex.h \ + Exynos_OSAL_Thread.c \ + Exynos_OSAL_Thread.h \ + Exynos_OSAL_Memory.c \ + Exynos_OSAL_Memory.h \ + Exynos_OSAL_Semaphore.c \ + Exynos_OSAL_Semaphore.h \ + Exynos_OSAL_Library.c \ + Exynos_OSAL_Library.h \ + Exynos_OSAL_Log.c \ + Exynos_OSAL_Log.h \ + Exynos_OSAL_Platform_Specific.c \ + Exynos_OSAL_Platform_Specific.h \ + Exynos_OSAL_SharedMemory.c \ + Exynos_OSAL_SharedMemory.h + +libExynosOMX_OSAL_la_LIBADD = $(top_builddir)/exynos4/libion_exynos/libion_exynos.la + +libExynosOMX_OSAL_la_CFLAGS = -I$(top_srcdir)/exynos4/include \ + -I$(top_srcdir)/openmax/include/khronos \ + -I$(top_srcdir)/openmax/include/exynos \ + -I$(top_srcdir)/openmax/osal \ + -I$(top_srcdir)/openmax/component/common \ + -I$(top_srcdir)/openmax/component/video/dec \ + -I$(top_srcdir)/exynos/include \ + -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include + +if USE_DLOG +libExynosOMX_OSAL_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG +libExynosOMX_OSAL_la_LIBADD += $(DLOG_LIBS) +endif \ No newline at end of file diff --git a/packaging/libomxil-e3250-v4l2.spec b/packaging/libomxil-e3250-v4l2.spec new file mode 100755 index 0000000..2d629a2 --- /dev/null +++ b/packaging/libomxil-e3250-v4l2.spec @@ -0,0 +1,74 @@ +Name: libomxil-e3250-v4l2 +Summary: OpenMAX IL for e3250-v4l2 +Version: 0.0.16 +License: TO BE FILLED IN +Group: Development/Libraries +Release: 0 +ExclusiveArch: %arm +Source: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +#!BuildIgnore: kernel-headers +BuildRequires: kernel-headers-3.4-exynos3250 +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(mm-ta) + +%description +implementation of OpenMAX IL for e3250-v4l2 for B2 + + +%package devel +Summary: OpenMAX IL for e3250-v4l2 (Developement) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +development package for libomxil-e3250-v4l2 + +%prep +%setup -q + +%build +./autogen.sh + +export CFLAGS+=" -mfpu=neon\ + -DUSE_DLOG\ + -DUSE_PB\ + -DUSE_DMA_BUF\ + -DUSE_H264_PREPEND_SPS_PPS\ + -DGST_EXT_TIME_ANALYSIS" + +%configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-mm-ta --enable-exynos3250 + +#make %{?jobs:-j%jobs} +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp COPYING %{buildroot}/usr/share/license/%{name} +%make_install + + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%manifest libomxil-e3250-v4l2.manifest +/usr/lib/*.so* +/usr/lib/omx/libOMX.Exynos.AVC.Decoder.so +/usr/lib/omx/libOMX.Exynos.AVC.Encoder.so +/usr/lib/omx/libOMX.Exynos.M4V.Decoder.so +/usr/share/license/%{name} +%exclude /usr/lib/omx/libOMX.Exynos.M2V.Decoder.so +%exclude /usr/lib/omx/libOMX.Exynos.WMV.Decoder.so +%exclude /usr/lib/omx/libOMX.Exynos.M4V.Encoder.so +%exclude /usr/lib/omx/libOMX.Exynos.MP3.Decoder.so + +%files devel +/usr/include/* +/usr/lib/pkgconfig/* + diff --git a/srp.pc.in b/srp.pc.in new file mode 100644 index 0000000..2dc20c3 --- /dev/null +++ b/srp.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +libdir=@prefix@/lib +includedir=@prefix@/include + +Name: Samsung RP package +Description: Samsung RP API +Version: @VERSION@ +Requires: +Libs: -L${libdir} -lsrp + +Cflags: -I${includedir}/srp -DSLP_PLATFORM + diff --git a/tool/NV12T_converter b/tool/NV12T_converter new file mode 100755 index 0000000000000000000000000000000000000000..e7594a494c1b1d3ac277c12d043ceca099b2702c GIT binary patch literal 16224 zcmeHOeRNbsmaq4^lRW5ef3sZ~|Q$&TB zB=W(ctonZFAezX)m| zL2R`FQsQq9!}EvX9m8;V7>*6YQ-@*yFg$x0rmyT^g1FZPNLjzCVff}@I5iAU1a5iQ zY0#Hrg7z9IvR75DeO*TT8KVmikek3Ey6rzimtgieZuHxMOJU< zO?*p;&h!_VOlEUWGOzzFaQmM^o%+`!V|uT#x|fP7WG+9Anr9||fnRbmli30}G6(u# zAv2jR2~#$3Kw`EiOqUGwNX(XnIpqd+Nz4|8P2wjcW=q3Uh__437Kf{d@0XY@56>ZP zlb9X|*AU++F+CB!j(C~G^hkIaagD_EOn4=6mBjQ=_)cO|VtOjf1`T*5rpLl&av{u!)YVU3hx8Q_ z-rI1z48MCm*VD(fxrY-MYbY5{cc_2pZb5@X-Iq+8RcBx}_dX03Cdr!Y}PoJ~HYXE}o@SaG2 zr&OfsI=vnVPj-4sBypR1_k_cHvcr2C+;pG2{tkMUK0tLRYr>kzRF}A-V*p_pSMri+Ku1zclt%L94hHP2fSM(Dfm)HcO4&< zMaT2Hx%PE1E3t<6P-{vwaIHYc?tXqn z8PuSpLH!Vaj%WuQ=&BV*_Ppoly!}+ie|8-Fw+}o1_@E~ZQTjVa9P7ub91iaxhxZ5? z8-G5HlE9qrJ$c{8w6_mxeQv6$V&;2I_r}XGPSf5)9+X1=Y&?iYr@e=P4@>z!1KVzW zF2}78{{^>p-e4Xapl_j*^=(Ie*0J}Xs~q0a9LG+E=Ks~P1MKr}@a@1Br6b*opXi1}@b0A3RMDAJuxYj>Z6kqn$$>ZTs!7$&Yc${OQ+?AttQ8($-@D9m4qk z;6m-d!PA{9j%vST_a4EpKKQ}h1MZDnuLgV1y|qkY*@Fe^$J;f*@K@?RveyQCu~GFR z2K3>q&NbxiUAFp;+c~jr#mqW-a>EJU&~E`P3l!%pm#fAh~Ohd~uMJMgh~`F`UT> zSizpc63~C?XPJzY3{1rJuM>4n_c$?!FlV=Il9l1SJ^JTNM#&7wz^FquG>fxW@e39I zTZ-QUe)kt#V!A3w%k`y8s&kFm)}<_4>&ygNSH|4WZ&Ddh#(J<(2HQA-)UTv$_6X8C zC8Z}ukWN-oI%foFfs)cIFIRluX>7CnVAXbt5CHZJmqT6}UXyvB#=9mp04G z2Qb~R)E)c)%2PV_zl`$4r%8~TD)xfxY^Vr#Z$(L+TP4Q&k*(sxpJGuO9G(N;!(GyF z-(We%66DO#l@R8_`bJIm9W{UYjhgI7YTiGnIp{J} zhjKXN398lOqJ{CvR${`+Y`^|Q_8n(v_fGn*OU_oiJH8F^@HXu^H~^L$U0up9FNSb- zuH6kecK4rYSBJR!sN&1E^3vQTD{B}1?w?R}mntXQj2_jDQnZMZ6Q%Ov?!kO6M4hC6 zc~#z2Av=Xv=E0tPS9ypN4vT>MCETlNKMWVUc*AO z#*_fzIc5hW+d`*S-{HHxH+xUM0@uL)2oyH-{>=p#MJLKSTPmuyy~2C{{@?!*InpGj z?%R{mH)oPlXMCdW%R3iV%;}g`fl+FJtmf4x)AdhOO~0wl{VMftdT*I5>G+szStLI0 z?JTPpEPgv~ZA)PQ9zoU(y`P?s3$3#POBpX{G%asN`;Va}>Aj_^dDZ6g!;{>HNuSOn z$Gt+TX?yy(GjpKR0aof%T0RtPr|s-B-QzIazaAb)tLHbCpyBB?9EvoDljfD?a$Rpu2lt6)|zyUFZVPEJhAsmwGpx0a(tTr7@a zSHP6|0e>_aOPbs&m^8^0{zd`Qkm89y8uG_kh`3R5&d@iRK^kFhGm#1eLW#sYb8fa@exFUSSo4_3wF8C z&U4Ja4yl1ydNPvo7RE2L2KY-65ohG1qxDx(>JaHAt5r<^JPJq}&JO zd}Pq>T`siy4DGx^r}IJZP4LPPpZ!B7gTX08k+G<#aEaTMbheADC(gfgX2nI6*B~xH z*>dlsw#eA5Uo$38|H&ILgB?*J?nHbG@>LwgcU~vlfbPKr{_;E8-_u zx4z`YpRKDeN#{M_+~RONn@{z9R)#rH;U((r&odc6Ql(#8RJg@aTjY7bSzA<+&Rbek zr7tNe0izd^H(_#LZISa057bXH4}7CDMIf&b?fek-oRXv3Z-Unko}3ggkk;#p%)5#V z*y**@&L(F)aMlB7J#f|oXFYJ%17|((|Jnn1GU5&nk6UC)nzx7Y{t0ROCZ~auDN&E@ zyFY!Ei9L%mX6!kMBO7t1hV*S<-o*Y4kw*2#9I)X5Z59;fcOK%rx9%%*Vfg|GpDR*#2tKUdVM77kH^gF%Gs5(E}M~(%*&@L zEbq3}-Ke_%3_jpA9CVQtZpF!>CD+~oq0x13qPIfnfa?EGp_}S)0u|@T;VYCHc@62+<`=QP<@V{B;Rvz%%wGb9=Q+jG+I9o z{pHxgqI8z+cuXT^dDFXcfejGm`neQA!TU!2|km_Zu{)`L3DJTWml{Z%FLu&k%7K*iRGjBNt33z$u zXgti-%bi9qrKJ`$j9Dl&?_3KO8v6++TF_(gX({hK3zit~5tdo7)VQ9e&bMHh@gCs? z7Br3fscc%X!gz$1Cs}ZcQA>D{1*aKaRT3%+= zIc#j8bh%c8L@#dHIb%5B$mN)j++{ZR5;6K=Fpd27bu8%5$dP~VQCU&pdX4CBg6S_ zYbcw!U7}LgQd*hyBZ}!mzRdM6M5`2P5JlRTC_@{s z(UC!{Gh?@?b!J+g5bka%qe$N&+`CbRHeMm8`(bdk2?`nR1v#kDy^ER?WY6vJc=~Cj zRH2~fBcgK^3VS}yK`ov)i6$ypo9A4#P&-edq-QH_mML_n7^|(N?re?qO-jwMAY(38`OBSLGV#F6aMSkb!`ctrEOz;faWKB{?6 z5+<)gHb-*5=2=OPrIt$ggy#7vjjmPjDa|9tM>}imNbc4=a)7K;ut)P;M&)}I+^c!G z(W2eQ$*3n6cw{$ymmT9sKBIYLKdo2rSSgly|aCA%%j-q+4`L4yd%WzZ(m+LCX zaj~&TT=DYU;KBwIY88yr97Qe{GUaK2xDApP@)nPqgFBv4wm~6AXBAykbXkfpLd8N& zTRe{ZF_XmNann&kQKfcup{mU#g^S0riZ%JvaOY(!sUxSSdI%hwn{6;tF|-WTGG-Fn z(GR-#Io+UrUNi>3@|8z+$MjSpE??Md4g{u0X3v?eUfa8@IhvY|o0#d5XrLt(3<;@c zf$5Q1L-ZOWcx5bCL5N}d&y@l80bV%^hMFqFyqip}YYQbnqGo&(Ed~{g{nJ-uce4d``lnnhuHIVl!rSth?J-&kaEyRFnQ{*U(sOQ*@6+HZ{^*yo?5|5or0goGA}g$` zy6P4vR|+>N8_^NeYjgAF0!PG1!n&5fG2b!KSa1yC{bTR1($B{T^!Z{wQjB18 zeuNQ&w-5R1U?S-YU@$;2<-0rOr|!D87~WA#gk$k!W2#BM&WP04=*LTmO>I78YKcXg zP5G0GCL+zzP|)Q4FKjj9mBlp)PP>aHLT7^a=8be{NI4NNDcwiwJsVHBTtY$qV zb-65;FFpD~(ID83Eo%bNq|DReZ$<_2mL;ntrGZo&M>j30)~Kkn4giqFY7Ywa%O=KJ zf^-Ytv5fG{MV5{VHN^xQCl7{@Ef`vhVvs8pLBS}d)gNCIic3874jWW|Jso9n$H)-0nQp&wGKaokA6b)*_4?qizgXO=@^k*>x(8r0Wm!sYYk1m zYt5`S)L{C}u~a+|ntsC#i*EJJ$f*rIApMBL9A;%smM@(rs|vvK=sb{%7T0@~Ls=-8 z*`pxgV<*|CE5d5H>^9i|k!>RePh6;zBCGlA;|BER%!R&&m~YjJTdHvmh6bVEWZSsn zB-&WDwMl;?j@GQ6z=*;b7tguC@ySCwR1TvA730xTEl%!eCys6rczM~ZvmW>S@#eKs zV`-{&r6knvs+?-zc@f8E!XHSc{4H7I=vTTT8fwQc>oL39a*cGE9O&5&q<2v~rV(`8 z{6To0$xM~ZQVGW`m>9G^wv*P>FrF#YnHf#60W{l)cYjlDYGi=j%CQ-UFTzj|Xj8yC z#l-u+m}%5kV@}qJ>pYfstm{enh6EOM(gsr=KkFi8Fy&zqb&$wF{2U^AOm`{TV44Rl z=3|;K>A`%&d{LMAn2u7kAyZsfnNLT`$L!qlL}g-KE4mqJGOp6FO<|yf;%%Z52c4nH z+G`eHmPEr9!ez0tF%`kv?eKObQP`gdi^|}-DD0^eQ%_28Oq+1wc$J{ zs$pS$7Xg5~n{1$rp&Su+aOf)Q`vnM0&~`xY%E0XkTkk>aH}O2P!jdtu^%jE0i!w3V z<3821mOVV%$Ur^DrHB|IvRv+8y$wCSN{QP39f4u)bJ+n|WVi#r z+^b@_+^6b7ri(z^<&w|129bMPq`AM<4ZRxBx#a?idl5$=Qjhy%r=iCk8QUJ~N1R5q z^|+tL#&MsGdWDF#-d518E6d@2UONPppzT0ChAoJ;-Y)3vqQGt>Ncw~<`7DT(_W140 zE)@7E3$z0D7#=~i?Q#FGzF3HfQlftBav!tw*xoSo!qDT>gdJ?Xr@^2-isbh!*ifvu zm5|zcFM_u9j^b6CqtL6#X@{-%nxzN#s_$%g-Ebr|~* zZF>vwhWi3@ zrYU^L#3vJ+_*SrG=M2*uxI~CAZ6&0(9$$L4X^P*Ug87*Dm07rVH_m4J;kPv4}a@#h;;fEe%+~CYk0`NA%&Np*GB=a`0y%vd=h|ILCAC zEyMPUCx>C%gW4H^-=vYLzI0RTtiq~fuBQqsgIqTiX6b5wUtv@Xf&2ana|EmPPGQwi zT-OwqiCn)FW-Ac5P9Zo1pH0QA=Ej9!bK8uy-?UKG1mo! z)hfjKuP}Q>&2xpZ$RKb&E3B?ioVN<|v_j2Kh1IDB=b^$An8@=Dh2^P+;Ji|}l!=@_ z3iAc-!QdFO60-fgY7Pd6JU__Ac*!g$IK%}xi1{(;bAm&dL&m;Se3YR_`9>SnG<2;jhzP) zR$%!_(4{%$ZvZxbVAp4?_*>xI^0|X*TK!9VF96$t_Id&A_V6pZL%{ZVkA_pI{}?7e z3C#5o3F>x^$VUbFT@hzOG3-wOJ_*cqpjaOx&If+aI*1{z2Dbax#Fvcx3dRl`O*ak0 zeqh_)MabU-EI&+*iN&<_3Iy>GLfd zf|k_fh=MU+b4#odPk{1{-sexX3*4=@wS~ z>pHs}@6v^`m_^HLZ}9qT#A0lEuoU_DAWJ!OqmGZZ5o}1rBvRPGz~hYkoRm+p++eJ14kdkU z0beqlims__Y?nI}>RVCkGt-(H`wP)3`Qd0TmisookbJ69pP>#)@!&gHT+Y|4gBpAa zmfxTbvQUJ4d>z8!Q+6&xeIc96vAR>aR(%LNRLmOMt->d@Lxn@W%f)_9BIXPGqrnz@ zBa6rBoKJJl_>wl)&fsQ-wTqDBclMO}qIWRI4D0*dK~9xWJ#2L*b~?iMz(sgkw5qNi j@t3UiEe|zE5_l}GYw;%%cxW6f+uBIshrdG%%NqO-*VlQn literal 0 HcmV?d00001 diff --git a/tool/NV12T_converter.c b/tool/NV12T_converter.c new file mode 100755 index 0000000..de9dd8c --- /dev/null +++ b/tool/NV12T_converter.c @@ -0,0 +1,208 @@ +/* + * + * Copyright 2015 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 + +/* 2D Configurable tiled memory access (TM) + * Return the linear address from tiled position (x, y) */ +unsigned int Tile2D_To_Linear(unsigned int width, unsigned int height, + unsigned int xpos, unsigned int ypos, int crFlag) +{ + int tileNumX; + int tileX, tileY; + int tileAddr; + int offset; + int addr; + + width = ((width + 15) / 16)*16; + tileNumX = width / 16; + + /* crFlag - 0: Y plane, 1: CbCr plane */ + if (crFlag == 0) + { + tileX = xpos / 16; + tileY = ypos / 16; + tileAddr = tileY * tileNumX + tileX; + offset = (ypos & 15) * 16 + (xpos & 15); + addr = (tileAddr << 8) | offset; + } + else + { + tileX = xpos / 16; + tileY = ypos / 8; + tileAddr = tileY * tileNumX + tileX; + offset = (ypos & 7) * 16 + (xpos & 15); + addr = (tileAddr << 7) | offset; + } + + return addr; +} + +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; + + printf("height = %d width = %d y_addr= %x c_addr = %x \n", height, width, y_addr, c_addr); + + // 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; + } + } + } + } + } +} + +int main (int argc, char **argv) +{ + int i = 0; + int j = 0; + int size = 0; + + char filename[100]={0}; + FILE *fp_in = NULL; + FILE *fp_out = NULL; + + unsigned int width; + unsigned int height; + unsigned int num_frame; + + struct stat input_file_info; + + unsigned char* Y_plane = NULL; + unsigned char* Cb_plane = NULL; + unsigned char* Cr_plane = NULL; + + unsigned int* c_addr = NULL; + unsigned int* y_addr = NULL; + + if(argc != 4) + { + printf("Usage : NV12T_converter [file_path] width height ex)NV12T_converter out.yuv 1280 720\n"); + return 0; + } + + strcpy(filename, argv[1]); + width = atoi(argv[2]); + height = atoi(argv[3]); + printf("file path=%s, width = %d, height = %d \n", filename, width, height); + + /**/ + Y_plane = (unsigned char*)malloc(width * height); + Cb_plane = (unsigned char*)malloc(width * height); + Cr_plane = (unsigned char*)malloc(width * height); + + c_addr = (unsigned int*)malloc(width * height); + y_addr = (unsigned int*)malloc(width * height); + + fp_in = fopen(filename, "r"); + if (fp_in == NULL) + printf ("Input file cannot open!! \n"); + + fp_out = fopen("output_linear.yuv", "ab"); + if (fp_out == NULL) + printf ("Output file cannot open !! \n"); + + printf("file open success: %s \n", filename); + + stat(filename, &input_file_info); + num_frame = input_file_info.st_size / (width*height*3/2); + + printf("file size = %d, num_frame = %d \n", input_file_info.st_size, num_frame); + + for (i=0; i < num_frame; i++) + { + memset(Y_plane, 0xff, width * height); + memset(Cb_plane, 0xff, width * height); + memset(Cr_plane, 0xff, width * height); + memset(c_addr, 0xff, width * height); + memset(y_addr, 0xff, width * height); + + size = fread(y_addr, 1, width * height, fp_in); + printf("[fread] y_addr size = %d \n", size); + size = fread(c_addr, 1, (width * height)/2, fp_in); + printf("[fread] c_addr size = %d \n", size); + printf("[tiled_transcode] y_addr: 0x%x c_addr: 0x%x \n", y_addr, c_addr); + + Tile2D_To_YUV420(Y_plane, Cb_plane, Cr_plane, y_addr, c_addr, width, height); + printf (" Y_plane %02x %02x %02x %02x %02x \n", Y_plane[0], Y_plane[1], Y_plane[2], Y_plane[3], Y_plane[4]); + + size = fwrite(Y_plane, 1, width * height, fp_out); + printf("write Y_plane size = %d \n", size); + size = fwrite(Cb_plane, 1, (width * height / 4), fp_out); + printf("write Cb_plane size = %d \n", size); + size = fwrite(Cr_plane, 1, (width * height / 4), fp_out); + printf("write Cr_plane size = %d \n", size); + printf("count = %d \n", i); + } + + free(Y_plane); + free(Cb_plane); + free(Cr_plane); + free(c_addr); + free(y_addr); + + fclose (fp_in); + fclose (fp_out); + + return 0; +} -- 2.7.4 From d13508130aeb99537fcd12782785db753efd1b7f Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 24 Mar 2016 10:22:38 +0900 Subject: [PATCH 3/7] Changed sources for compiling Change-Id: I7b3a6c5572a3d816d30a8a828e5f411f7c612c8a --- configure.ac | 32 +- exynos/include/exynos_v4l2.h | 13 +- exynos/include/media.h | 132 ++ exynos/include/v4l2-mediabus.h | 116 + exynos/include/v4l2-subdev.h | 141 ++ exynos/include/videodev2.h | 2452 ++++++++++++++++++++ exynos/include/videodev2_exynos_media.h | 236 ++ exynos/kernel_header/compiler.h | 307 +++ exynos/kernel_header/media.h | 132 ++ exynos/kernel_header/v4l2-mediabus.h | 111 + exynos/kernel_header/v4l2-subdev.h | 145 ++ exynos/libcsc/csc.c | 24 + exynos/libv4l2/exynos_mc.c | 7 +- exynos/libv4l2/exynos_v4l2.c | 2 +- exynos4/libcodec/video/v4l2/Makefile.am | 6 +- .../libcodec/video/v4l2/dec/ExynosVideoDecoder.c | 120 +- .../libcodec/video/v4l2/enc/ExynosVideoEncoder.c | 119 +- exynos4/libswconverter/Makefile.am | 18 +- exynos4/libswconverter/swconvertor.c | 2 + openmax/component/audio/dec/mp3/Makefile.am | 2 +- openmax/component/video/dec/Exynos_OMX_Vdec.c | 46 +- .../component/video/dec/Exynos_OMX_VdecControl.c | 39 +- openmax/component/video/dec/Makefile.am | 11 +- .../component/video/dec/h264/Exynos_OMX_H264dec.c | 7 +- .../component/video/dec/h264/Exynos_OMX_H264dec.h | 3 + openmax/component/video/dec/h264/Makefile.am | 5 +- .../video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c | 1 + .../video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h | 3 + openmax/component/video/dec/mpeg2/Makefile.am | 6 +- .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 3 +- .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h | 2 + openmax/component/video/dec/mpeg4/Makefile.am | 5 +- .../component/video/dec/vc1/Exynos_OMX_Wmvdec.h | 3 + openmax/component/video/dec/vc1/Makefile.am | 2 +- openmax/component/video/enc/Exynos_OMX_Venc.c | 7 +- .../component/video/enc/Exynos_OMX_VencControl.c | 27 + openmax/component/video/enc/Makefile.am | 5 +- .../video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c | 6 +- openmax/component/video/enc/mpeg4/Makefile.am | 2 +- openmax/include/exynos/Exynos_OMX_Def.h | 4 +- openmax/osal/Exynos_OSAL_Platform_Specific.c | 84 +- openmax/osal/Makefile.am | 3 + packaging/libomxil-e3250-v4l2.spec | 39 +- srp.pc.in | 2 +- 44 files changed, 4104 insertions(+), 328 deletions(-) mode change 100644 => 100755 exynos/include/exynos_v4l2.h create mode 100755 exynos/include/media.h create mode 100755 exynos/include/v4l2-mediabus.h create mode 100755 exynos/include/v4l2-subdev.h create mode 100755 exynos/include/videodev2.h create mode 100755 exynos/include/videodev2_exynos_media.h create mode 100755 exynos/kernel_header/compiler.h create mode 100755 exynos/kernel_header/media.h create mode 100755 exynos/kernel_header/v4l2-mediabus.h create mode 100755 exynos/kernel_header/v4l2-subdev.h mode change 100644 => 100755 exynos/libcsc/csc.c mode change 100644 => 100755 exynos/libv4l2/exynos_mc.c mode change 100644 => 100755 exynos/libv4l2/exynos_v4l2.c mode change 100644 => 100755 exynos4/libcodec/video/v4l2/Makefile.am mode change 100644 => 100755 exynos4/libswconverter/Makefile.am mode change 100644 => 100755 exynos4/libswconverter/swconvertor.c mode change 100644 => 100755 openmax/component/audio/dec/mp3/Makefile.am mode change 100644 => 100755 openmax/component/video/dec/Exynos_OMX_VdecControl.c mode change 100644 => 100755 openmax/component/video/dec/Makefile.am mode change 100644 => 100755 openmax/component/video/dec/h264/Exynos_OMX_H264dec.h mode change 100644 => 100755 openmax/component/video/dec/h264/Makefile.am mode change 100644 => 100755 openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c mode change 100644 => 100755 openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h mode change 100644 => 100755 openmax/component/video/dec/mpeg2/Makefile.am mode change 100644 => 100755 openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c mode change 100644 => 100755 openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h mode change 100644 => 100755 openmax/component/video/dec/mpeg4/Makefile.am mode change 100644 => 100755 openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h mode change 100644 => 100755 openmax/component/video/dec/vc1/Makefile.am mode change 100644 => 100755 openmax/component/video/enc/Exynos_OMX_Venc.c mode change 100644 => 100755 openmax/component/video/enc/Exynos_OMX_VencControl.c mode change 100644 => 100755 openmax/component/video/enc/Makefile.am mode change 100644 => 100755 openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c mode change 100644 => 100755 openmax/component/video/enc/mpeg4/Makefile.am mode change 100644 => 100755 openmax/include/exynos/Exynos_OMX_Def.h mode change 100644 => 100755 openmax/osal/Makefile.am mode change 100644 => 100755 srp.pc.in diff --git a/configure.ac b/configure.ac index 4a336a0..cc2ad52 100755 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,10 @@ AM_INIT_AUTOMAKE([tar-ustar]) # Set to 'm4' the directory where the extra autoconf macros are stored AC_CONFIG_MACRO_DIR([m4]) +PKG_CHECK_MODULES(MM_COMMON, mm-common) +AC_SUBST(MM_COMMON_CFLAGS) +AC_SUBST(MM_COMMON_LIBS) + AC_CONFIG_FILES([ omxil-e3250-v4l2.pc srp.pc @@ -93,23 +97,6 @@ fi AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes") dnl end ----------------------------------------------------------------------- -dnl use mm-ta ------------------------------------------------------------------ -AC_ARG_ENABLE(mm-ta, AC_HELP_STRING([--enable-mm-ta], [using mm-ta]), - [ - case "${enableval}" in - yes) USE_MMTA=yes ;; - no) USE_MMTA=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-mm-ta) ;; - esac - ],[USE_MMTA=no]) - -if test "x$USE_MMTA" = "xyes"; then - PKG_CHECK_MODULES(MMTA, mm-ta) - AC_SUBST(MMTA_CFLAGS) - AC_SUBST(MMTA_LIBS) -fi -AM_CONDITIONAL(USE_MMTA, test "x$USE_MMTA" = "xyes") -dnl end ----------------------------------------------------------------------- AC_ARG_ENABLE([exynos3250], AC_HELP_STRING([--enable-exynos3250], [Enable exynos3250 specific code]), [ case "${enableval}" in @@ -209,4 +196,15 @@ AC_ARG_ENABLE(drm, AC_HELP_STRING([--enable-use-drm], [use drm]), [BOARD_USE_DRM=no]) AM_CONDITIONAL([BOARD_USE_DRM], [test "x$BOARD_USE_DRM" = "xyes"]) +AC_ARG_ENABLE(neon, AC_HELP_STRING([--enable-neon], [neon]), + [ + case "${enableval}" in + yes) BOARD_USE_NEON=yes ;; + no) BOARD_USE_NEON=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-neon) ;; + esac + ], + [BOARD_USE_NEON=no]) +AM_CONDITIONAL([BOARD_USE_NEON], [test "x$BOARD_USE_NEON" = "xyes"]) + AC_OUTPUT diff --git a/exynos/include/exynos_v4l2.h b/exynos/include/exynos_v4l2.h old mode 100644 new mode 100755 index 2abbb5c..b682703 --- a/exynos/include/exynos_v4l2.h +++ b/exynos/include/exynos_v4l2.h @@ -43,7 +43,7 @@ extern "C" { #include #ifdef SLP_PLATFORM #include -#include +//#include #else #include "videodev2.h" /* vendor specific videodev2.h */ #include "videodev2_exynos_media.h" @@ -108,7 +108,11 @@ int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl); #include #else +#ifdef KERNEL_HEADER_MODIFICATION +#include "../kernel_header/v4l2-subdev.h" +#else #include +#endif #endif @@ -140,8 +144,13 @@ int exynos_subdev_enum_mbus_code(int fd, struct v4l2_subdev_mbus_code_enum *mbus #include #else -//#include +#ifdef KERNEL_HEADER_MODIFICATION +#include "../kernel_header/compiler.h" +#include "../kernel_header/media.h" +#else +#include #include +#endif #endif diff --git a/exynos/include/media.h b/exynos/include/media.h new file mode 100755 index 0000000..0ef8833 --- /dev/null +++ b/exynos/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/exynos/include/v4l2-mediabus.h b/exynos/include/v4l2-mediabus.h new file mode 100755 index 0000000..1a13cf3 --- /dev/null +++ b/exynos/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/exynos/include/v4l2-subdev.h b/exynos/include/v4l2-subdev.h new file mode 100755 index 0000000..f5dd9a1 --- /dev/null +++ b/exynos/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/exynos/include/videodev2.h b/exynos/include/videodev2.h new file mode 100755 index 0000000..d4fde43 --- /dev/null +++ b/exynos/include/videodev2.h @@ -0,0 +1,2452 @@ +/* + * 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, + V4L2_MEMORY_DMABUF = 4, +}; + +/* 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; +}; + +/** + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP + * + * @driver: name of the driver module (e.g. "bttv") + * @card: name of the card (e.g. "Hauppauge WinTV") + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) + * @version: KERNEL_VERSION + * @capabilities: capabilities of the physical device as a whole + * @device_caps: capabilities accessed via this particular device (node) + * @reserved: reserved fields for future extensions + */ +struct v4l2_capability { + __u8 driver[16]; + __u8 card[32]; + __u8 bus_info[32]; + __u32 version; + __u32 capabilities; + __u32 device_caps; + __u32 reserved[3]; +}; + +/* 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 */ + +#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ + +/* + * 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 */ +#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ +#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ + +/* 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_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 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 Multiplexed */ +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ +#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ +#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ +#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */ +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ +#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ +#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ + +/* 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_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB 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_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ + +/* + * 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 + * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file + * descriptor associated with 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; + int fd; + } m; + __u32 data_offset; + __u32 reserved[11]; +}; + +/** + * 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 + * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; + * a userspace file descriptor associated with 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; + int fd; + } 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 */ +#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ +/* Cache handling flags */ +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 + +/* + * 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; +}; + +/* Hints for adjustments of selection rectangle */ +#define V4L2_SEL_FLAG_GE 0x00000001 +#define V4L2_SEL_FLAG_LE 0x00000002 + +/* Selection targets */ + +/* Current cropping area */ +#define V4L2_SEL_TGT_CROP_ACTIVE 0x0000 +/* Default cropping area */ +#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 +/* Cropping bounds */ +#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 +/* Current composing area */ +#define V4L2_SEL_TGT_COMPOSE_ACTIVE 0x0100 +/* Default composing area */ +#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 +/* Composing bounds */ +#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 +/* Current composing area plus all padding pixels */ +#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 + +/** + * struct v4l2_selection - selection info + * @type: buffer type (do not use *_MPLANE types) + * @target: selection target, used to choose one of possible rectangles + * @flags: constraints flags + * @r: coordinates of selection window + * @reserved: for future use, rounds structure size to 64 bytes, set to zero + * + * Hardware may use multiple helper windows to process a video stream. + * The structure is used to exchange this selection areas between + * an application and a driver. + */ +struct v4l2_selection { + __u32 type; + __u32 target; + __u32 flags; + struct v4l2_rect r; + __u32 reserved[9]; +}; + + +/* + * 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) /* BTSC */ +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ +#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ + +#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 macros to merge video standards in order to make live easier for the + * drivers and V4L2 applications + */ + +/* + * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is + * Missing here. + */ +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) +/* Secam macros */ +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1) +/* All Secam Standards */ +#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) +/* PAL macros */ +#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) +/* + * "Common" PAL - This macro is there to be compatible with the old + * V4L1 concept of "PAL": /BGDKHI. + * Several PAL standards are mising here: /M, /N and /Nc + */ +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +/* Chroma "agnostic" standards */ +#define V4L2_STD_B (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_SECAM_B) +#define V4L2_STD_G (V4L2_STD_PAL_G |\ + V4L2_STD_SECAM_G) +#define V4L2_STD_H (V4L2_STD_PAL_H |\ + V4L2_STD_SECAM_H) +#define V4L2_STD_L (V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +#define V4L2_STD_GH (V4L2_STD_G |\ + V4L2_STD_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK |\ + V4L2_STD_SECAM_DK) +#define V4L2_STD_BG (V4L2_STD_B |\ + V4L2_STD_G) +#define V4L2_STD_MN (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_NTSC) + +/* Standards where MTS/BTSC stereo could be found */ +#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ + V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc) + +/* Standards for Countries with 60Hz Line frequency */ +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC |\ + V4L2_STD_NTSC_443) +/* Standards for Countries with 50Hz Line frequency */ +#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) +/* Macros with none and all analog standards */ +#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_FLASH 0x009c0000 /* Camera flash controls */ +#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ +#define V4L2_CTRL_CLASS_CODEC 0x009e0000 /* 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, + V4L2_CTRL_TYPE_BITMASK = 8, +}; + +/* 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 +#define V4L2_CTRL_FLAG_VOLATILE 0x0080 + +/* 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_MAX_CTRLS 1024 +#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, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; +#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) + +#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) +#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) + +#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+42) + +/* 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, specific to multiplexed 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 controls specific to multiplexed streams */ +#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, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) +enum v4l2_mpeg_audio_dec_playback { + V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) + +/* MPEG video controls specific to multiplexed streams */ +#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) +#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) +#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) +#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) +#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) +#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) +enum v4l2_mpeg_video_header_mode { + V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, + +}; +#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) +#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) +enum v4l2_mpeg_video_multi_slice_mode { + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) +#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) +#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) + +#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) +#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) +#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) +#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) +#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) +#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) +#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) +#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) +#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) +#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) +enum v4l2_mpeg_video_h264_entropy_mode { + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) +#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) +enum v4l2_mpeg_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, + V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, + V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, + V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, + V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, + V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, + V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, + V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, + V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, +}; +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) +enum v4l2_mpeg_video_h264_loop_filter_mode { + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, +}; +#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) +enum v4l2_mpeg_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, + V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, + V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, + V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, + V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, +}; +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) +enum v4l2_mpeg_video_h264_vui_sar_idc { + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) +#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) +#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) +#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) +enum v4l2_mpeg_video_mpeg4_level { + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) +enum v4l2_mpeg_video_mpeg4_profile { + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) + +/* 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) + +/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ +#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) + +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) +enum v4l2_mpeg_mfc51_video_frame_skip_mode { + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) +enum v4l2_mpeg_mfc51_video_force_frame_type { + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) + +/* 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) + +/* Flash and privacy (indicator) light controls */ +#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) +#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) + +#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) +enum v4l2_flash_led_mode { + V4L2_FLASH_LED_MODE_NONE, + V4L2_FLASH_LED_MODE_FLASH, + V4L2_FLASH_LED_MODE_TORCH, +}; + +#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) +enum v4l2_flash_strobe_source { + V4L2_FLASH_STROBE_SOURCE_SOFTWARE, + V4L2_FLASH_STROBE_SOURCE_EXTERNAL, +}; + +#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) +#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) +#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) + +#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) +#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) +#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) +#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) + +#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) +#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) +#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) +#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) +#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) +#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) +#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) + +#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) +#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) + +/* JPEG-class control IDs defined by V4L2 */ +#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) +#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) + +#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) +enum v4l2_jpeg_chroma_subsampling { + V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, + V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, + V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, + V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, + V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, +}; +#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) +#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) + +#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) +#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) +#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) +#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) +#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) +#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) + +/* + * 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; + }; +}; + +/* Decoder commands */ +#define V4L2_DEC_CMD_START (0) +#define V4L2_DEC_CMD_STOP (1) +#define V4L2_DEC_CMD_PAUSE (2) +#define V4L2_DEC_CMD_RESUME (3) + +/* Flags for V4L2_DEC_CMD_START */ +#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) + +/* Flags for V4L2_DEC_CMD_PAUSE */ +#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) + +/* Flags for V4L2_DEC_CMD_STOP */ +#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) +#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) + +/* Play format requirements (returned by the driver): */ + +/* The decoder has no special format requirements */ +#define V4L2_DEC_START_FMT_NONE (0) +/* The decoder requires full GOPs */ +#define V4L2_DEC_START_FMT_GOP (1) + +/* The structure must be zeroed before use by the application + This ensures it can be extended safely in the future. */ +struct v4l2_decoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u64 pts; + } stop; + + struct { + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; + __u32 format; + } start; + + struct { + __u32 data[16]; + } 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_CTRL 3 +#define V4L2_EVENT_FRAME_SYNC 4 +#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)); + +/* Payload for V4L2_EVENT_CTRL */ +#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) +#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) + +struct v4l2_event_ctrl { + __u32 changes; + __u32 type; + union { + __s32 value; + __s64 value64; + }; + __u32 flags; + __s32 minimum; + __s32 maximum; + __s32 step; + __s32 default_value; +}; + +struct v4l2_event_frame_sync { + __u32 frame_sequence; +}; + +struct v4l2_event { + __u32 type; + union { + struct v4l2_event_vsync vsync; + struct v4l2_event_ctrl ctrl; + struct v4l2_event_frame_sync frame_sync; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + struct timespec timestamp; + __u32 id; + __u32 reserved[8]; +}; + +#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) +#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) + +struct v4l2_event_subscription { + __u32 type; + __u32 id; + __u32 flags; + __u32 reserved[5]; +}; + +/* + * 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)); + +/** + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument + * @index: on return, index of the first created buffer + * @count: entry: number of requested buffers, + * return: number of created buffers + * @memory: buffer memory type + * @format: frame format, for which buffers are requested + * @reserved: future extensions + */ +struct v4l2_create_buffers { + __u32 index; + __u32 count; + enum v4l2_memory memory; + struct v4l2_format format; + __u32 reserved[8]; +}; + +/* + * 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) + +/* Experimental, the below two ioctls may change over the next couple of kernel + versions */ +#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) +#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) + +/* Experimental selection API */ +#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) +#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) + +/* Experimental, these two ioctls may change over the next couple of kernel + versions. */ +#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) +#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) + +/* 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/exynos/include/videodev2_exynos_media.h b/exynos/include/videodev2_exynos_media.h new file mode 100755 index 0000000..a952438 --- /dev/null +++ b/exynos/include/videodev2_exynos_media.h @@ -0,0 +1,236 @@ +/* + * Video for Linux Two header file for Exynos + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until being accepted, will be used restrictly for Exynos. + * + * 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_VIDEODEV2_EXYNOS_MEDIA_H +#define __LINUX_VIDEODEV2_EXYNOS_MEDIA_H + +/* Pixel format FOURCC depth Description */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P') /* 24 Y/CbCr */ +#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P') /* 24 Y/CrCb */ + +/* three planes -- one Y, one Cr, one Cb */ +#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P') /* 24 Y/Cb/Cr */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +/* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') +/* 12 Y/CbCr 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') + +/* three non contiguous planes - Y, Cb, Cr */ +/* 12 YVU420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'V', 'U', 'M') + +/* compressed formats */ +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ +#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_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + +/* yuv444 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4') +/* yuv422 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2') +/* yuv420 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0') +/* grey of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G') + +/* + * C O N T R O L S + */ +/* CID base for Exynos controls (USER_CLASS) */ +#define V4L2_CID_EXYNOS_BASE (V4L2_CTRL_CLASS_USER | 0x2000) + +/* for rgb alpha function */ +#define V4L2_CID_GLOBAL_ALPHA (V4L2_CID_EXYNOS_BASE + 1) + +/* cacheable configuration */ +#define V4L2_CID_CACHEABLE (V4L2_CID_EXYNOS_BASE + 10) + +/* jpeg captured size */ +#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_EXYNOS_BASE + 20) +#define V4L2_CID_CAM_JPEG_ENCODEDSIZE (V4L2_CID_EXYNOS_BASE + 21) + +#define V4L2_CID_SET_SHAREABLE (V4L2_CID_EXYNOS_BASE + 40) + +/* TV configuration */ +#define V4L2_CID_TV_LAYER_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 50) +#define V4L2_CID_TV_LAYER_BLEND_ALPHA (V4L2_CID_EXYNOS_BASE + 51) +#define V4L2_CID_TV_PIXEL_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 52) +#define V4L2_CID_TV_CHROMA_ENABLE (V4L2_CID_EXYNOS_BASE + 53) +#define V4L2_CID_TV_CHROMA_VALUE (V4L2_CID_EXYNOS_BASE + 54) +#define V4L2_CID_TV_HPD_STATUS (V4L2_CID_EXYNOS_BASE + 55) +#define V4L2_CID_TV_LAYER_PRIO (V4L2_CID_EXYNOS_BASE + 56) +#define V4L2_CID_TV_SET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 57) +#define V4L2_CID_TV_GET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 58) +#define V4L2_CID_TV_SET_ASPECT_RATIO (V4L2_CID_EXYNOS_BASE + 59) + +/* for color space conversion equation selection */ +#define V4L2_CID_CSC_EQ_MODE (V4L2_CID_EXYNOS_BASE + 100) +#define V4L2_CID_CSC_EQ (V4L2_CID_EXYNOS_BASE + 101) +#define V4L2_CID_CSC_RANGE (V4L2_CID_EXYNOS_BASE + 102) + +#define V4L2_CID_CONTENT_PROTECTION (V4L2_CID_EXYNOS_BASE + 201) + +/* CID base for MFC controls (MPEG_CLASS) */ +#define V4L2_CID_MPEG_MFC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL \ + (V4L2_CID_MPEG_MFC_BASE + 1) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID \ + (V4L2_CID_MPEG_MFC_BASE + 2) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO \ + (V4L2_CID_MPEG_MFC_BASE + 3) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS \ + (V4L2_CID_MPEG_MFC_BASE + 4) + +#define V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB \ + (V4L2_CID_MPEG_MFC_BASE + 5) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG \ + (V4L2_CID_MPEG_MFC_BASE + 6) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE \ + (V4L2_CID_MPEG_MFC_BASE + 7) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA \ + (V4L2_CID_MPEG_MFC_BASE + 8) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA \ + (V4L2_CID_MPEG_MFC_BASE + 9) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 10) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 11) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED \ + (V4L2_CID_MPEG_MFC_BASE + 12) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE \ + (V4L2_CID_MPEG_MFC_BASE + 13) +#define V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS \ + (V4L2_CID_MPEG_MFC_BASE + 14) + +#define V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 15) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 16) + +#define V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE \ + (V4L2_CID_MPEG_MFC_BASE + 17) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT \ + (V4L2_CID_MPEG_MFC_BASE + 18) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 19) +enum v4l2_mpeg_mfc51_video_frame_type { + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_NOT_CODED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_P_FRAME = 2, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_B_FRAME = 3, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_SKIPPED = 4, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_OTHERS = 5, +}; + +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE \ + (V4L2_CID_MPEG_MFC_BASE + 20) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 21) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES \ + (V4L2_CID_MPEG_MFC_BASE + 22) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 23) +#define V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 24) + +#define V4L2_CID_MPEG_MFC6X_VIDEO_FRAME_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 25) + +#define V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH V4L2_CID_MPEG_VIDEO_GOP_SIZE +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH \ + V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE +#define V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH V4L2_CID_MPEG_VIDEO_BITRATE + +/* new entry for enum v4l2_mpeg_video_mpeg4_level */ +#define V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 8 + +/* proposed CIDs, based on 3.3-rc3 */ +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_MFC_BASE + 26) + +#define V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B \ + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING \ + (V4L2_CID_MPEG_MFC_BASE + 27) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 \ + (V4L2_CID_MPEG_MFC_BASE + 28) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 29) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_CHEKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO \ + (V4L2_CID_MPEG_MFC_BASE + 30) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 31) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP \ + (V4L2_CID_MPEG_MFC_BASE + 32) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION \ + (V4L2_CID_MPEG_MFC_BASE + 33) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 34) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH \ + (V4L2_CID_MPEG_MFC_BASE + 35) +#define V4L2_CID_MPEG_VIDEO_H264_ASO \ + (V4L2_CID_MPEG_MFC_BASE + 36) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER \ + (V4L2_CID_MPEG_MFC_BASE + 37) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING \ + (V4L2_CID_MPEG_MFC_BASE + 38) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 39) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER \ + (V4L2_CID_MPEG_MFC_BASE + 40) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP \ + (V4L2_CID_MPEG_MFC_BASE + 41) + +#define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID \ + (V4L2_CID_MPEG_MFC_BASE + 42) + +#define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46) + +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS \ + (V4L2_CID_MPEG_MFC_BASE + 43) +#endif /* __LINUX_VIDEODEV2_EXYNOS_MEDIA_H */ diff --git a/exynos/kernel_header/compiler.h b/exynos/kernel_header/compiler.h new file mode 100755 index 0000000..c1a62c5 --- /dev/null +++ b/exynos/kernel_header/compiler.h @@ -0,0 +1,307 @@ +#ifndef __LINUX_COMPILER_H +#define __LINUX_COMPILER_H + +#ifndef __ASSEMBLY__ + +#ifdef __CHECKER__ +# define __user __attribute__((noderef, address_space(1))) +# define __kernel __attribute__((address_space(0))) +# define __safe __attribute__((safe)) +# define __force __attribute__((force)) +# define __nocast __attribute__((nocast)) +# define __iomem __attribute__((noderef, address_space(2))) +# define __acquires(x) __attribute__((context(x,0,1))) +# define __releases(x) __attribute__((context(x,1,0))) +# define __acquire(x) __context__(x,1) +# define __release(x) __context__(x,-1) +# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) +# define __percpu __attribute__((noderef, address_space(3))) +# define __rcu +extern void __chk_user_ptr(const volatile void __user *); +extern void __chk_io_ptr(const volatile void __iomem *); +#else +# define __user +# define __kernel +# define __safe +# define __force +# define __nocast +# define __iomem +# define __chk_user_ptr(x) (void)0 +# define __chk_io_ptr(x) (void)0 +# define __builtin_warning(x, y...) (1) +# define __acquires(x) +# define __releases(x) +# define __acquire(x) (void)0 +# define __release(x) (void)0 +# define __cond_lock(x,c) (c) +# define __percpu +# define __rcu +#endif + +#ifdef __KERNEL__ + +#ifdef __GNUC__ +#include +#endif + +#define notrace __attribute__((no_instrument_function)) + +/* Intel compiler defines __GNUC__. So we will overwrite implementations + * coming from above header files here + */ +#ifdef __INTEL_COMPILER +# include +#endif + +/* + * Generic compiler-dependent macros required for kernel + * build go below this comment. Actual compiler/compiler version + * specific implementations come from the above header files + */ + +struct ftrace_branch_data { + const char *func; + const char *file; + unsigned line; + union { + struct { + unsigned long correct; + unsigned long incorrect; + }; + struct { + unsigned long miss; + unsigned long hit; + }; + unsigned long miss_hit[2]; + }; +}; + +/* + * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code + * to disable branch tracing on a per file basis. + */ +#if defined(CONFIG_TRACE_BRANCH_PROFILING) \ + && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__) +void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); + +#define likely_notrace(x) __builtin_expect(!!(x), 1) +#define unlikely_notrace(x) __builtin_expect(!!(x), 0) + +#define __branch_check__(x, expect) ({ \ + int ______r; \ + static struct ftrace_branch_data \ + __attribute__((__aligned__(4))) \ + __attribute__((section("_ftrace_annotated_branch"))) \ + ______f = { \ + .func = __func__, \ + .file = __FILE__, \ + .line = __LINE__, \ + }; \ + ______r = likely_notrace(x); \ + ftrace_likely_update(&______f, ______r, expect); \ + ______r; \ + }) + +/* + * Using __builtin_constant_p(x) to ignore cases where the return + * value is always the same. This idea is taken from a similar patch + * written by Daniel Walker. + */ +# ifndef likely +# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1)) +# endif +# ifndef unlikely +# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) +# endif + +#ifdef CONFIG_PROFILE_ALL_BRANCHES +/* + * "Define 'is'", Bill Clinton + * "Define 'if'", Steven Rostedt + */ +#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) ) +#define __trace_if(cond) \ + if (__builtin_constant_p((cond)) ? !!(cond) : \ + ({ \ + int ______r; \ + static struct ftrace_branch_data \ + __attribute__((__aligned__(4))) \ + __attribute__((section("_ftrace_branch"))) \ + ______f = { \ + .func = __func__, \ + .file = __FILE__, \ + .line = __LINE__, \ + }; \ + ______r = !!(cond); \ + ______f.miss_hit[______r]++; \ + ______r; \ + })) +#endif /* CONFIG_PROFILE_ALL_BRANCHES */ + +#else +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +/* Optimization barrier */ +#ifndef barrier +# define barrier() __memory_barrier() +#endif + +/* Unreachable code */ +#ifndef unreachable +# define unreachable() do { } while (1) +#endif + +#ifndef RELOC_HIDE +# define RELOC_HIDE(ptr, off) \ + ({ unsigned long __ptr; \ + __ptr = (unsigned long) (ptr); \ + (typeof(ptr)) (__ptr + (off)); }) +#endif + +#endif /* __KERNEL__ */ + +#endif /* __ASSEMBLY__ */ + +#ifdef __KERNEL__ +/* + * Allow us to mark functions as 'deprecated' and have gcc emit a nice + * warning for each use, in hopes of speeding the functions removal. + * Usage is: + * int __deprecated foo(void) + */ +#ifndef __deprecated +# define __deprecated /* unimplemented */ +#endif + +#ifdef MODULE +#define __deprecated_for_modules __deprecated +#else +#define __deprecated_for_modules +#endif + +#ifndef __must_check +#define __must_check +#endif + +#ifndef CONFIG_ENABLE_MUST_CHECK +#undef __must_check +#define __must_check +#endif +#ifndef CONFIG_ENABLE_WARN_DEPRECATED +#undef __deprecated +#undef __deprecated_for_modules +#define __deprecated +#define __deprecated_for_modules +#endif + +/* + * Allow us to avoid 'defined but not used' warnings on functions and data, + * as well as force them to be emitted to the assembly file. + * + * As of gcc 3.4, static functions that are not marked with attribute((used)) + * may be elided from the assembly file. As of gcc 3.4, static data not so + * marked will not be elided, but this may change in a future gcc version. + * + * NOTE: Because distributions shipped with a backported unit-at-a-time + * compiler in gcc 3.3, we must define __used to be __attribute__((used)) + * for gcc >=3.3 instead of 3.4. + * + * In prior versions of gcc, such functions and data would be emitted, but + * would be warned about except with attribute((unused)). + * + * Mark functions that are referenced only in inline assembly as __used so + * the code is emitted even though it appears to be unreferenced. + */ +#ifndef __used +# define __used /* unimplemented */ +#endif + +#ifndef __maybe_unused +# define __maybe_unused /* unimplemented */ +#endif + +#ifndef __always_unused +# define __always_unused /* unimplemented */ +#endif + +#ifndef noinline +#define noinline +#endif + +/* + * Rather then using noinline to prevent stack consumption, use + * noinline_for_stack instead. For documentaiton reasons. + */ +#define noinline_for_stack noinline + +#ifndef __always_inline +#define __always_inline inline +#endif + +#endif /* __KERNEL__ */ + +/* + * From the GCC manual: + * + * Many functions do not examine any values except their arguments, + * and have no effects except the return value. Basically this is + * just slightly more strict class than the `pure' attribute above, + * since function is not allowed to read global memory. + * + * Note that a function that has pointer arguments and examines the + * data pointed to must _not_ be declared `const'. Likewise, a + * function that calls a non-`const' function usually must not be + * `const'. It does not make sense for a `const' function to return + * `void'. + */ +#ifndef __attribute_const__ +# define __attribute_const__ /* unimplemented */ +#endif + +/* + * Tell gcc if a function is cold. The compiler will assume any path + * directly leading to the call is unlikely. + */ + +#ifndef __cold +#define __cold +#endif + +/* Simple shorthand for a section definition */ +#ifndef __section +# define __section(S) __attribute__ ((__section__(#S))) +#endif + +/* Are two types/vars the same type (ignoring qualifiers)? */ +#ifndef __same_type +# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) +#endif + +/* Compile time object size, -1 for unknown */ +#ifndef __compiletime_object_size +# define __compiletime_object_size(obj) -1 +#endif +#ifndef __compiletime_warning +# define __compiletime_warning(message) +#endif +#ifndef __compiletime_error +# define __compiletime_error(message) +#endif + +/* + * Prevent the compiler from merging or refetching accesses. The compiler + * is also forbidden from reordering successive instances of ACCESS_ONCE(), + * but only when the compiler is aware of some particular ordering. One way + * to make the compiler aware of ordering is to put the two invocations of + * ACCESS_ONCE() in different C statements. + * + * This macro does absolutely -nothing- to prevent the CPU from reordering, + * merging, or refetching absolutely anything at any time. Its main intended + * use is to mediate communication between process-level code and irq/NMI + * handlers, all running on the same CPU. + */ +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) + +#endif /* __LINUX_COMPILER_H */ diff --git a/exynos/kernel_header/media.h b/exynos/kernel_header/media.h new file mode 100755 index 0000000..0ef8833 --- /dev/null +++ b/exynos/kernel_header/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/exynos/kernel_header/v4l2-mediabus.h b/exynos/kernel_header/v4l2-mediabus.h new file mode 100755 index 0000000..fa0c1c4 --- /dev/null +++ b/exynos/kernel_header/v4l2-mediabus.h @@ -0,0 +1,111 @@ +/* + * 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, + + /* YUV (including grey) - next is 0x2013 */ + 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_UYVY8_1X16 = 0x200f, + V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, + V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, + V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, + V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, + V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, + + /* Bayer - next is 0x3013 */ + V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, + V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, + 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 */ + V4L2_MBUS_FMT_JPEG_1X8 = 0x4000, +}; + +/** + * 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/exynos/kernel_header/v4l2-subdev.h b/exynos/kernel_header/v4l2-subdev.h new file mode 100755 index 0000000..77f05c0 --- /dev/null +++ b/exynos/kernel_header/v4l2-subdev.h @@ -0,0 +1,145 @@ +/* + * 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 +#ifdef KERNEL_HEADER_MODIFICATION +#include "v4l2-mediabus.h" +#else +#include +#endif + +/** + * 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/exynos/libcsc/csc.c b/exynos/libcsc/csc.c old mode 100644 new mode 100755 index 970f1ad..7fe7afe --- a/exynos/libcsc/csc.c +++ b/exynos/libcsc/csc.c @@ -132,7 +132,11 @@ static CSC_ERRORCODE conv_sw_src_argb888( ret = CSC_ErrorNone; break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: +#ifdef USE_NEON csc_ARGB8888_to_YUV420SP_NEON( +#else + csc_ARGB8888_to_YUV420SP( +#endif (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], @@ -157,12 +161,20 @@ static CSC_ERRORCODE conv_sw_src_nv12t( switch (handle->dst_format.color_format) { case HAL_PIXEL_FORMAT_YCbCr_420_P: ALOGE("dst_format HAL_PIXEL_FORMAT_YCbCr_420_P"); +#ifdef USE_NEON csc_tiled_to_linear_y_neon( +#else + csc_tiled_to_linear_y( +#endif (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); +#ifdef USE_NEON csc_tiled_to_linear_uv_deinterleave_neon( +#else + csc_tiled_to_linear_uv_deinterleave( +#endif (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], @@ -172,12 +184,20 @@ static CSC_ERRORCODE conv_sw_src_nv12t( break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: ALOGE("dst_format HAL_PIXEL_FORMAT_YCbCr_420_SP"); +#ifdef USE_NEON csc_tiled_to_linear_y_neon( +#else + csc_tiled_to_linear_y( +#endif (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); +#ifdef USE_NEON csc_tiled_to_linear_uv_neon( +#else + csc_tiled_to_linear_uv( +#endif (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], handle->src_format.width, @@ -238,7 +258,11 @@ static CSC_ERRORCODE conv_sw_src_yuv420p( 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); +#ifdef USE_NEON csc_interleave_memcpy_neon( +#else + csc_interleave_memcpy( +#endif (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], diff --git a/exynos/libv4l2/exynos_mc.c b/exynos/libv4l2/exynos_mc.c old mode 100644 new mode 100755 index bfaa9b3..6ada9d1 --- a/exynos/libv4l2/exynos_mc.c +++ b/exynos/libv4l2/exynos_mc.c @@ -41,8 +41,13 @@ #include #else -//#include +#ifdef KERNEL_HEADER_MODIFICATION +#include "../kernel_header/compiler.h" +#include "../kernel_header/media.h" +#else +#include #include +#endif #endif #include diff --git a/exynos/libv4l2/exynos_v4l2.c b/exynos/libv4l2/exynos_v4l2.c old mode 100644 new mode 100755 index dce7223..08b4f82 --- a/exynos/libv4l2/exynos_v4l2.c +++ b/exynos/libv4l2/exynos_v4l2.c @@ -453,7 +453,7 @@ int exynos_v4l2_expbuf(int fd, int *buf_fd, __u32 mem_offset) } expbuf.flags = O_CLOEXEC; - expbuf.mem_offset = mem_offset; + //expbuf.mem_offset = mem_offset; ALOGE("%s: fd:%d mem_offset:%d", __func__, fd, mem_offset); ret = ioctl(fd, VIDIOC_EXPBUF, &expbuf); diff --git a/exynos4/libcodec/video/v4l2/Makefile.am b/exynos4/libcodec/video/v4l2/Makefile.am old mode 100644 new mode 100755 index 8a25923..d702c18 --- a/exynos4/libcodec/video/v4l2/Makefile.am +++ b/exynos4/libcodec/video/v4l2/Makefile.am @@ -3,12 +3,10 @@ lib_LTLIBRARIES = libExynosVideoApi.la libExynosVideoApi_la_SOURCES = dec/ExynosVideoDecoder.c \ enc/ExynosVideoEncoder.c -libExynosVideoApi_la_LIBADD = \ - $(MMTA_LIBS) +libExynosVideoApi_la_LIBADD = libExynosVideoApi_la_CFLAGS = -I$(CURDIR)/include \ -I$(top_srcdir)/exynos/include \ - -I$(top_srcdir)/openmax/osal \ - $(MMTA_CFLAGS) + -I$(top_srcdir)/openmax/osal if BOARD_USE_DMA_BUF libExynosVideoApi_la_CFLAGS += -DUSE_DMA_BUF diff --git a/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c index 1ccd8f6..964686c 100755 --- a/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c +++ b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c @@ -42,7 +42,7 @@ #include "ExynosVideoApi.h" #include "ExynosVideoDec.h" -#include +//#include /* #define LOG_NDEBUG 0 */ #define LOG_TAG "ExynosVideoDecoder" @@ -127,7 +127,7 @@ static void *MFC_Decoder_Init(int nMemoryType) pthread_mutex_t *pMutex = NULL; int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING); - MMTA_ACUM_ITEM_BEGIN("Video First Frame Coming", 0); + pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx)); if (pCtx == NULL) { @@ -137,20 +137,16 @@ static void *MFC_Decoder_Init(int nMemoryType) memset(pCtx, 0, sizeof(*pCtx)); - __ta__("exynos_v4l2_open_devname : VIDEO_DECODER_NAME", pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0); - ); if (pCtx->hDec < 0) { ALOGE("%s: Failed to open decoder device", __func__); goto EXIT_OPEN_FAIL; } - __ta__("exynos_v4l2_querycap", if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) { ALOGE("%s: Failed to querycap", __func__); goto EXIT_QUERYCAP_FAIL; } - ); pCtx->bStreamonInbuf = VIDEO_FALSE; pCtx->bStreamonOutbuf = VIDEO_FALSE; @@ -292,19 +288,18 @@ static ExynosVideoErrorType MFC_Decoder_Set_FrameTag( { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoErrorType ret = VIDEO_ERROR_NONE; - +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG if (pCtx == NULL) { ALOGE("%s: Video context info must be supplied", __func__); ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); +#endif EXIT: return ret; @@ -322,11 +317,9 @@ static int MFC_Decoder_Get_FrameTag(void *pHandle) ALOGE("%s: Video context info must be supplied", __func__); goto EXIT; } - - __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag); - ); - +#endif EXIT: return frameTag; } @@ -344,9 +337,7 @@ static int MFC_Decoder_Get_ActualBufferCount(void *pHandle) goto EXIT; } - __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MIN_BUFFERS_FOR_CAPTURE", exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount); - ); EXIT: return bufferCount; @@ -368,12 +359,10 @@ static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay( goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY", if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); EXIT: return ret; @@ -385,20 +374,18 @@ static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle) { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoErrorType ret = VIDEO_ERROR_NONE; - +#ifdef V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY if (pCtx == NULL) { ALOGE("%s: Video context info must be supplied", __func__); ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY", if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -415,14 +402,12 @@ static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -441,12 +426,10 @@ static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle) goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER" , if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) EXIT: return ret; @@ -466,12 +449,10 @@ static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle) goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE" , if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) EXIT: return ret; @@ -491,12 +472,10 @@ static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle) goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING" , if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) EXIT: return ret; @@ -511,7 +490,7 @@ static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo( { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoErrorType ret = VIDEO_ERROR_NONE; - +#ifdef V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM]; struct v4l2_ext_controls ext_ctrls; @@ -536,12 +515,10 @@ static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo( ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO; ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS; - __ta__("exynos_v4l2_g_ext_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FP_XX(AVAIL,ARRGMENT_ID,INFO,GRID_POS)" , if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) seiAvailable = ext_ctrl[0].value; seiArgmtId = ext_ctrl[1].value; @@ -564,7 +541,7 @@ static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo( pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4); pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8); pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12); - +#endif EXIT: return ret; } @@ -579,20 +556,18 @@ static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(void *pHandle) { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoErrorType ret = VIDEO_ERROR_NONE; - +#ifdef V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START if (pCtx == NULL) { ALOGE("%s: Video context info must be supplied", __func__); ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START" , if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) - +#endif EXIT: return ret; } @@ -612,14 +587,12 @@ static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" , +#ifdef V4L2_CID_CACHEABLE if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) - +#endif EXIT: return ret; } @@ -637,14 +610,12 @@ static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" , +#ifdef V4L2_CID_CACHEABLE if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) - +#endif EXIT: return ret; } @@ -779,12 +750,10 @@ static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf( fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat); fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage; -__ta__("exynos_v4l2_s_fmt" , if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry)); @@ -821,12 +790,10 @@ static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf( fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat); - __ta__("exynos_v4l2_s_fmt" , if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry)); @@ -864,23 +831,19 @@ static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf( fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - __ta__("exynos_v4l2_g_fmt" , if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) { ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - __ta__("exynos_v4l2_g_crop" , if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) { ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) bufferConf->nFrameWidth = fmt.fmt.pix_mp.width; bufferConf->nFrameHeight = fmt.fmt.pix_mp.height; @@ -935,12 +898,10 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf( else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); if (req.count != nBufferCount) { ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); @@ -969,20 +930,16 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf( ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__); for (i = 0; i < pCtx->nInbufs; i++) { buf.index = i; - __ta__("INBUF : exynos_v4l2_querybuf", if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pVideoPlane = &pCtx->pInbuf[i].planes[0]; - __ta__("mmap : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", pVideoPlane->addr = mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE, MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset); - ); if (pVideoPlane->addr == MAP_FAILED) { ret = VIDEO_ERROR_MAPFAIL; @@ -1061,12 +1018,10 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) if (req.count != nBufferCount) { ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); @@ -1095,20 +1050,16 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__); for (i = 0; i < pCtx->nOutbufs; i++) { buf.index = i; - __ta__("exynos_v4l2_querybuf" , if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { pVideoPlane = &pCtx->pOutbuf[i].planes[j]; - __ta__("mmap : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", pVideoPlane->addr = mmap(NULL, buf.m.planes[j].length, PROT_READ | PROT_WRITE, MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset); - ); if (pVideoPlane->addr == MAP_FAILED) { ret = VIDEO_ERROR_MAPFAIL; @@ -1119,12 +1070,12 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( pVideoPlane->dataSize = 0; #ifdef SLP_PLATFORM /* dmabuf */ - __ta__("exynos_v4l2_expbuf" , -// if (pCtx->bufShareMethod == BUF_SHARE_FD) { +#if 0 + if (pCtx->bufShareMethod == BUF_SHARE_FD) { exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset); ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd); -// } - ) + } +#endif #endif } @@ -1173,13 +1124,11 @@ static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle) } if (pCtx->bStreamonInbuf == VIDEO_FALSE) { - __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { ALOGE("%s: Failed to streamon for input buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->bStreamonInbuf = VIDEO_TRUE; } @@ -1202,13 +1151,11 @@ static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle) } if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { - __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { ALOGE("%s: Failed to streamon for output buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->bStreamonOutbuf = VIDEO_TRUE; } @@ -1232,13 +1179,11 @@ static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle) } if (pCtx->bStreamonInbuf == VIDEO_TRUE) { - __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { ALOGE("%s: Failed to streamoff for input buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->bStreamonInbuf = VIDEO_FALSE; } @@ -1266,13 +1211,11 @@ static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle) } if (pCtx->bStreamonOutbuf == VIDEO_TRUE) { - __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { ALOGE("%s: Failed to streamoff for output buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->bStreamonOutbuf = VIDEO_FALSE; } @@ -1582,14 +1525,12 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( buf.m.planes[i].bytesused = dataSize[i]; } - __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->pInbuf[buf.index].pPrivate = pPrivate; @@ -1670,14 +1611,12 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf( buf.memory = V4L2_MEMORY_MMAP; } - __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { ALOGE("%s: Failed to enqueue output buffer", __func__); pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->pOutbuf[buf.index].pPrivate = pPrivate; @@ -1714,12 +1653,10 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle) else buf.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { pInbuf = NULL; goto EXIT; } - ) pInbuf = &pCtx->pInbuf[buf.index]; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; @@ -1763,9 +1700,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) buf.memory = V4L2_MEMORY_MMAP; /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */ - __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf); - ); if (ret != 0) { if (errno == EIO) pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO; @@ -1781,9 +1716,8 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) pOutbuf = &pCtx->pOutbuf[buf.index]; - __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); - ); ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value); switch (value) { @@ -1797,9 +1731,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; break; case 3: - __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE", exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state); - ); if (state == 1) /* Resolution change is detected */ pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; else /* Decoding is finished */ @@ -1809,7 +1741,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; break; } - +#endif switch (buf.flags & (0x7 << 3)) { ALOGV("%s: frameType: %d", __func__, buf.flags & (0x7 << 3)); case V4L2_BUF_FLAG_KEYFRAME: @@ -1919,12 +1851,10 @@ static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle) else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" , if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->nInbufs = (int)req.count; @@ -1983,13 +1913,11 @@ static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle) else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" , if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { ALOGE("reqbuf fail"); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ) pCtx->nOutbufs = req.count; diff --git a/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c b/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c index dba248f..8a12320 100755 --- a/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c +++ b/exynos4/libcodec/video/v4l2/enc/ExynosVideoEncoder.c @@ -43,7 +43,7 @@ #include "ExynosVideoApi.h" #include "ExynosVideoEnc.h" -#include +//#include /* #define LOG_NDEBUG 0 */ #define LOG_TAG "ExynosVideoEncoder" @@ -59,10 +59,11 @@ #define H263_CTRL_NUM 18 /* FIXME: build error related with kernel-header pkg */ +#if 0 #ifndef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR #define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46) #endif - +#endif /* * [Common] __CodingType_To_V4L2PixelFormat */ @@ -146,20 +147,16 @@ static void *MFC_Encoder_Init(int nMemoryType) memset(pCtx, 0, sizeof(*pCtx)); - __ta__("exynos_v4l2_open_devname : VIDEO_ENCODER_NAME", pCtx->hEnc = exynos_v4l2_open_devname(VIDEO_ENCODER_NAME, O_RDWR, 0); - ); if (pCtx->hEnc < 0) { ALOGE("%s: Failed to open encoder device", __func__); goto EXIT_OPEN_FAIL; } - __ta__("exynos_v4l2_querycap", if (!exynos_v4l2_querycap(pCtx->hEnc, needCaps)) { ALOGE("%s: Failed to querycap", __func__); goto EXIT_QUERYCAP_FAIL; } - ); pCtx->bStreamonInbuf = VIDEO_FALSE; pCtx->bStreamonOutbuf = VIDEO_FALSE; @@ -405,13 +402,16 @@ static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset; ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; ext_ctrl[k++].value = pH264Param->SymbolMode; +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE; ext_ctrl[k++].value = pH264Param->PictureInterlace; +#endif ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM; ext_ctrl[k++].value = pH264Param->Transform8x8Mode; - +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE; ext_ctrl[k++].value = pH264Param->FrameRate; +#endif ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; ext_ctrl[k++].value = pH264Param->FrameQp_B; @@ -477,9 +477,10 @@ static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( ext_ctrl[k++].value = 0; ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0; ext_ctrl[k++].value = 0; +#ifdef V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE; ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE; - +#endif /* FMO is not supported yet */ ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO; ext_ctrl[k++].value = 0; @@ -565,12 +566,14 @@ static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( */ ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES; ext_ctrl[k++].value = pMpeg4Param->NumberBFrames; - +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES; ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes; +#endif +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA; ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament; - +#endif ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP; ext_ctrl[k++].value = pMpeg4Param->FrameQp_B; ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE; @@ -618,9 +621,10 @@ static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( ext_ctrl[k++].value = pCommonParam->CBRPeriodRf; /* H263 specific parameters */ +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE; ext_ctrl[k++].value = pH263Param->FrameRate; - +#endif ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE; ext_ctrl[k++].value = 0; ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; @@ -657,13 +661,11 @@ static ExynosVideoErrorType MFC_Encoder_Set_EncParam ( ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; ext_ctrls.controls = ext_ctrl; - __ta__("exynos_v4l2_s_ext_ctrl", if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) { ALOGE("%s: Failed to s_ext_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); EXIT: return ret; @@ -684,15 +686,13 @@ static ExynosVideoErrorType MFC_Encoder_Set_FrameTag( ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -711,15 +711,13 @@ static int MFC_Encoder_Get_FrameTag(void *pHandle) ALOGE("%s: Video context info must be supplied", __func__); goto EXIT; } - - __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) { ALOGE("%s: Failed to g_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return frameTag; } @@ -740,13 +738,13 @@ static ExynosVideoErrorType MFC_Encoder_Set_FrameType( goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE", + if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); + EXIT: return ret; @@ -767,14 +765,13 @@ static ExynosVideoErrorType MFC_Encoder_Set_FrameRate( ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); +#endif EXIT: return ret; @@ -795,15 +792,13 @@ static ExynosVideoErrorType MFC_Encoder_Set_BitRate( ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH", +#ifdef V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -824,13 +819,11 @@ static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip( goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE", if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); EXIT: return ret; @@ -852,13 +845,11 @@ static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod( goto EXIT; } - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_I_PERIOD", if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); EXIT: return ret; @@ -877,15 +868,13 @@ static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR", +#ifdef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) { ALOGE("%s: Failed to s_ctrl", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -903,15 +892,13 @@ static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE", +#ifdef V4L2_CID_CACHEABLE if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) { ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -929,15 +916,13 @@ static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle) ret = VIDEO_ERROR_BADPARAM; goto EXIT; } - - __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE", +#ifdef V4L2_CID_CACHEABLE if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) { ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); - +#endif EXIT: return ret; } @@ -1074,13 +1059,12 @@ static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf( fmt.fmt.pix_mp.height = bufferConf->nFrameHeight; fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES; - __ta__("exynos_v4l2_s_fmt : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) { ALOGE("%s: Failed to s_fmt", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry)); @@ -1115,13 +1099,11 @@ static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf( memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - __ta__("exynos_v4l2_g_fmt : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) { ALOGE("%s: Failed to g_fmt", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); bufferConf->nFrameHeight = fmt.fmt.pix_mp.width; bufferConf->nFrameHeight = fmt.fmt.pix_mp.height; @@ -1161,13 +1143,11 @@ static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf( fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat); fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage; - __ta__("exynos_v4l2_s_fmt : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) { ALOGE("%s: Failed to s_fmt", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry)); @@ -1202,13 +1182,12 @@ static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf( memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - __ta__("exynos_v4l2_g_fmt : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) { ALOGE("%s: Failed to g_fmt", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); + bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; @@ -1254,13 +1233,11 @@ static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf( else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) { ALOGE("Failed to require buffer"); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->nInbufs = (int)req.count; @@ -1282,21 +1259,17 @@ static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf( for (i = 0; i < pCtx->nInbufs; i++) { buf.index = i; - __ta__("exynos_v4l2_querybuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to querybuf", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) { pVideoPlane = &pCtx->pInbuf[i].planes[j]; - __ta__("mmap : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", pVideoPlane->addr = mmap(NULL, buf.m.planes[j].length, PROT_READ | PROT_WRITE, MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset); - ); if (pVideoPlane->addr == MAP_FAILED) { ALOGE("%s: Failed to map", __func__); @@ -1383,13 +1356,11 @@ static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf( else req.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) { ALOGE("%s: Failed to reqbuf", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->nOutbufs = req.count; @@ -1411,21 +1382,17 @@ static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf( for (i = 0; i < pCtx->nOutbufs; i++) { buf.index = i; - __ta__("exynos_v4l2_querybuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to querybuf", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) { pVideoPlane = &pCtx->pOutbuf[i].planes[j]; - __ta__("mmap : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", pVideoPlane->addr = mmap(NULL, buf.m.planes[j].length, PROT_READ | PROT_WRITE, MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset); - ); if (pVideoPlane->addr == MAP_FAILED) { ALOGE("%s: Failed to map", __func__); @@ -1488,13 +1455,11 @@ static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle) } if (pCtx->bStreamonInbuf == VIDEO_FALSE) { - __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { ALOGE("%s: Failed to streamon for input buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->bStreamonInbuf = VIDEO_TRUE; } @@ -1517,13 +1482,11 @@ static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle) } if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { - __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { ALOGE("%s: Failed to streamon for output buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->bStreamonOutbuf = VIDEO_TRUE; } @@ -1547,13 +1510,11 @@ static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle) } if (pCtx->bStreamonInbuf == VIDEO_TRUE) { - __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { ALOGE("%s: Failed to streamoff for input buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->bStreamonInbuf = VIDEO_FALSE; } @@ -1581,13 +1542,11 @@ static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle) } if (pCtx->bStreamonOutbuf == VIDEO_TRUE) { - __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { ALOGE("%s: Failed to streamoff for output buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->bStreamonOutbuf = VIDEO_FALSE; } @@ -1708,7 +1667,7 @@ static ExynosVideoErrorType MFC_Encoder_Register_Inbuf( pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr; pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd; - ALOGE("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr); + ALOGV("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr); } pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE; break; @@ -1894,6 +1853,7 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf( goto EXIT; } + memset(&planes,0,sizeof(planes)); memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; @@ -1934,14 +1894,13 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf( buf.m.planes[i].bytesused = dataSize[i]; } - __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", + ALOGE("call exynos_v4l2_qbuf(): %d", buf.m.planes[0].m.fd); if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->pInbuf[buf.index].pPrivate = pPrivate; @@ -2016,14 +1975,12 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf( buf.memory = V4L2_MEMORY_MMAP; } - __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to enqueue output buffer", __func__); pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - ); pCtx->pOutbuf[buf.index].pPrivate = pPrivate; @@ -2089,12 +2046,10 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle) else buf.memory = V4L2_MEMORY_MMAP; - __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE", if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) { pInbuf = NULL; goto EXIT; } - ); pInbuf = &pCtx->pInbuf[buf.index]; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; @@ -2137,11 +2092,9 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle) buf.memory = V4L2_MEMORY_MMAP; /* no error case for output buffer dequeue in encoder */ - __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE", if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) { goto EXIT; } - ); pOutbuf = &pCtx->pOutbuf[buf.index]; pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused; diff --git a/exynos4/libswconverter/Makefile.am b/exynos4/libswconverter/Makefile.am old mode 100644 new mode 100755 index 18adaa3..393621c --- a/exynos4/libswconverter/Makefile.am +++ b/exynos4/libswconverter/Makefile.am @@ -1,17 +1,17 @@ lib_LTLIBRARIES = libswconverter.la -libswconverter_la_SOURCES = swconvertor.c \ - csc_ARGB8888_to_YUV420SP_NEON.s \ - csc_interleave_memcpy_neon.s \ - 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 - +libswconverter_la_SOURCES = swconvertor.c libswconverter_la_LIBADD = libswconverter_la_CFLAGS = -I$(top_srcdir)/exynos4/include \ -I$(top_srcdir)/exynos/include -libswconverter_la_LDFLAGS = "-Wl,-z,noexecstack" +if BOARD_USE_NEON +libswconverter_la_SOURCES += csc_ARGB8888_to_YUV420SP_NEON.s \ + csc_interleave_memcpy_neon.s \ + 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 +endif diff --git a/exynos4/libswconverter/swconvertor.c b/exynos4/libswconverter/swconvertor.c old mode 100644 new mode 100755 index 043add2..756fb13 --- a/exynos4/libswconverter/swconvertor.c +++ b/exynos4/libswconverter/swconvertor.c @@ -1386,6 +1386,7 @@ void csc_linear_to_tiled_uv( 0, 0, 0, 0); } +#ifdef USE_NEON /* * Converts tiled data to linear for mfc 6.x * 1. Y of NV12T to Y of YUV420P @@ -1527,6 +1528,7 @@ void csc_linear_to_tiled_uv_neon( csc_linear_to_tiled_interleave_crop_neon(uv_dst, u_src, v_src, width, height, 0, 0, 0, 0); } +#endif /* * Converts RGB565 to YUV420P diff --git a/openmax/component/audio/dec/mp3/Makefile.am b/openmax/component/audio/dec/mp3/Makefile.am old mode 100644 new mode 100755 index eaff551..23453a4 --- a/openmax/component/audio/dec/mp3/Makefile.am +++ b/openmax/component/audio/dec/mp3/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.MP3.Decoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_MP3_Decoder_la_SOURCES = Exynos_OMX_Mp3dec.c \ Exynos_OMX_Mp3dec.h \ diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.c b/openmax/component/video/dec/Exynos_OMX_Vdec.c index 1c1dddf..9b3bf68 100755 --- a/openmax/component/video/dec/Exynos_OMX_Vdec.c +++ b/openmax/component/video/dec/Exynos_OMX_Vdec.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OSAL_Event.h" #include "Exynos_OMX_Vdec.h" @@ -112,7 +113,7 @@ inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) #ifdef SLP_PLATFORM /* nv12t fd */ case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: if (width && height) - exynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + exynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer); break; #endif case OMX_SEC_COLOR_FormatNV12Tiled: @@ -251,7 +252,7 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA OMX_U32 copySize = 0; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; #ifdef SLP_PLATFORM - SCMN_IMGB *pSlpOutBuf = NULL; + MMVideoBuffer *pSlpOutBuf = NULL; #endif FunctionIn(); @@ -276,35 +277,36 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA colorFormat = pBufferInfo->ColorFormat; #ifdef SLP_PLATFORM - pSlpOutBuf = (SCMN_IMGB *)pOutputBuf; - pSlpOutBuf->w[0] = width; - pSlpOutBuf->w[1] = width; - pSlpOutBuf->h[0] = height; - pSlpOutBuf->h[1] = height/2; - pSlpOutBuf->s[0] = width; /* need to check. stride */ - pSlpOutBuf->s[1] = width; - pSlpOutBuf->e[0] = height; /* need to check. elevation */ - pSlpOutBuf->e[1] = height/2; + pSlpOutBuf = (MMVideoBuffer *)pOutputBuf; + pSlpOutBuf->width[0] = width; + pSlpOutBuf->width[1] = width; + pSlpOutBuf->height[0] = height; + pSlpOutBuf->height[1] = height/2; + pSlpOutBuf->stride_width[0] = width; /* need to check. stride */ + pSlpOutBuf->stride_width[1] = width; + pSlpOutBuf->stride_height[0] = height; /* need to check. elevation */ + pSlpOutBuf->stride_height[1] = height/2; if (pVideoDec->bDRMPlayerMode == OMX_TRUE) { - pSlpOutBuf->a[0] = 0; - pSlpOutBuf->a[1] = 0; + pSlpOutBuf->data[0] = 0; + pSlpOutBuf->data[1] = 0; } else { - pSlpOutBuf->a[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0]; - pSlpOutBuf->a[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1]; + pSlpOutBuf->data[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0]; + pSlpOutBuf->data[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1]; } - pSlpOutBuf->a[2] = 0; /* omx do not use this plane */ + pSlpOutBuf->data[2] = 0; /* omx do not use this plane */ - pSlpOutBuf->fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; - pSlpOutBuf->fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; - pSlpOutBuf->fd[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2]; + pSlpOutBuf->handle.dmabuf_fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0]; + pSlpOutBuf->handle.dmabuf_fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; + pSlpOutBuf->handle.dmabuf_fd[2] = 0; /* omx do not use this plane */ - pSlpOutBuf->buf_share_method = MEMORY_DMABUF; - dstOutputData->dataLen = sizeof(SCMN_IMGB); + //pSlpOutBuf->buf_share_method = MEMORY_DMABUF; + dstOutputData->dataLen = sizeof(MMVideoBuffer); Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__); - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->fd[2]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1], + pSlpOutBuf->handle.dmabuf_fd[2]); ret = OMX_TRUE; goto EXIT; diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.c b/openmax/component/video/dec/Exynos_OMX_VdecControl.c old mode 100644 new mode 100755 index c1f81a2..f2ed5aa --- a/openmax/component/video/dec/Exynos_OMX_VdecControl.c +++ b/openmax/component/video/dec/Exynos_OMX_VdecControl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OSAL_Event.h" #include "Exynos_OMX_Vdec.h" @@ -122,23 +123,43 @@ OMX_ERRORTYPE Exynos_OMX_UseBuffer( temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; #ifdef SLP_PLATFORM if (nPortIndex == OUTPUT_PORT_INDEX) { - SCMN_IMGB * pSlpOutBuf = (SCMN_IMGB *)pBuffer; + MMVideoBuffer * pSlpOutBuf = (MMVideoBuffer *)pBuffer; - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd[0] =%d, fd[1] =%d, vaddr[0] =%p, vaddr[1] = %p", - pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->a[0], pSlpOutBuf->a[1]); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "fd[0] =%d, fd[1] =%d, vaddr[0] =%p, vaddr[1] = %p, y_size=%d, uv_size=%d\n", + pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1], pSlpOutBuf->data[0], pSlpOutBuf->data[1], + pSlpOutBuf->size[0],pSlpOutBuf->size[1]); - pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->fd[0]; - pExynosPort->extendBufferHeader[i].buf_fd[1] = pSlpOutBuf->fd[1]; + pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->handle.dmabuf_fd[0]; + pExynosPort->extendBufferHeader[i].buf_fd[1] = pSlpOutBuf->handle.dmabuf_fd[1]; pExynosPort->extendBufferHeader[i].buf_fd[2] = 0; - pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->a[0]; - pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->a[1]; + pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->data[0]; + pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->data[1]; pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL; Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PlatformBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ", i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], pExynosPort->extendBufferHeader[i].pYUVBuf[1]); } else if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { pExynosPort->extendBufferHeader[i].buf_fd[0] = pBuffer; + } else if(nPortIndex == INPUT_PORT_INDEX){ + MMVideoBuffer * pSlpOutBuf = (MMVideoBuffer *)pBuffer; + temp_bufferHeader->pBuffer = pSlpOutBuf->data[0]; +#if 0 + pExynosPort->extendBufferHeader[i].buf_fd[0] = pBuffer; + SCMN_IMGB * pSlpOutBuf = (SCMN_IMGB *)pBuffer; + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "fd[0] =%d, vaddr[0] =%p, , length=%d", + pSlpOutBuf->fd[0], pSlpOutBuf->a[0], nSizeBytes); + + pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->fd[0]; + pExynosPort->extendBufferHeader[i].buf_fd[1] = 0; + pExynosPort->extendBufferHeader[i].buf_fd[2] = 0; + + pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->a[0]; + pExynosPort->extendBufferHeader[i].pYUVBuf[1] = NULL; + pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL; + + temp_bufferHeader->pBuffer = pSlpOutBuf->a[0]; +#endif } #endif *ppBufferHdr = temp_bufferHeader; @@ -794,7 +815,7 @@ OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) if (bufferHeader != NULL) { #ifdef SLP_PLATFORM - bufferHeader->nFilledLen = sizeof(SCMN_IMGB); + bufferHeader->nFilledLen = sizeof(MMVideoBuffer); #else bufferHeader->nFilledLen = dataBuffer->remainDataLen; #endif @@ -1547,7 +1568,7 @@ OMX_ERRORTYPE Exynos_Shared_DataToPlatformBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_ pUseBuffer->bufferHeader = pData->bufferHeader; pUseBuffer->allocSize = pData->allocSize; #ifdef SLP_PLATFORM - pUseBuffer->dataLen = sizeof(SCMN_IMGB); + pUseBuffer->dataLen = sizeof(MMVideoBuffer); #else pUseBuffer->dataLen = pData->dataLen; #endif diff --git a/openmax/component/video/dec/Makefile.am b/openmax/component/video/dec/Makefile.am old mode 100644 new mode 100755 index 5b04d89..334d2fa --- a/openmax/component/video/dec/Makefile.am +++ b/openmax/component/video/dec/Makefile.am @@ -7,13 +7,13 @@ libExynosOMX_Vdec_la_SOURCES = Exynos_OMX_Vdec.c \ Exynos_OMX_VdecControl.c \ Exynos_OMX_VdecControl.h -libExynosOMX_Vdec_la_LIBADD = $(X11_LIBS) $(DRI2_LIBS) $(DRM_SLP_LIBS) $(XFIXES_LIBS)\ - $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ +libExynosOMX_Vdec_la_LIBADD = \ + $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \ $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \ $(top_builddir)/exynos/libcsc/libcsc.la -libExynosOMX_Vdec_la_CFLAGS = $(X11_CFLAGS) $(DRI2_CFLAGS) $(DRM_SLP_CFLAGS) $(XFIXES_CFLAGS) \ - -I$(top_srcdir)/openmax/include/khronos \ +libExynosOMX_Vdec_la_CFLAGS = \ + -I$(top_srcdir)/openmax/include/khronos \ -I$(top_srcdir)/openmax/include/exynos \ -I$(top_srcdir)/openmax/osal \ -I$(top_srcdir)/openmax/core \ @@ -23,6 +23,9 @@ libExynosOMX_Vdec_la_CFLAGS = $(X11_CFLAGS) $(DRI2_CFLAGS) $(DRM_SLP_CFLAGS) $(X -I$(top_srcdir)/exynos/include \ -I$(top_srcdir)/exynos/libcsc +libExynosOMX_Vdec_la_CFLAGS += $(MM_COMMON_CFLAGS) +libExynosOMX_Vdec_la_LIBADD += $(MM_COMMON_LIBS) + if BOARD_USE_DMA_BUF libExynosOMX_Vdec_la_CFLAGS += -DUSE_ANB endif diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c index 54bf2f0..5211a6f 100755 --- a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OMX_Basecomponent.h" @@ -41,7 +42,7 @@ #include "Exynos_OSAL_SharedMemory.h" #include "Exynos_OSAL_Event.h" -#include + #ifdef USE_PB #include "Exynos_OSAL_Platform_Specific.h" @@ -1617,7 +1618,7 @@ OMX_ERRORTYPE Exynos_H264Dec_SetParameter( break; #ifdef SLP_PLATFORM /* NV12T fd */ case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: - pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer); break; #endif case OMX_SEC_COLOR_FormatNV12Tiled: @@ -2162,7 +2163,7 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ /*Add First Frame check : */ if((pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG) { - MMTA_ACUM_ITEM_END("Video First Frame Coming", 0); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"Video First Frame Coming"); } /* queue work for input buffer */ diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h old mode 100644 new mode 100755 index 9b039f2..7f36d71 --- a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h @@ -74,6 +74,9 @@ extern "C" { OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE H264CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent); + #ifdef __cplusplus }; #endif diff --git a/openmax/component/video/dec/h264/Makefile.am b/openmax/component/video/dec/h264/Makefile.am old mode 100644 new mode 100755 index 8cdbb5d..f9b4318 --- a/openmax/component/video/dec/h264/Makefile.am +++ b/openmax/component/video/dec/h264/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.AVC.Decoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_AVC_Decoder_la_SOURCES = Exynos_OMX_H264dec.c \ Exynos_OMX_H264dec.h \ @@ -25,6 +25,9 @@ libOMX_Exynos_AVC_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ -I$(top_srcdir)/exynos/include +libOMX_Exynos_AVC_Decoder_la_LIBADD += $(MM_COMMON_LIB) +libOMX_Exynos_AVC_Decoder_la_CFLAGS += $(MM_COMMON_CFLAGS) + if BOARD_USE_ANB libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DUSE_ANB endif diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c old mode 100644 new mode 100755 index 1fce8b5..0bbd7fe --- a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c +++ b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OMX_Basecomponent.h" diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h old mode 100644 new mode 100755 index 914ed64..c6c36f6 --- a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h +++ b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h @@ -36,6 +36,7 @@ typedef struct _EXYNOS_MFC_MPEG2DEC_HANDLE { OMX_HANDLETYPE hMFCHandle; + OMX_BOOL bShareableBuf; OMX_U32 indexTimestamp; OMX_U32 outputIndexTimestamp; OMX_BOOL bConfiguredMFCSrc; @@ -74,6 +75,8 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Mpeg2CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent); #ifdef __cplusplus }; #endif diff --git a/openmax/component/video/dec/mpeg2/Makefile.am b/openmax/component/video/dec/mpeg2/Makefile.am old mode 100644 new mode 100755 index 8a5d601..1316b11 --- a/openmax/component/video/dec/mpeg2/Makefile.am +++ b/openmax/component/video/dec/mpeg2/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.M2V.Decoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_M2V_Decoder_la_SOURCES = Exynos_OMX_Mpeg2dec.c \ Exynos_OMX_Mpeg2dec.h \ @@ -24,6 +24,9 @@ libOMX_Exynos_M2V_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ -I$(top_srcdir)/exynos/include +libOMX_Exynos_M2V_Decoder_la_CFLAGS += $(MM_COMMON_CFLAGS) +libOMX_Exynos_M2V_Decoder_la_LIBADD += $(MM_COMMON_LIBS) + if BOARD_USE_ANB libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DUSE_ANB endif @@ -36,5 +39,6 @@ if BOARD_USE_DMA_BUF libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DUSE_DMA_BUF endif +libOMX_Exynos_M2V_Decoder_la_CFLAGS += -DTBM_BUF_FD libOMX_Exynos_M2V_Decoder_la_LDFLAGS = -module -avoid-version diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c old mode 100644 new mode 100755 index c518a06..bb4ea92 --- a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OMX_Basecomponent.h" @@ -1752,7 +1753,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_SetParameter( break; #ifdef SLP_PLATFORM /* NV12T fd */ case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: - pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB); + pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer); break; #endif case OMX_SEC_COLOR_FormatNV12Tiled: diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h old mode 100644 new mode 100755 index a1b0706..3740733 --- a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h @@ -107,6 +107,8 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE Mpeg4CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent); #ifdef __cplusplus }; #endif diff --git a/openmax/component/video/dec/mpeg4/Makefile.am b/openmax/component/video/dec/mpeg4/Makefile.am old mode 100644 new mode 100755 index 0de12e3..de95dff --- a/openmax/component/video/dec/mpeg4/Makefile.am +++ b/openmax/component/video/dec/mpeg4/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.M4V.Decoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_M4V_Decoder_la_SOURCES = Exynos_OMX_Mpeg4dec.c \ Exynos_OMX_Mpeg4dec.h \ @@ -24,6 +24,9 @@ libOMX_Exynos_M4V_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ -I$(top_srcdir)/exynos/include +libOMX_Exynos_M4V_Decoder_la_CFLAGS += $(MM_COMMON_CFLAGS) +libOMX_Exynos_M4V_Decoder_la_LIBADD += $(MM_COMMON_LIBS) + if BOARD_USE_ANB libOMX_Exynos_M4V_Decoder_la_CFLAGS += -DUSE_ANB endif diff --git a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h old mode 100644 new mode 100755 index d944208..f614c83 --- a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h +++ b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h @@ -112,6 +112,9 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE WmvCodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE WmvCodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent); #ifdef __cplusplus }; #endif diff --git a/openmax/component/video/dec/vc1/Makefile.am b/openmax/component/video/dec/vc1/Makefile.am old mode 100644 new mode 100755 index d3636bc..abb2fb5 --- a/openmax/component/video/dec/vc1/Makefile.am +++ b/openmax/component/video/dec/vc1/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.WMV.Decoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_WMV_Decoder_la_SOURCES = Exynos_OMX_Wmvdec.c \ Exynos_OMX_Wmvdec.h \ diff --git a/openmax/component/video/enc/Exynos_OMX_Venc.c b/openmax/component/video/enc/Exynos_OMX_Venc.c old mode 100644 new mode 100755 index afd3c4e..4d45cd2 --- a/openmax/component/video/enc/Exynos_OMX_Venc.c +++ b/openmax/component/video/enc/Exynos_OMX_Venc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OSAL_Event.h" #include "Exynos_OMX_Venc.h" @@ -373,12 +374,12 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[1]); } #else // for Tizen Camera scenario - SCMN_IMGB *pscmn_Imgb = (SCMN_IMGB*)inputUseBuffer->bufferHeader->pBuffer; + MMVideoBuffer *mm_buf = (MMVideoBuffer*)inputUseBuffer->bufferHeader->pBuffer; int plane = 0; for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { - srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pscmn_Imgb->a[plane]; - srcInputData->buffer.multiPlaneBuffer.fd[plane] = pscmn_Imgb->fd[plane]; + srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = mm_buf->data[plane];//handle.paddr[plane]; + srcInputData->buffer.multiPlaneBuffer.fd[plane] = mm_buf->handle.dmabuf_fd[plane]; Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[ENC] get fd[%d] %d , a[%d] %x " , plane, srcInputData->buffer.multiPlaneBuffer.fd[plane], plane, srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] ); } diff --git a/openmax/component/video/enc/Exynos_OMX_VencControl.c b/openmax/component/video/enc/Exynos_OMX_VencControl.c old mode 100644 new mode 100755 index 49203f5..c46dde3 --- a/openmax/component/video/enc/Exynos_OMX_VencControl.c +++ b/openmax/component/video/enc/Exynos_OMX_VencControl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "Exynos_OMX_Macros.h" #include "Exynos_OSAL_Event.h" #include "Exynos_OMX_Venc.h" @@ -129,6 +130,32 @@ OMX_ERRORTYPE Exynos_OMX_UseBuffer( #ifdef SLP_PLATFORM if (nPortIndex == OUTPUT_PORT_INDEX && pVideoEnc->bSharedOutputFD == OMX_TRUE) pExynosPort->extendBufferHeader[i].buf_fd[0] = (int)(pBuffer); /*IL Client provides only FD value*/ + + MMVideoBuffer * pSlpOutBuf = (MMVideoBuffer *)pBuffer; + + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "fd[0] =%d, fd[1] =%d, vaddr[0] =%p, vaddr[1] = %p, y_size=%d, uv_size=%d\n", + pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1], pSlpOutBuf->data[0], pSlpOutBuf->data[1], + pSlpOutBuf->size[0],pSlpOutBuf->size[1]); + if(nPortIndex == OUTPUT_PORT_INDEX ) + pTempBufferHdr->pBuffer = pSlpOutBuf->handle.paddr[0]; + + pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->handle.dmabuf_fd[0]; + pExynosPort->extendBufferHeader[i].buf_fd[1] = pSlpOutBuf->handle.dmabuf_fd[1]; + pExynosPort->extendBufferHeader[i].buf_fd[2] = 0; + + pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->data[0]; + pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->data[1]; + pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL; + + //pExynosPort->extendBufferHeader[i].tbm_bo[0] = pSlpOutBuf->handle.bo[0]; + //pExynosPort->extendBufferHeader[i].tbm_bo[1] = pSlpOutBuf->handle.bo[1]; + //pExynosPort->extendBufferHeader[i].tbm_bo[2] = NULL; + + //pExynosPort->extendBufferHeader[i].size[0] = pSlpOutBuf->size[0]; + //pExynosPort->extendBufferHeader[i].size[1] = pSlpOutBuf->size[1]; + //pExynosPort->extendBufferHeader[i].size[2] = 0; + + #endif pExynosPort->assignedBufferNum++; if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) { diff --git a/openmax/component/video/enc/Makefile.am b/openmax/component/video/enc/Makefile.am old mode 100644 new mode 100755 index 72d5c89..47b6e4e --- a/openmax/component/video/enc/Makefile.am +++ b/openmax/component/video/enc/Makefile.am @@ -19,7 +19,10 @@ libExynosOMX_Venc_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \ -I$(top_srcdir)/openmax/component/video/enc \ -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include \ -I$(top_srcdir)/exynos/include \ - -I$(top_srcdir)/exynos/libcsc + -I$(top_srcdir)/exynos/libcsc + +libExynosOMX_Venc_la_CFLAGS += $(MM_COMMON_CFLAGS) +libExynosOMX_Venc_la_LIBADD += $(MM_COMMON_LIBS) if BOARD_USE_METADATABUFFERTYPE libExynosOMX_Venc_la_CFLAGS += -DUSE_METADATABUFFERTYPE diff --git a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c old mode 100644 new mode 100755 index 651eaaa..c8b189f --- a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c +++ b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c @@ -582,15 +582,15 @@ OMX_ERRORTYPE Mpeg4CodecOpen(EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc) if (pMpeg4Enc->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) { #ifdef USE_DMA_BUF v4l2MemoryType = V4L2_MEMORY_DMABUF; - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_DMABUF"); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "using Enc V4L2_MEMORY_DMABUF"); #else v4l2MemoryType = V4L2_MEMORY_USERPTR; - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_USEPTR"); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "using Enc V4L2_MEMORY_USEPTR"); #endif } else { //v4l2MemoryType = V4L2_MEMORY_MMAP; v4l2MemoryType = V4L2_MEMORY_DMABUF; //if input port is using Buffer-share mode - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY - DMABUF & MMAP"); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "using Enc V4L2_MEMORY - DMABUF & MMAP"); } /* alloc context, open, querycap */ diff --git a/openmax/component/video/enc/mpeg4/Makefile.am b/openmax/component/video/enc/mpeg4/Makefile.am old mode 100644 new mode 100755 index dda1a4f..9e46125 --- a/openmax/component/video/enc/mpeg4/Makefile.am +++ b/openmax/component/video/enc/mpeg4/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libOMX.Exynos.M4V.Encoder.la -libdir = @prefix@/lib/omx +libdir = @libdir@/omx libOMX_Exynos_M4V_Encoder_la_SOURCES = Exynos_OMX_Mpeg4enc.c \ Exynos_OMX_Mpeg4enc.h \ diff --git a/openmax/include/exynos/Exynos_OMX_Def.h b/openmax/include/exynos/Exynos_OMX_Def.h old mode 100644 new mode 100755 index 6b4acbb..c533aa9 --- a/openmax/include/exynos/Exynos_OMX_Def.h +++ b/openmax/include/exynos/Exynos_OMX_Def.h @@ -52,10 +52,10 @@ #define MAX_BUFFER_PLANE 3 -#ifdef SLP_PLATFORM /* build env */ +#ifdef USE_NEON #define EXYNOS_OMX_INSTALL_PATH "/usr/lib/omx/" #else -#define EXYNOS_OMX_INSTALL_PATH "/system/lib/omx/" +#define EXYNOS_OMX_INSTALL_PATH "/usr/lib64/omx/" #endif typedef enum _EXYNOS_CODEC_TYPE diff --git a/openmax/osal/Exynos_OSAL_Platform_Specific.c b/openmax/osal/Exynos_OSAL_Platform_Specific.c index 004049a..8359e6a 100755 --- a/openmax/osal/Exynos_OSAL_Platform_Specific.c +++ b/openmax/osal/Exynos_OSAL_Platform_Specific.c @@ -28,6 +28,7 @@ #include #include +#include #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OMX_Baseport.h" @@ -153,22 +154,22 @@ OMX_ERRORTYPE Exynos_OSAL_LockPB( #ifdef SLP_PLATFORM ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes; - SCMN_IMGB *buffer = (SCMN_IMGB *) pBuffer; + MMVideoBuffer *buffer = (MMVideoBuffer *) pBuffer; - vplanes[0].fd = buffer->fd[0]; + vplanes[0].fd = buffer->handle.dmabuf_fd[0]; vplanes[0].offset = 0; - vplanes[1].fd = buffer->fd[1]; + vplanes[1].fd = buffer->handle.dmabuf_fd[1]; vplanes[1].offset = 0; //priv_hnd->uoffset; vplanes[2].fd = 0; //priv_hnd->v_fd; vplanes[2].offset = 0; //priv_hnd->voffset; - vplanes[0].addr = buffer->a[0]; //vaddr[0]; - vplanes[1].addr = buffer->a[1]; //vaddr[1]; + vplanes[0].addr = buffer->data[0]; //vaddr[0]; + vplanes[1].addr = buffer->data[1]; //vaddr[1]; vplanes[2].addr = NULL; //vaddr[2]; Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OSAL_LockPB:fd[0](%d) fd[1](%d) a[0](%p) a[1](%p)", - buffer->fd[0], buffer->fd[1], buffer->a[0], buffer->a[1]); + buffer->handle.dmabuf_fd[0], buffer->handle.dmabuf_fd[1], buffer->data[0], buffer->data[1]); #else android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; @@ -192,42 +193,43 @@ OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, EXYNOS_OMX_DATA *pDat OMX_ERRORTYPE ret = OMX_ErrorNone; #ifdef SLP_PLATFORM - SCMN_IMGB *pSlpOutBuf = NULL; + MMVideoBuffer *pSlpOutBuf = NULL; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; - pSlpOutBuf = (SCMN_IMGB *)pBuffer; + pSlpOutBuf = (MMVideoBuffer *)pBuffer; if (pSlpOutBuf == NULL) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pBuffer is NULL!"); ret = OMX_ErrorInsufficientResources; goto EXIT; } - memset(pSlpOutBuf, 0, sizeof(SCMN_IMGB)); + memset(pSlpOutBuf, 0, sizeof(MMVideoBuffer)); pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pData->extInfo; if (pExynosPort->cropRectangle.nWidth != 0 && pExynosPort->cropRectangle.nHeight != 0) { /* modify for h264 trim */ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "this has cropRectangle(h264).crop.nWidth = %d, crop.nHeight = %d", - pExynosPort->cropRectangle.nWidth, pExynosPort->cropRectangle.nHeight); - pSlpOutBuf->w[0] = pExynosPort->cropRectangle.nWidth; - pSlpOutBuf->w[1] = pExynosPort->cropRectangle.nWidth; - pSlpOutBuf->h[0] = pExynosPort->cropRectangle.nHeight; - pSlpOutBuf->h[1] = (pExynosPort->cropRectangle.nHeight/2); - - pSlpOutBuf->s[0] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ - pSlpOutBuf->s[1] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); - pSlpOutBuf->e[0] = ALIGN(pExynosPort->cropRectangle.nHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ - pSlpOutBuf->e[1] = ALIGN((pExynosPort->cropRectangle.nHeight/2), S5P_FIMV_NV12MT_VALIGN); + pExynosPort->cropRectangle.nWidth, pExynosPort->cropRectangle.nWidth); + pSlpOutBuf->width[0] = pExynosPort->cropRectangle.nWidth; + pSlpOutBuf->width[1] = pExynosPort->cropRectangle.nWidth; + pSlpOutBuf->height[0] = pExynosPort->cropRectangle.nHeight; + pSlpOutBuf->height[1] = pExynosPort->cropRectangle.nHeight/2; + + + pSlpOutBuf->stride_width[0] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ + pSlpOutBuf->stride_width[1] = ALIGN(pExynosPort->cropRectangle.nWidth, S5P_FIMV_NV12MT_HALIGN); + pSlpOutBuf->stride_height[0] = ALIGN(pExynosPort->cropRectangle.nHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ + pSlpOutBuf->stride_height[1] = ALIGN((pExynosPort->cropRectangle.nHeight/2), S5P_FIMV_NV12MT_VALIGN); } else { - pSlpOutBuf->w[0] = pBufferInfo->imageWidth; - pSlpOutBuf->w[1] = pBufferInfo->imageWidth; - pSlpOutBuf->h[0] = pBufferInfo->imageHeight; - pSlpOutBuf->h[1] = (pBufferInfo->imageHeight/2); + pSlpOutBuf->width[0] = pBufferInfo->imageWidth; + pSlpOutBuf->width[1] = pBufferInfo->imageWidth; + pSlpOutBuf->height[0] = pBufferInfo->imageHeight; + pSlpOutBuf->height[1] = (pBufferInfo->imageHeight/2); - pSlpOutBuf->s[0] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ - pSlpOutBuf->s[1] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); - pSlpOutBuf->e[0] = ALIGN(pBufferInfo->imageHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ - pSlpOutBuf->e[1] = ALIGN((pBufferInfo->imageHeight/2), S5P_FIMV_NV12MT_VALIGN); + pSlpOutBuf->stride_width[0] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); /* need to check. stride */ + pSlpOutBuf->stride_width[1] = ALIGN(pBufferInfo->imageWidth, S5P_FIMV_NV12MT_HALIGN); + pSlpOutBuf->stride_height[0] = ALIGN(pBufferInfo->imageHeight, S5P_FIMV_NV12MT_VALIGN); /* need to check. elevation */ + pSlpOutBuf->stride_height[1] = ALIGN((pBufferInfo->imageHeight/2), S5P_FIMV_NV12MT_VALIGN); } @@ -238,30 +240,30 @@ OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, EXYNOS_OMX_DATA *pDat pSlpOutBuf->a[1] = 0; } else { */ - pSlpOutBuf->a[0] = pData->buffer.multiPlaneBuffer.dataBuffer[0]; - pSlpOutBuf->a[1] = pData->buffer.multiPlaneBuffer.dataBuffer[1]; + pSlpOutBuf->data[0] = pData->buffer.multiPlaneBuffer.dataBuffer[0]; + pSlpOutBuf->data[1] = pData->buffer.multiPlaneBuffer.dataBuffer[1]; // } - pSlpOutBuf->a[2] = 0; /* omx do not use this plane */ + pSlpOutBuf->data[2] = 0; /* omx do not use this plane */ - pSlpOutBuf->fd[0] = pData->buffer.multiPlaneBuffer.fd[0]; - pSlpOutBuf->fd[1] = pData->buffer.multiPlaneBuffer.fd[1]; - pSlpOutBuf->fd[2] = 0; + pSlpOutBuf->handle.dmabuf_fd[0] = pData->buffer.multiPlaneBuffer.fd[0]; + pSlpOutBuf->handle.dmabuf_fd[1] = pData->buffer.multiPlaneBuffer.fd[1]; + pSlpOutBuf->handle.dmabuf_fd[2] = 0; if(pExynosInPort->portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) { - pSlpOutBuf->y_size = calc_plane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); - pSlpOutBuf->uv_size = calc_plane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); - Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"H264 foramt and y_size=%d, uv_size=%d",pSlpOutBuf->y_size,pSlpOutBuf->uv_size); + pSlpOutBuf->size[0] = calc_plane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); + pSlpOutBuf->size[1] = calc_plane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"H264 foramt and y_size=%d, uv_size=%d",pSlpOutBuf->size[0],pSlpOutBuf->size[1]); } else { - pSlpOutBuf->y_size= calc_yplane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); - pSlpOutBuf->uv_size = calc_uvplane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); - Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"foramt is %d, and y_size=%d, uv_size=%d",pExynosInPort->portDefinition.format.video.eCompressionFormat ,pSlpOutBuf->y_size,pSlpOutBuf->uv_size); + pSlpOutBuf->size[0]= calc_yplane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); + pSlpOutBuf->size[1] = calc_uvplane(pBufferInfo->imageWidth,(pBufferInfo->imageHeight) / 2); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"foramt is %d, and y_size=%d, uv_size=%d",pExynosInPort->portDefinition.format.video.eCompressionFormat ,pSlpOutBuf->size[0],pSlpOutBuf->size[1]); } - pSlpOutBuf->buf_share_method = 1; /* use fd mode */ + //pSlpOutBuf->type = 1; /* use fd mode */ - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->fd[2]); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1], pSlpOutBuf->handle.dmabuf_fd[2]); #else android_native_buffer_t *pANB = (android_native_buffer_t *) pBuffer; diff --git a/openmax/osal/Makefile.am b/openmax/osal/Makefile.am old mode 100644 new mode 100755 index 4509e8a..4a45f99 --- a/openmax/osal/Makefile.am +++ b/openmax/osal/Makefile.am @@ -34,6 +34,9 @@ libExynosOMX_OSAL_la_CFLAGS = -I$(top_srcdir)/exynos4/include \ -I$(top_srcdir)/exynos/include \ -I$(top_srcdir)/exynos4/libcodec/video/v4l2/include +libExynosOMX_OSAL_la_CFLAGS += $(MM_COMMON_CFLAGS) +libExynosOMX_OSAL_la_LIBADD += $(MM_COMMON_LIBS) + if USE_DLOG libExynosOMX_OSAL_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG libExynosOMX_OSAL_la_LIBADD += $(DLOG_LIBS) diff --git a/packaging/libomxil-e3250-v4l2.spec b/packaging/libomxil-e3250-v4l2.spec index 2d629a2..ece82c8 100755 --- a/packaging/libomxil-e3250-v4l2.spec +++ b/packaging/libomxil-e3250-v4l2.spec @@ -8,10 +8,9 @@ ExclusiveArch: %arm Source: %{name}-%{version}.tar.gz Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig -#!BuildIgnore: kernel-headers -BuildRequires: kernel-headers-3.4-exynos3250 +BuildRequires: kernel-headers BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(mm-ta) +BuildRequires: pkgconfig(mm-common) %description implementation of OpenMAX IL for e3250-v4l2 for B2 @@ -31,14 +30,22 @@ development package for libomxil-e3250-v4l2 %build ./autogen.sh -export CFLAGS+=" -mfpu=neon\ - -DUSE_DLOG\ +export CFLAGS+="\ +%ifnarch aarch64 + -mfpu=neon\ + -DUSE_NEON\ +%endif -DUSE_PB\ -DUSE_DMA_BUF\ -DUSE_H264_PREPEND_SPS_PPS\ - -DGST_EXT_TIME_ANALYSIS" + -DGST_EXT_TIME_ANALYSIS\ + -DKERNEL_HEADER_MODIFICATION" -%configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-mm-ta --enable-exynos3250 +%ifnarch aarch64 +%configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-exynos3250 --enable-neon +%else +%configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-exynos3250 --disable-neon +%endif #make %{?jobs:-j%jobs} make @@ -46,8 +53,8 @@ make %install rm -rf %{buildroot} -mkdir -p %{buildroot}/usr/share/license -cp COPYING %{buildroot}/usr/share/license/%{name} +#mkdir -p %{buildroot}/usr/share/license +#cp COPYING %{buildroot}/usr/share/license/%{name} %make_install @@ -58,17 +65,11 @@ cp COPYING %{buildroot}/usr/share/license/%{name} %files %manifest libomxil-e3250-v4l2.manifest -/usr/lib/*.so* -/usr/lib/omx/libOMX.Exynos.AVC.Decoder.so -/usr/lib/omx/libOMX.Exynos.AVC.Encoder.so -/usr/lib/omx/libOMX.Exynos.M4V.Decoder.so -/usr/share/license/%{name} -%exclude /usr/lib/omx/libOMX.Exynos.M2V.Decoder.so -%exclude /usr/lib/omx/libOMX.Exynos.WMV.Decoder.so -%exclude /usr/lib/omx/libOMX.Exynos.M4V.Encoder.so -%exclude /usr/lib/omx/libOMX.Exynos.MP3.Decoder.so +%{_libdir}/*.so* +%{_libdir}/omx/*.so + %files devel /usr/include/* -/usr/lib/pkgconfig/* +%{_libdir}/pkgconfig/* diff --git a/srp.pc.in b/srp.pc.in old mode 100644 new mode 100755 index 2dc20c3..d7cc67a --- a/srp.pc.in +++ b/srp.pc.in @@ -1,5 +1,5 @@ prefix=@prefix@ -libdir=@prefix@/lib +libdir=@LIB_INSTALL_DIR@ includedir=@prefix@/include Name: Samsung RP package -- 2.7.4 From 4c851a904d2d4ae6927accc7b3de9564071b5f36 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 31 Mar 2016 20:02:34 +0900 Subject: [PATCH 4/7] Enabling omxil for TW1 Change-Id: Ic28be863263b78761c69765af7552803788d14a4 --- exynos/include/exynos_v4l2.h | 16 +- exynos/include/media.h | 132 -- exynos/include/v4l2-mediabus.h | 116 - exynos/include/v4l2-subdev.h | 141 -- exynos/include/videodev2.h | 2452 -------------------- exynos/include/videodev2_exynos_media.h | 236 -- exynos/kernel_header/compiler.h | 307 --- exynos/kernel_header/media.h | 132 -- exynos/kernel_header/v4l2-mediabus.h | 111 - exynos/kernel_header/v4l2-subdev.h | 145 -- exynos/libv4l2/exynos_mc.c | 8 - .../libcodec/video/v4l2/dec/ExynosVideoDecoder.c | 5 +- .../libcodec/video/v4l2/include/ExynosVideoApi.h | 1 + openmax/component/common/Exynos_OMX_Baseport.h | 4 + openmax/component/video/dec/Exynos_OMX_Vdec.c | 6 +- .../component/video/dec/Exynos_OMX_VdecControl.c | 8 +- .../component/video/dec/h264/Exynos_OMX_H264dec.c | 2 + .../video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c | 2 + .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 1 + openmax/osal/Exynos_OSAL_Platform_Specific.c | 4 + packaging/libomxil-e3250-v4l2.spec | 11 +- 21 files changed, 34 insertions(+), 3806 deletions(-) delete mode 100755 exynos/include/media.h delete mode 100755 exynos/include/v4l2-mediabus.h delete mode 100755 exynos/include/v4l2-subdev.h delete mode 100755 exynos/include/videodev2.h delete mode 100755 exynos/include/videodev2_exynos_media.h delete mode 100755 exynos/kernel_header/compiler.h delete mode 100755 exynos/kernel_header/media.h delete mode 100755 exynos/kernel_header/v4l2-mediabus.h delete mode 100755 exynos/kernel_header/v4l2-subdev.h mode change 100644 => 100755 exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h mode change 100644 => 100755 openmax/component/common/Exynos_OMX_Baseport.h diff --git a/exynos/include/exynos_v4l2.h b/exynos/include/exynos_v4l2.h index b682703..7df8cc9 100755 --- a/exynos/include/exynos_v4l2.h +++ b/exynos/include/exynos_v4l2.h @@ -43,7 +43,7 @@ extern "C" { #include #ifdef SLP_PLATFORM #include -//#include +#include #else #include "videodev2.h" /* vendor specific videodev2.h */ #include "videodev2_exynos_media.h" @@ -107,15 +107,9 @@ int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl); #ifndef SLP_PLATFORM /* build env */ #include #else - -#ifdef KERNEL_HEADER_MODIFICATION -#include "../kernel_header/v4l2-subdev.h" -#else #include #endif -#endif - /*! \ingroup exynos_v4l2 */ int exynos_subdev_open(const char *filename, int oflag, ...); /*! \ingroup exynos_v4l2 */ @@ -143,17 +137,9 @@ int exynos_subdev_enum_mbus_code(int fd, struct v4l2_subdev_mbus_code_enum *mbus #ifndef SLP_PLATFORM /* build env */ #include #else - -#ifdef KERNEL_HEADER_MODIFICATION -#include "../kernel_header/compiler.h" -#include "../kernel_header/media.h" -#else -#include #include #endif -#endif - /*! media_link * \ingroup exynos_v4l2 */ diff --git a/exynos/include/media.h b/exynos/include/media.h deleted file mode 100755 index 0ef8833..0000000 --- a/exynos/include/media.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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/exynos/include/v4l2-mediabus.h b/exynos/include/v4l2-mediabus.h deleted file mode 100755 index 1a13cf3..0000000 --- a/exynos/include/v4l2-mediabus.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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/exynos/include/v4l2-subdev.h b/exynos/include/v4l2-subdev.h deleted file mode 100755 index f5dd9a1..0000000 --- a/exynos/include/v4l2-subdev.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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/exynos/include/videodev2.h b/exynos/include/videodev2.h deleted file mode 100755 index d4fde43..0000000 --- a/exynos/include/videodev2.h +++ /dev/null @@ -1,2452 +0,0 @@ -/* - * 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, - V4L2_MEMORY_DMABUF = 4, -}; - -/* 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; -}; - -/** - * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP - * - * @driver: name of the driver module (e.g. "bttv") - * @card: name of the card (e.g. "Hauppauge WinTV") - * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) - * @version: KERNEL_VERSION - * @capabilities: capabilities of the physical device as a whole - * @device_caps: capabilities accessed via this particular device (node) - * @reserved: reserved fields for future extensions - */ -struct v4l2_capability { - __u8 driver[16]; - __u8 card[32]; - __u8 bus_info[32]; - __u32 version; - __u32 capabilities; - __u32 device_caps; - __u32 reserved[3]; -}; - -/* 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 */ - -#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ - -/* - * 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 */ -#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ -#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ - -/* 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_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ - -/* three non contiguous planes - Y, Cb, Cr */ -#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 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 Multiplexed */ -#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ -#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ -#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ -#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ -#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ -#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */ -#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ -#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ -#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ - -/* 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_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB 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_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ - -/* - * 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 - * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file - * descriptor associated with 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; - int fd; - } m; - __u32 data_offset; - __u32 reserved[11]; -}; - -/** - * 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 - * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; - * a userspace file descriptor associated with 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; - int fd; - } 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 */ -#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ -/* Cache handling flags */ -#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 -#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 - -/* - * 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; -}; - -/* Hints for adjustments of selection rectangle */ -#define V4L2_SEL_FLAG_GE 0x00000001 -#define V4L2_SEL_FLAG_LE 0x00000002 - -/* Selection targets */ - -/* Current cropping area */ -#define V4L2_SEL_TGT_CROP_ACTIVE 0x0000 -/* Default cropping area */ -#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 -/* Cropping bounds */ -#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 -/* Current composing area */ -#define V4L2_SEL_TGT_COMPOSE_ACTIVE 0x0100 -/* Default composing area */ -#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 -/* Composing bounds */ -#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 -/* Current composing area plus all padding pixels */ -#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 - -/** - * struct v4l2_selection - selection info - * @type: buffer type (do not use *_MPLANE types) - * @target: selection target, used to choose one of possible rectangles - * @flags: constraints flags - * @r: coordinates of selection window - * @reserved: for future use, rounds structure size to 64 bytes, set to zero - * - * Hardware may use multiple helper windows to process a video stream. - * The structure is used to exchange this selection areas between - * an application and a driver. - */ -struct v4l2_selection { - __u32 type; - __u32 target; - __u32 flags; - struct v4l2_rect r; - __u32 reserved[9]; -}; - - -/* - * 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) /* BTSC */ -#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ -#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) -#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ - -#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 macros to merge video standards in order to make live easier for the - * drivers and V4L2 applications - */ - -/* - * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is - * Missing here. - */ -#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ - V4L2_STD_NTSC_M_JP |\ - V4L2_STD_NTSC_M_KR) -/* Secam macros */ -#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ - V4L2_STD_SECAM_K |\ - V4L2_STD_SECAM_K1) -/* All Secam Standards */ -#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) -/* PAL macros */ -#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) -/* - * "Common" PAL - This macro is there to be compatible with the old - * V4L1 concept of "PAL": /BGDKHI. - * Several PAL standards are mising here: /M, /N and /Nc - */ -#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ - V4L2_STD_PAL_DK |\ - V4L2_STD_PAL_H |\ - V4L2_STD_PAL_I) -/* Chroma "agnostic" standards */ -#define V4L2_STD_B (V4L2_STD_PAL_B |\ - V4L2_STD_PAL_B1 |\ - V4L2_STD_SECAM_B) -#define V4L2_STD_G (V4L2_STD_PAL_G |\ - V4L2_STD_SECAM_G) -#define V4L2_STD_H (V4L2_STD_PAL_H |\ - V4L2_STD_SECAM_H) -#define V4L2_STD_L (V4L2_STD_SECAM_L |\ - V4L2_STD_SECAM_LC) -#define V4L2_STD_GH (V4L2_STD_G |\ - V4L2_STD_H) -#define V4L2_STD_DK (V4L2_STD_PAL_DK |\ - V4L2_STD_SECAM_DK) -#define V4L2_STD_BG (V4L2_STD_B |\ - V4L2_STD_G) -#define V4L2_STD_MN (V4L2_STD_PAL_M |\ - V4L2_STD_PAL_N |\ - V4L2_STD_PAL_Nc |\ - V4L2_STD_NTSC) - -/* Standards where MTS/BTSC stereo could be found */ -#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ - V4L2_STD_PAL_M |\ - V4L2_STD_PAL_N |\ - V4L2_STD_PAL_Nc) - -/* Standards for Countries with 60Hz Line frequency */ -#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ - V4L2_STD_PAL_60 |\ - V4L2_STD_NTSC |\ - V4L2_STD_NTSC_443) -/* Standards for Countries with 50Hz Line frequency */ -#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) -/* Macros with none and all analog standards */ -#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_FLASH 0x009c0000 /* Camera flash controls */ -#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ -#define V4L2_CTRL_CLASS_CODEC 0x009e0000 /* 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, - V4L2_CTRL_TYPE_BITMASK = 8, -}; - -/* 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 -#define V4L2_CTRL_FLAG_VOLATILE 0x0080 - -/* 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_MAX_CTRLS 1024 -#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, - V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, -}; -#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) - -#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) -#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) - -#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) - -/* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+42) - -/* 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, specific to multiplexed 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 controls specific to multiplexed streams */ -#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, -}; -#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) -enum v4l2_mpeg_audio_dec_playback { - V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, - V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, - V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, - V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, - V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, - V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, -}; -#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) - -/* MPEG video controls specific to multiplexed streams */ -#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) -#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) -#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) -#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) -#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) -#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) -enum v4l2_mpeg_video_header_mode { - V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, - V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, - -}; -#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) -#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) -#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) -#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) -#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) -enum v4l2_mpeg_video_multi_slice_mode { - V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, - V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, - V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, -}; -#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) -#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) -#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) - -#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) -#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) -#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) -#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) -#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) -#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) -#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) -#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) -#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) -#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) -#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) -#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) -#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) -enum v4l2_mpeg_video_h264_entropy_mode { - V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, - V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, -}; -#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) -#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) -enum v4l2_mpeg_video_h264_level { - V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, - V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, - V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, - V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, - V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, - V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, - V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, - V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, - V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, - V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, - V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, - V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, - V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, - V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, -}; -#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) -#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) -#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) -enum v4l2_mpeg_video_h264_loop_filter_mode { - V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, - V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, - V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, -}; -#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) -enum v4l2_mpeg_video_h264_profile { - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, - V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, - V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, - V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, - V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, - V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, - V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, - V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, - V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, - V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, -}; -#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) -#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) -#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) -#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) -enum v4l2_mpeg_video_h264_vui_sar_idc { - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, - V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, -}; -#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) -#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) -#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) -#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) -#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) -#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) -enum v4l2_mpeg_video_mpeg4_level { - V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, - V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, -}; -#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) -enum v4l2_mpeg_video_mpeg4_profile { - V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, - V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, - V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, - V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, - V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, -}; -#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) - -/* 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) - -/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ -#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) - -#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) -#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) -enum v4l2_mpeg_mfc51_video_frame_skip_mode { - V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, - V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, - V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, -}; -#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) -enum v4l2_mpeg_mfc51_video_force_frame_type { - V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, - V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, - V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, -}; -#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) -#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) -#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) -#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) - -/* 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) - -/* Flash and privacy (indicator) light controls */ -#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) -#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) - -#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) -enum v4l2_flash_led_mode { - V4L2_FLASH_LED_MODE_NONE, - V4L2_FLASH_LED_MODE_FLASH, - V4L2_FLASH_LED_MODE_TORCH, -}; - -#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) -enum v4l2_flash_strobe_source { - V4L2_FLASH_STROBE_SOURCE_SOFTWARE, - V4L2_FLASH_STROBE_SOURCE_EXTERNAL, -}; - -#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) -#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) -#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) - -#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) -#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) -#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) -#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) - -#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) -#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) -#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) -#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) -#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) -#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) -#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) - -#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) -#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) - -/* JPEG-class control IDs defined by V4L2 */ -#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) -#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) - -#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) -enum v4l2_jpeg_chroma_subsampling { - V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, - V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, - V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, - V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, - V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, - V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, -}; -#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) -#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) - -#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) -#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) -#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) -#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) -#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) -#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) - -/* - * 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; - }; -}; - -/* Decoder commands */ -#define V4L2_DEC_CMD_START (0) -#define V4L2_DEC_CMD_STOP (1) -#define V4L2_DEC_CMD_PAUSE (2) -#define V4L2_DEC_CMD_RESUME (3) - -/* Flags for V4L2_DEC_CMD_START */ -#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) - -/* Flags for V4L2_DEC_CMD_PAUSE */ -#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) - -/* Flags for V4L2_DEC_CMD_STOP */ -#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) -#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) - -/* Play format requirements (returned by the driver): */ - -/* The decoder has no special format requirements */ -#define V4L2_DEC_START_FMT_NONE (0) -/* The decoder requires full GOPs */ -#define V4L2_DEC_START_FMT_GOP (1) - -/* The structure must be zeroed before use by the application - This ensures it can be extended safely in the future. */ -struct v4l2_decoder_cmd { - __u32 cmd; - __u32 flags; - union { - struct { - __u64 pts; - } stop; - - struct { - /* 0 or 1000 specifies normal speed, - 1 specifies forward single stepping, - -1 specifies backward single stepping, - >1: playback at speed/1000 of the normal speed, - <-1: reverse playback at (-speed/1000) of the normal speed. */ - __s32 speed; - __u32 format; - } start; - - struct { - __u32 data[16]; - } 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_CTRL 3 -#define V4L2_EVENT_FRAME_SYNC 4 -#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)); - -/* Payload for V4L2_EVENT_CTRL */ -#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) -#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) - -struct v4l2_event_ctrl { - __u32 changes; - __u32 type; - union { - __s32 value; - __s64 value64; - }; - __u32 flags; - __s32 minimum; - __s32 maximum; - __s32 step; - __s32 default_value; -}; - -struct v4l2_event_frame_sync { - __u32 frame_sequence; -}; - -struct v4l2_event { - __u32 type; - union { - struct v4l2_event_vsync vsync; - struct v4l2_event_ctrl ctrl; - struct v4l2_event_frame_sync frame_sync; - __u8 data[64]; - } u; - __u32 pending; - __u32 sequence; - struct timespec timestamp; - __u32 id; - __u32 reserved[8]; -}; - -#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) -#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) - -struct v4l2_event_subscription { - __u32 type; - __u32 id; - __u32 flags; - __u32 reserved[5]; -}; - -/* - * 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)); - -/** - * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument - * @index: on return, index of the first created buffer - * @count: entry: number of requested buffers, - * return: number of created buffers - * @memory: buffer memory type - * @format: frame format, for which buffers are requested - * @reserved: future extensions - */ -struct v4l2_create_buffers { - __u32 index; - __u32 count; - enum v4l2_memory memory; - struct v4l2_format format; - __u32 reserved[8]; -}; - -/* - * 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) - -/* Experimental, the below two ioctls may change over the next couple of kernel - versions */ -#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) -#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) - -/* Experimental selection API */ -#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) -#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) - -/* Experimental, these two ioctls may change over the next couple of kernel - versions. */ -#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) -#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) - -/* 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/exynos/include/videodev2_exynos_media.h b/exynos/include/videodev2_exynos_media.h deleted file mode 100755 index a952438..0000000 --- a/exynos/include/videodev2_exynos_media.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Video for Linux Two header file for Exynos - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * This header file contains several v4l2 APIs to be proposed to v4l2 - * community and until being accepted, will be used restrictly for Exynos. - * - * 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_VIDEODEV2_EXYNOS_MEDIA_H -#define __LINUX_VIDEODEV2_EXYNOS_MEDIA_H - -/* Pixel format FOURCC depth Description */ - -/* two planes -- one Y, one Cr + Cb interleaved */ -#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P') /* 24 Y/CbCr */ -#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P') /* 24 Y/CrCb */ - -/* three planes -- one Y, one Cr, one Cb */ -#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P') /* 24 Y/Cb/Cr */ - -/* two non contiguous planes - one Y, one Cr + Cb interleaved */ -/* 21 Y/CrCb 4:2:0 */ -#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') -/* 12 Y/CbCr 4:2:0 16x16 macroblocks */ -#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') - -/* three non contiguous planes - Y, Cb, Cr */ -/* 12 YVU420 planar */ -#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'V', 'U', 'M') - -/* compressed formats */ -#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ -#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_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ - -/* yuv444 of JFIF JPEG */ -#define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4') -/* yuv422 of JFIF JPEG */ -#define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2') -/* yuv420 of JFIF JPEG */ -#define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0') -/* grey of JFIF JPEG */ -#define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G') - -/* - * C O N T R O L S - */ -/* CID base for Exynos controls (USER_CLASS) */ -#define V4L2_CID_EXYNOS_BASE (V4L2_CTRL_CLASS_USER | 0x2000) - -/* for rgb alpha function */ -#define V4L2_CID_GLOBAL_ALPHA (V4L2_CID_EXYNOS_BASE + 1) - -/* cacheable configuration */ -#define V4L2_CID_CACHEABLE (V4L2_CID_EXYNOS_BASE + 10) - -/* jpeg captured size */ -#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_EXYNOS_BASE + 20) -#define V4L2_CID_CAM_JPEG_ENCODEDSIZE (V4L2_CID_EXYNOS_BASE + 21) - -#define V4L2_CID_SET_SHAREABLE (V4L2_CID_EXYNOS_BASE + 40) - -/* TV configuration */ -#define V4L2_CID_TV_LAYER_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 50) -#define V4L2_CID_TV_LAYER_BLEND_ALPHA (V4L2_CID_EXYNOS_BASE + 51) -#define V4L2_CID_TV_PIXEL_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 52) -#define V4L2_CID_TV_CHROMA_ENABLE (V4L2_CID_EXYNOS_BASE + 53) -#define V4L2_CID_TV_CHROMA_VALUE (V4L2_CID_EXYNOS_BASE + 54) -#define V4L2_CID_TV_HPD_STATUS (V4L2_CID_EXYNOS_BASE + 55) -#define V4L2_CID_TV_LAYER_PRIO (V4L2_CID_EXYNOS_BASE + 56) -#define V4L2_CID_TV_SET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 57) -#define V4L2_CID_TV_GET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 58) -#define V4L2_CID_TV_SET_ASPECT_RATIO (V4L2_CID_EXYNOS_BASE + 59) - -/* for color space conversion equation selection */ -#define V4L2_CID_CSC_EQ_MODE (V4L2_CID_EXYNOS_BASE + 100) -#define V4L2_CID_CSC_EQ (V4L2_CID_EXYNOS_BASE + 101) -#define V4L2_CID_CSC_RANGE (V4L2_CID_EXYNOS_BASE + 102) - -#define V4L2_CID_CONTENT_PROTECTION (V4L2_CID_EXYNOS_BASE + 201) - -/* CID base for MFC controls (MPEG_CLASS) */ -#define V4L2_CID_MPEG_MFC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) - -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL \ - (V4L2_CID_MPEG_MFC_BASE + 1) -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID \ - (V4L2_CID_MPEG_MFC_BASE + 2) -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO \ - (V4L2_CID_MPEG_MFC_BASE + 3) -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS \ - (V4L2_CID_MPEG_MFC_BASE + 4) - -#define V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB \ - (V4L2_CID_MPEG_MFC_BASE + 5) -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG \ - (V4L2_CID_MPEG_MFC_BASE + 6) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE \ - (V4L2_CID_MPEG_MFC_BASE + 7) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA \ - (V4L2_CID_MPEG_MFC_BASE + 8) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA \ - (V4L2_CID_MPEG_MFC_BASE + 9) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA_BOT \ - (V4L2_CID_MPEG_MFC_BASE + 10) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA_BOT \ - (V4L2_CID_MPEG_MFC_BASE + 11) -#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED \ - (V4L2_CID_MPEG_MFC_BASE + 12) -#define V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE \ - (V4L2_CID_MPEG_MFC_BASE + 13) -#define V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS \ - (V4L2_CID_MPEG_MFC_BASE + 14) - -#define V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR \ - (V4L2_CID_MPEG_MFC_BASE + 15) -#define V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR \ - (V4L2_CID_MPEG_MFC_BASE + 16) - -#define V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE \ - (V4L2_CID_MPEG_MFC_BASE + 17) -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT \ - (V4L2_CID_MPEG_MFC_BASE + 18) -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE \ - (V4L2_CID_MPEG_MFC_BASE + 19) -enum v4l2_mpeg_mfc51_video_frame_type { - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_NOT_CODED = 0, - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_I_FRAME = 1, - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_P_FRAME = 2, - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_B_FRAME = 3, - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_SKIPPED = 4, - V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_OTHERS = 5, -}; - -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE \ - (V4L2_CID_MPEG_MFC_BASE + 20) -#define V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE \ - (V4L2_CID_MPEG_MFC_BASE + 21) -#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES \ - (V4L2_CID_MPEG_MFC_BASE + 22) -#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA \ - (V4L2_CID_MPEG_MFC_BASE + 23) -#define V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE \ - (V4L2_CID_MPEG_MFC_BASE + 24) - -#define V4L2_CID_MPEG_MFC6X_VIDEO_FRAME_DELTA \ - (V4L2_CID_MPEG_MFC_BASE + 25) - -#define V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH V4L2_CID_MPEG_VIDEO_GOP_SIZE -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH \ - V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE -#define V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH V4L2_CID_MPEG_VIDEO_BITRATE - -/* new entry for enum v4l2_mpeg_video_mpeg4_level */ -#define V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 8 - -/* proposed CIDs, based on 3.3-rc3 */ -#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_MFC_BASE + 26) - -#define V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B \ - V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY - -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING \ - (V4L2_CID_MPEG_MFC_BASE + 27) -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 \ - (V4L2_CID_MPEG_MFC_BASE + 28) -#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE \ - (V4L2_CID_MPEG_MFC_BASE + 29) -enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_CHEKERBOARD = 0, - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_COLUMN = 1, - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_ROW = 2, - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE = 3, - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TOP_BOTTOM = 4, - V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TEMPORAL = 5, -}; -#define V4L2_CID_MPEG_VIDEO_H264_FMO \ - (V4L2_CID_MPEG_MFC_BASE + 30) -#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE \ - (V4L2_CID_MPEG_MFC_BASE + 31) -enum v4l2_mpeg_video_h264_fmo_map_type { - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, - V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, -}; -#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP \ - (V4L2_CID_MPEG_MFC_BASE + 32) -#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION \ - (V4L2_CID_MPEG_MFC_BASE + 33) -enum v4l2_mpeg_video_h264_fmo_change_dir { - V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, - V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, -}; -#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE \ - (V4L2_CID_MPEG_MFC_BASE + 34) -#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH \ - (V4L2_CID_MPEG_MFC_BASE + 35) -#define V4L2_CID_MPEG_VIDEO_H264_ASO \ - (V4L2_CID_MPEG_MFC_BASE + 36) -#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER \ - (V4L2_CID_MPEG_MFC_BASE + 37) -#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING \ - (V4L2_CID_MPEG_MFC_BASE + 38) -#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE \ - (V4L2_CID_MPEG_MFC_BASE + 39) -enum v4l2_mpeg_video_h264_hierarchical_coding_type { - V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, - V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, -}; -#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER \ - (V4L2_CID_MPEG_MFC_BASE + 40) -#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP \ - (V4L2_CID_MPEG_MFC_BASE + 41) - -#define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID \ - (V4L2_CID_MPEG_MFC_BASE + 42) - -#define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46) - -#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS \ - (V4L2_CID_MPEG_MFC_BASE + 43) -#endif /* __LINUX_VIDEODEV2_EXYNOS_MEDIA_H */ diff --git a/exynos/kernel_header/compiler.h b/exynos/kernel_header/compiler.h deleted file mode 100755 index c1a62c5..0000000 --- a/exynos/kernel_header/compiler.h +++ /dev/null @@ -1,307 +0,0 @@ -#ifndef __LINUX_COMPILER_H -#define __LINUX_COMPILER_H - -#ifndef __ASSEMBLY__ - -#ifdef __CHECKER__ -# define __user __attribute__((noderef, address_space(1))) -# define __kernel __attribute__((address_space(0))) -# define __safe __attribute__((safe)) -# define __force __attribute__((force)) -# define __nocast __attribute__((nocast)) -# define __iomem __attribute__((noderef, address_space(2))) -# define __acquires(x) __attribute__((context(x,0,1))) -# define __releases(x) __attribute__((context(x,1,0))) -# define __acquire(x) __context__(x,1) -# define __release(x) __context__(x,-1) -# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) -# define __percpu __attribute__((noderef, address_space(3))) -# define __rcu -extern void __chk_user_ptr(const volatile void __user *); -extern void __chk_io_ptr(const volatile void __iomem *); -#else -# define __user -# define __kernel -# define __safe -# define __force -# define __nocast -# define __iomem -# define __chk_user_ptr(x) (void)0 -# define __chk_io_ptr(x) (void)0 -# define __builtin_warning(x, y...) (1) -# define __acquires(x) -# define __releases(x) -# define __acquire(x) (void)0 -# define __release(x) (void)0 -# define __cond_lock(x,c) (c) -# define __percpu -# define __rcu -#endif - -#ifdef __KERNEL__ - -#ifdef __GNUC__ -#include -#endif - -#define notrace __attribute__((no_instrument_function)) - -/* Intel compiler defines __GNUC__. So we will overwrite implementations - * coming from above header files here - */ -#ifdef __INTEL_COMPILER -# include -#endif - -/* - * Generic compiler-dependent macros required for kernel - * build go below this comment. Actual compiler/compiler version - * specific implementations come from the above header files - */ - -struct ftrace_branch_data { - const char *func; - const char *file; - unsigned line; - union { - struct { - unsigned long correct; - unsigned long incorrect; - }; - struct { - unsigned long miss; - unsigned long hit; - }; - unsigned long miss_hit[2]; - }; -}; - -/* - * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code - * to disable branch tracing on a per file basis. - */ -#if defined(CONFIG_TRACE_BRANCH_PROFILING) \ - && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__) -void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); - -#define likely_notrace(x) __builtin_expect(!!(x), 1) -#define unlikely_notrace(x) __builtin_expect(!!(x), 0) - -#define __branch_check__(x, expect) ({ \ - int ______r; \ - static struct ftrace_branch_data \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_annotated_branch"))) \ - ______f = { \ - .func = __func__, \ - .file = __FILE__, \ - .line = __LINE__, \ - }; \ - ______r = likely_notrace(x); \ - ftrace_likely_update(&______f, ______r, expect); \ - ______r; \ - }) - -/* - * Using __builtin_constant_p(x) to ignore cases where the return - * value is always the same. This idea is taken from a similar patch - * written by Daniel Walker. - */ -# ifndef likely -# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1)) -# endif -# ifndef unlikely -# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) -# endif - -#ifdef CONFIG_PROFILE_ALL_BRANCHES -/* - * "Define 'is'", Bill Clinton - * "Define 'if'", Steven Rostedt - */ -#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) ) -#define __trace_if(cond) \ - if (__builtin_constant_p((cond)) ? !!(cond) : \ - ({ \ - int ______r; \ - static struct ftrace_branch_data \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_branch"))) \ - ______f = { \ - .func = __func__, \ - .file = __FILE__, \ - .line = __LINE__, \ - }; \ - ______r = !!(cond); \ - ______f.miss_hit[______r]++; \ - ______r; \ - })) -#endif /* CONFIG_PROFILE_ALL_BRANCHES */ - -#else -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -#endif - -/* Optimization barrier */ -#ifndef barrier -# define barrier() __memory_barrier() -#endif - -/* Unreachable code */ -#ifndef unreachable -# define unreachable() do { } while (1) -#endif - -#ifndef RELOC_HIDE -# define RELOC_HIDE(ptr, off) \ - ({ unsigned long __ptr; \ - __ptr = (unsigned long) (ptr); \ - (typeof(ptr)) (__ptr + (off)); }) -#endif - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ -/* - * Allow us to mark functions as 'deprecated' and have gcc emit a nice - * warning for each use, in hopes of speeding the functions removal. - * Usage is: - * int __deprecated foo(void) - */ -#ifndef __deprecated -# define __deprecated /* unimplemented */ -#endif - -#ifdef MODULE -#define __deprecated_for_modules __deprecated -#else -#define __deprecated_for_modules -#endif - -#ifndef __must_check -#define __must_check -#endif - -#ifndef CONFIG_ENABLE_MUST_CHECK -#undef __must_check -#define __must_check -#endif -#ifndef CONFIG_ENABLE_WARN_DEPRECATED -#undef __deprecated -#undef __deprecated_for_modules -#define __deprecated -#define __deprecated_for_modules -#endif - -/* - * Allow us to avoid 'defined but not used' warnings on functions and data, - * as well as force them to be emitted to the assembly file. - * - * As of gcc 3.4, static functions that are not marked with attribute((used)) - * may be elided from the assembly file. As of gcc 3.4, static data not so - * marked will not be elided, but this may change in a future gcc version. - * - * NOTE: Because distributions shipped with a backported unit-at-a-time - * compiler in gcc 3.3, we must define __used to be __attribute__((used)) - * for gcc >=3.3 instead of 3.4. - * - * In prior versions of gcc, such functions and data would be emitted, but - * would be warned about except with attribute((unused)). - * - * Mark functions that are referenced only in inline assembly as __used so - * the code is emitted even though it appears to be unreferenced. - */ -#ifndef __used -# define __used /* unimplemented */ -#endif - -#ifndef __maybe_unused -# define __maybe_unused /* unimplemented */ -#endif - -#ifndef __always_unused -# define __always_unused /* unimplemented */ -#endif - -#ifndef noinline -#define noinline -#endif - -/* - * Rather then using noinline to prevent stack consumption, use - * noinline_for_stack instead. For documentaiton reasons. - */ -#define noinline_for_stack noinline - -#ifndef __always_inline -#define __always_inline inline -#endif - -#endif /* __KERNEL__ */ - -/* - * From the GCC manual: - * - * Many functions do not examine any values except their arguments, - * and have no effects except the return value. Basically this is - * just slightly more strict class than the `pure' attribute above, - * since function is not allowed to read global memory. - * - * Note that a function that has pointer arguments and examines the - * data pointed to must _not_ be declared `const'. Likewise, a - * function that calls a non-`const' function usually must not be - * `const'. It does not make sense for a `const' function to return - * `void'. - */ -#ifndef __attribute_const__ -# define __attribute_const__ /* unimplemented */ -#endif - -/* - * Tell gcc if a function is cold. The compiler will assume any path - * directly leading to the call is unlikely. - */ - -#ifndef __cold -#define __cold -#endif - -/* Simple shorthand for a section definition */ -#ifndef __section -# define __section(S) __attribute__ ((__section__(#S))) -#endif - -/* Are two types/vars the same type (ignoring qualifiers)? */ -#ifndef __same_type -# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) -#endif - -/* Compile time object size, -1 for unknown */ -#ifndef __compiletime_object_size -# define __compiletime_object_size(obj) -1 -#endif -#ifndef __compiletime_warning -# define __compiletime_warning(message) -#endif -#ifndef __compiletime_error -# define __compiletime_error(message) -#endif - -/* - * Prevent the compiler from merging or refetching accesses. The compiler - * is also forbidden from reordering successive instances of ACCESS_ONCE(), - * but only when the compiler is aware of some particular ordering. One way - * to make the compiler aware of ordering is to put the two invocations of - * ACCESS_ONCE() in different C statements. - * - * This macro does absolutely -nothing- to prevent the CPU from reordering, - * merging, or refetching absolutely anything at any time. Its main intended - * use is to mediate communication between process-level code and irq/NMI - * handlers, all running on the same CPU. - */ -#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) - -#endif /* __LINUX_COMPILER_H */ diff --git a/exynos/kernel_header/media.h b/exynos/kernel_header/media.h deleted file mode 100755 index 0ef8833..0000000 --- a/exynos/kernel_header/media.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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/exynos/kernel_header/v4l2-mediabus.h b/exynos/kernel_header/v4l2-mediabus.h deleted file mode 100755 index fa0c1c4..0000000 --- a/exynos/kernel_header/v4l2-mediabus.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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, - - /* YUV (including grey) - next is 0x2013 */ - 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_UYVY8_1X16 = 0x200f, - V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, - V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, - V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, - V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, - V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, - - /* Bayer - next is 0x3013 */ - V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, - V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, - 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 */ - V4L2_MBUS_FMT_JPEG_1X8 = 0x4000, -}; - -/** - * 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/exynos/kernel_header/v4l2-subdev.h b/exynos/kernel_header/v4l2-subdev.h deleted file mode 100755 index 77f05c0..0000000 --- a/exynos/kernel_header/v4l2-subdev.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 -#ifdef KERNEL_HEADER_MODIFICATION -#include "v4l2-mediabus.h" -#else -#include -#endif - -/** - * 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/exynos/libv4l2/exynos_mc.c b/exynos/libv4l2/exynos_mc.c index 6ada9d1..4025b24 100755 --- a/exynos/libv4l2/exynos_mc.c +++ b/exynos/libv4l2/exynos_mc.c @@ -40,16 +40,8 @@ #ifndef SLP_PLATFORM /* build env */ #include #else - -#ifdef KERNEL_HEADER_MODIFICATION -#include "../kernel_header/compiler.h" -#include "../kernel_header/media.h" -#else -#include #include #endif - -#endif #include #include diff --git a/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c index 964686c..9d1e48c 100755 --- a/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c +++ b/exynos4/libcodec/video/v4l2/dec/ExynosVideoDecoder.c @@ -42,13 +42,11 @@ #include "ExynosVideoApi.h" #include "ExynosVideoDec.h" -//#include - /* #define LOG_NDEBUG 0 */ #define LOG_TAG "ExynosVideoDecoder" #ifndef SLP_PLATFORM /* build env */ #include -#else +#else #include "Exynos_OSAL_Log.h" #endif @@ -1328,6 +1326,7 @@ static ExynosVideoErrorType MFC_Decoder_Register_Outbuf( pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr; pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd; + pCtx->pOutbuf[nIndex].planes[plane].tbm_bo = planes[plane].tbm_bo; } pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE; ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n", diff --git a/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h b/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h old mode 100644 new mode 100755 index 8132417..b89adcc --- a/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h +++ b/exynos4/libcodec/video/v4l2/include/ExynosVideoApi.h @@ -107,6 +107,7 @@ typedef struct _ExynosVideoPlane { unsigned int dataSize; unsigned long offset; int fd; + void *tbm_bo; } ExynosVideoPlane; typedef struct _ExynosVideoBuffer { diff --git a/openmax/component/common/Exynos_OMX_Baseport.h b/openmax/component/common/Exynos_OMX_Baseport.h old mode 100644 new mode 100755 index 1b46f7b..df52a3c --- a/openmax/component/common/Exynos_OMX_Baseport.h +++ b/openmax/component/common/Exynos_OMX_Baseport.h @@ -55,6 +55,8 @@ typedef struct _EXYNOS_OMX_BUFFERHEADERTYPE OMX_HANDLETYPE ANBHandle; void *pYUVBuf[MAX_BUFFER_PLANE]; int buf_fd[MAX_BUFFER_PLANE]; + void *tbm_bo[MAX_BUFFER_PLANE]; + int size[MAX_BUFFER_PLANE]; } EXYNOS_OMX_BUFFERHEADERTYPE; typedef struct _EXYNOS_OMX_DATABUFFER @@ -84,6 +86,8 @@ typedef struct _EXYNOS_OMX_MULTIPLANE_DATA OMX_U32 validPlaneNum; OMX_PTR dataBuffer[MAX_BUFFER_PLANE]; int fd[MAX_BUFFER_PLANE]; + void *tbm_bo[MAX_BUFFER_PLANE]; + int size[MAX_BUFFER_PLANE]; } EXYNOS_OMX_MULTIPLANE_DATA; typedef struct _EXYNOS_OMX_DATA diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.c b/openmax/component/video/dec/Exynos_OMX_Vdec.c index 9b3bf68..fc99f84 100755 --- a/openmax/component/video/dec/Exynos_OMX_Vdec.c +++ b/openmax/component/video/dec/Exynos_OMX_Vdec.c @@ -301,7 +301,11 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA pSlpOutBuf->handle.dmabuf_fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1]; pSlpOutBuf->handle.dmabuf_fd[2] = 0; /* omx do not use this plane */ - //pSlpOutBuf->buf_share_method = MEMORY_DMABUF; + pSlpOutBuf->handle.bo[0] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[0]; + pSlpOutBuf->handle.bo[1] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[1]; + pSlpOutBuf->handle.bo[2] = NULL; + + //pSlpOutBuf->type = MM_VIDEO_BUFFER_TYPE_DMABUF_FD; dstOutputData->dataLen = sizeof(MMVideoBuffer); Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__); diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.c b/openmax/component/video/dec/Exynos_OMX_VdecControl.c index f2ed5aa..e236148 100755 --- a/openmax/component/video/dec/Exynos_OMX_VdecControl.c +++ b/openmax/component/video/dec/Exynos_OMX_VdecControl.c @@ -137,8 +137,12 @@ OMX_ERRORTYPE Exynos_OMX_UseBuffer( pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->data[1]; pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL; - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PlatformBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ", - i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], pExynosPort->extendBufferHeader[i].pYUVBuf[1]); + pExynosPort->extendBufferHeader[i].tbm_bo[0] = pSlpOutBuf->handle.bo[0]; + pExynosPort->extendBufferHeader[i].tbm_bo[1] = pSlpOutBuf->handle.bo[1]; + pExynosPort->extendBufferHeader[i].tbm_bo[2] = NULL; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\nPlatformBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ", + i, pExynosPort->extendBufferHeader[i].pYUVBuf[0], pExynosPort->extendBufferHeader[i].pYUVBuf[1]); } else if ((pVideoDec->bDRMPlayerMode == OMX_TRUE) && (nPortIndex == INPUT_PORT_INDEX)) { pExynosPort->extendBufferHeader[i].buf_fd[0] = pBuffer; } else if(nPortIndex == INPUT_PORT_INDEX){ diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c index 5211a6f..45f49cf 100755 --- a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -1161,6 +1161,7 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane]; planes[plane].allocSize = nAllocLen[plane]; } @@ -2384,6 +2385,7 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; } diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c index 0bbd7fe..3ae55f5 100755 --- a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c +++ b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c @@ -762,6 +762,7 @@ OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane]; planes[plane].allocSize = nAllocLen[plane]; } @@ -1705,6 +1706,7 @@ OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; } diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index bb4ea92..23b4c4f 100755 --- a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -1259,6 +1259,7 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; + planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane]; planes[plane].allocSize = nAllocLen[plane]; } diff --git a/openmax/osal/Exynos_OSAL_Platform_Specific.c b/openmax/osal/Exynos_OSAL_Platform_Specific.c index 8359e6a..69c9dad 100755 --- a/openmax/osal/Exynos_OSAL_Platform_Specific.c +++ b/openmax/osal/Exynos_OSAL_Platform_Specific.c @@ -249,6 +249,10 @@ OMX_ERRORTYPE Exynos_OSAL_UnlockPB(OMX_IN OMX_PTR pBuffer, EXYNOS_OMX_DATA *pDat pSlpOutBuf->handle.dmabuf_fd[1] = pData->buffer.multiPlaneBuffer.fd[1]; pSlpOutBuf->handle.dmabuf_fd[2] = 0; + pSlpOutBuf->handle.bo[0] = pData->buffer.multiPlaneBuffer.tbm_bo[0]; + pSlpOutBuf->handle.bo[1] = pData->buffer.multiPlaneBuffer.tbm_bo[1]; + pSlpOutBuf->handle.bo[2] = NULL; + if(pExynosInPort->portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) { pSlpOutBuf->size[0] = calc_plane(pBufferInfo->imageWidth,pBufferInfo->imageHeight); diff --git a/packaging/libomxil-e3250-v4l2.spec b/packaging/libomxil-e3250-v4l2.spec index ece82c8..b7cfa8a 100755 --- a/packaging/libomxil-e3250-v4l2.spec +++ b/packaging/libomxil-e3250-v4l2.spec @@ -1,6 +1,6 @@ Name: libomxil-e3250-v4l2 Summary: OpenMAX IL for e3250-v4l2 -Version: 0.0.16 +Version: 0.1.0 License: TO BE FILLED IN Group: Development/Libraries Release: 0 @@ -8,8 +8,10 @@ ExclusiveArch: %arm Source: %{name}-%{version}.tar.gz Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig -BuildRequires: kernel-headers -BuildRequires: pkgconfig(dlog) +#!BuildIgnore: kernel-headers +BuildConflicts: linux-glibc-devel +BuildRequires: kernel-headers-tizen-dev +BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(mm-common) %description @@ -38,8 +40,7 @@ export CFLAGS+="\ -DUSE_PB\ -DUSE_DMA_BUF\ -DUSE_H264_PREPEND_SPS_PPS\ - -DGST_EXT_TIME_ANALYSIS\ - -DKERNEL_HEADER_MODIFICATION" + -DGST_EXT_TIME_ANALYSIS" %ifnarch aarch64 %configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-exynos3250 --enable-neon -- 2.7.4 From d50233137ba7a7d71738f51842addfb86403eab1 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 20 Apr 2016 14:52:41 +0900 Subject: [PATCH 5/7] Fixed issue when decoding mpeg4 Change-Id: I83324ce4cc2968c45d72a2b2461334349ea33111 --- openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index 23b4c4f..a6bda69 100755 --- a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -2482,6 +2482,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; + pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo; pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; } -- 2.7.4 From aebc0e89e3990890d8c1d7a24d31a2184ceec75e Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 28 Jun 2016 16:29:11 +0900 Subject: [PATCH 6/7] Apply DEP to libswconverter Change-Id: Id3f2b6dca1c7376f9636507f6cd0acd38c660c27 --- packaging/libomxil-e3250-v4l2.spec | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packaging/libomxil-e3250-v4l2.spec b/packaging/libomxil-e3250-v4l2.spec index b7cfa8a..f801c16 100755 --- a/packaging/libomxil-e3250-v4l2.spec +++ b/packaging/libomxil-e3250-v4l2.spec @@ -1,7 +1,7 @@ Name: libomxil-e3250-v4l2 Summary: OpenMAX IL for e3250-v4l2 -Version: 0.1.0 -License: TO BE FILLED IN +Version: 0.1.1 +License: Apache-2.0 Group: Development/Libraries Release: 0 ExclusiveArch: %arm @@ -42,6 +42,8 @@ export CFLAGS+="\ -DUSE_H264_PREPEND_SPS_PPS\ -DGST_EXT_TIME_ANALYSIS" +export LDFLAGS+="-Wl,--rpath=%{_prefix} -Wl,--as-needed,-z,noexecstack" + %ifnarch aarch64 %configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-exynos3250 --enable-neon %else @@ -54,8 +56,8 @@ make %install rm -rf %{buildroot} -#mkdir -p %{buildroot}/usr/share/license -#cp COPYING %{buildroot}/usr/share/license/%{name} +mkdir -p %{buildroot}/usr/share/license +cp COPYING %{buildroot}/usr/share/license/%{name} %make_install @@ -68,6 +70,7 @@ rm -rf %{buildroot} %manifest libomxil-e3250-v4l2.manifest %{_libdir}/*.so* %{_libdir}/omx/*.so +%{_datadir}/license/%{name} %files devel -- 2.7.4 From fc05637baf4b8e0b572bc7a2cf06cf5d06ac1202 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 5 Jul 2016 10:38:21 +0900 Subject: [PATCH 7/7] Changed output format from NV12T to NV12 Change-Id: I21efa289485e2d55f57fed248d6fd5d665162e7d --- openmax/component/video/dec/Exynos_OMX_VdecControl.c | 2 +- openmax/component/video/dec/h264/Exynos_OMX_H264dec.c | 11 ++++++----- openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 11 ++++++----- packaging/libomxil-e3250-v4l2.spec | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.c b/openmax/component/video/dec/Exynos_OMX_VdecControl.c index e236148..2cbb0bc 100755 --- a/openmax/component/video/dec/Exynos_OMX_VdecControl.c +++ b/openmax/component/video/dec/Exynos_OMX_VdecControl.c @@ -1197,7 +1197,7 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter( break; case supportFormat_2: portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; - portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; + portFormat->eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; portFormat->xFramerate = portDefinition->format.video.xFramerate; break; #ifdef SLP_PLATFORM diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c index 45f49cf..e3992bb 100755 --- a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -1028,7 +1028,7 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); - pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -1617,7 +1617,8 @@ OMX_ERRORTYPE Exynos_H264Dec_SetParameter( case OMX_COLOR_FormatYUV420SemiPlanar: pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; break; -#ifdef SLP_PLATFORM /* NV12T fd */ +#ifdef SLP_PLATFORM /* NV12 fd */ + case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd: case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer); break; @@ -2400,8 +2401,8 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; switch (bufferGeometry->eColorFormat) { case VIDEO_COLORFORMAT_NV12: -#ifdef SLP_PLATFORM /* NV12T fd */ - pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#ifdef SLP_PLATFORM /* NV12 fd */ + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; #else pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; #endif @@ -2740,7 +2741,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent pExynosPort->portDefinition.format.video.pNativeRender = 0; pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; #ifdef SLP_PLATFORM - pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; #else pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; #endif diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index a6bda69..2afae9c 100755 --- a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -1127,7 +1127,7 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA /* set output geometry */ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); - pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; + pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); ret = OMX_ErrorInsufficientResources; @@ -1752,8 +1752,9 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_SetParameter( case OMX_COLOR_FormatYUV420SemiPlanar: pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; break; -#ifdef SLP_PLATFORM /* NV12T fd */ +#ifdef SLP_PLATFORM /* NV12 fd */ case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd: + case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd: pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer); break; #endif @@ -2497,8 +2498,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; switch (bufferGeometry->eColorFormat) { case VIDEO_COLORFORMAT_NV12: -#ifdef SLP_PLATFORM /* NV12T fd */ - pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; +#ifdef SLP_PLATFORM /* NV12 fd */ + pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; #else pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; #endif @@ -2831,7 +2832,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent pExynosPort->portDefinition.format.video.pNativeRender = 0; pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; #ifdef SLP_PLATFORM - pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd; + pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd; pExynosPort->bufferProcessType = BUFFER_SHARE; #else pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; diff --git a/packaging/libomxil-e3250-v4l2.spec b/packaging/libomxil-e3250-v4l2.spec index f801c16..1928b77 100755 --- a/packaging/libomxil-e3250-v4l2.spec +++ b/packaging/libomxil-e3250-v4l2.spec @@ -1,6 +1,6 @@ Name: libomxil-e3250-v4l2 Summary: OpenMAX IL for e3250-v4l2 -Version: 0.1.1 +Version: 0.1.2 License: Apache-2.0 Group: Development/Libraries Release: 0 -- 2.7.4